daily pastebin goal
84%
SHARE
TWEET

Untitled

a guest Nov 12th, 2015 76 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <sstream>
  3. #include <system_error>
  4. #include <cerrno>
  5. #include <boost/filesystem.hpp>
  6. #include <boost/optional.hpp>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <sys/wait.h>
  10. #include <fcntl.h>
  11.  
  12. namespace fs = boost::filesystem;
  13.  
  14. enum class SearchInPath { No, Yes };
  15.  
  16. void launch(SearchInPath search_in_path,
  17.             const fs::path& path,
  18.             const std::vector<std::string>& args,
  19.             const boost::optional<fs::path>& log = boost::none) {
  20.   std::vector<char*> exec_args;
  21.   for (const std::string& arg : args) {
  22.     exec_args.push_back(const_cast<char*>(arg.c_str()));
  23.   }
  24.   exec_args.push_back(nullptr);
  25.  
  26.   pid_t pid = fork();
  27.   if (pid == -1) {
  28.     throw std::system_error(errno, std::system_category());
  29.   } else if (pid == 0) {
  30.     int rc;
  31.  
  32.     if (log) {
  33.       int fd = open(log.get().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
  34.       if (fd != -1) {
  35.         close(STDERR_FILENO);
  36.         dup2(fd, STDERR_FILENO);
  37.       }
  38.     }
  39.  
  40.     if (search_in_path == SearchInPath::Yes) {
  41.       rc = execvp(path.c_str(), exec_args.data());
  42.     } else {
  43.       rc = execv(path.c_str(), exec_args.data());
  44.     }
  45.   } else {
  46.     int status;
  47.     int rc = waitpid(pid, &status, 0);
  48.     if (rc == -1) {
  49.       throw std::system_error(errno, std::system_category());
  50.     }
  51.  
  52.     if (status != 0) {
  53.       throw std::runtime_error("Process existed with return code: " + std::to_string(status));
  54.     }
  55.   }
  56. }
  57.  
  58. int main(int argc, char **argv) {
  59.   fs::path path;
  60.   fs::path daemon;
  61.   fs::path pakpath;
  62.   fs::path log;
  63.  
  64.   try {
  65.     path    = fs::read_symlink("/proc/self/exe").parent_path();
  66.     daemon  = path / "linux64" / "daemon";
  67.     pakpath = path / "pkg";
  68.     log     = path / "Unvanquished.log";
  69.  
  70.     launch(SearchInPath::No, daemon.c_str(), {"daemon", "-pakpath", pakpath.string()}, log);
  71.   } catch (const std::exception& e) {
  72.     std::ostringstream msg;
  73.  
  74.     msg << "Unvanquished has failed to launch.\n";
  75.     msg << "Visit <a href=\"http://forums.unvanquished.net/\">Unvanquished forums</a> for support.\n\n";
  76.  
  77.     msg << "Please include the following technical information in your post:\n\n";
  78.  
  79.     msg << "Error message: " << e.what() << ".";
  80.  
  81.     if (!path.empty()) {
  82.       msg << "\n";
  83.       msg << "Base path: " << path << ".\n";
  84.       msg << "Daemon executable exists: " << (fs::exists(daemon) ? "yes" : "no") << ".\n";
  85.       msg << "Package directory exists: " << (fs::exists(pakpath) ? "yes" : "no") << ".";
  86.     }
  87.  
  88.     if (fs::exists(log)) {
  89.       msg << "\n\n";
  90.       msg << "Please also incude the contents of the log file.\n\n";
  91.       msg << "Log file location: " << log.string();
  92.     }
  93.  
  94.     try {
  95.       launch(SearchInPath::Yes, "zenity", {"zenity", "--error", "--text", msg.str()});
  96.     } catch (...) {}
  97.  
  98.     std::cout << msg.str() << std::endl;
  99.   }
  100.  
  101.   return 0;
  102. }
RAW Paste Data
Top