31 #include <sys/types.h> 33 #include <boost/algorithm/string/join.hpp> 34 #include <boost/scope_exit.hpp> 45 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 46 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "spawn" 51 int spawn(
const char *filename,
const std::vector<std::string>& args,
bool wait)
54 std::string joined = boost::algorithm::join(args,
" ");
55 char *commandLine = !joined.empty() ? &joined[0] :
nullptr;
58 PROCESS_INFORMATION pi;
59 if (!CreateProcessA(filename, commandLine,
nullptr,
nullptr,
false, 0,
nullptr,
nullptr, &si, &pi))
61 MERROR(
"CreateProcess failed. Error code " << GetLastError());
67 CloseHandle(pi.hThread);
68 CloseHandle(pi.hProcess);
77 DWORD result = WaitForSingleObject(pi.hProcess, INFINITE);
78 if (result != WAIT_OBJECT_0)
80 MERROR(
"WaitForSingleObject failed. Result " << result <<
", error code " << GetLastError());
85 if (!GetExitCodeProcess(pi.hProcess, &exitCode))
87 MERROR(
"GetExitCodeProcess failed. Error code " << GetLastError());
91 MINFO(
"Child exited with " << exitCode);
92 return static_cast<int>(exitCode);
94 std::vector<char*> argv(args.size() + 1);
95 for (
size_t n = 0; n < args.size(); ++n)
96 argv[n] = (
char*)args[n].c_str();
97 argv[args.size()] = NULL;
102 MERROR(
"Error forking: " << strerror(errno));
111 char *envp[] = {NULL};
112 execve(filename, argv.data(), envp);
113 MERROR(
"Failed to execve: " << strerror(errno));
122 signal(SIGCHLD, SIG_IGN);
129 pid_t w = waitpid(pid, &wstatus, WUNTRACED | WCONTINUED);
131 MERROR(
"Error waiting for child: " << strerror(errno));
134 if (WIFEXITED(wstatus))
136 MINFO(
"Child exited with " << WEXITSTATUS(wstatus));
137 return WEXITSTATUS(wstatus);
139 if (WIFSIGNALED(wstatus))
141 MINFO(
"Child killed by " << WEXITSTATUS(wstatus));
142 return WEXITSTATUS(wstatus);
146 MERROR(
"Secret passage found");
void fork(const std::string &pidfile)