26 #include <sys/types.h> 38 std::string shell=
"/bin/sh";
39 std::vector<std::string> argv;
40 argv.push_back(shell);
41 argv.push_back(command);
42 return run(shell, argv,
"",
"");
46 const std::string &what,
47 const std::vector<std::string> &argv,
48 const std::string &std_input,
49 const std::string &std_output)
53 assert(std_input.empty());
54 assert(std_output.empty());
57 std::vector<std::wstring> wargv;
59 wargv.resize(argv.size());
61 for(std::size_t i=0; i<argv.size(); i++)
62 wargv[i]=
widen(argv[i]);
64 const wchar_t **_argv=
new const wchar_t * [argv.size()+1];
66 for(std::size_t i=0; i<wargv.size(); i++)
67 _argv[i]=wargv[i].c_str();
69 _argv[argv.size()]=NULL;
73 std::wstring wide_what=
widen(what);
75 int status=_wspawnvp(_P_WAIT, wide_what.c_str(), _argv);
82 int stdin_fd=STDIN_FILENO;
84 if(!std_input.empty())
86 stdin_fd=open(std_input.c_str(), O_RDONLY);
89 perror(
"Failed to open stdin copy");
94 int stdout_fd=STDOUT_FILENO;
96 if(!std_output.empty())
98 stdout_fd=open(std_output.c_str(), O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
101 perror(
"Failed to open stdout copy");
107 sigset_t new_mask, old_mask;
108 sigemptyset(&new_mask);
109 sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
112 pid_t childpid = fork();
120 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
122 char **_argv=
new char * [argv.size()+1];
123 for(std::size_t i=0; i<argv.size(); i++)
124 _argv[i]=strdup(argv[i].c_str());
126 _argv[argv.size()]=
nullptr;
128 if(stdin_fd!=STDIN_FILENO)
129 dup2(stdin_fd, STDIN_FILENO);
130 if(stdout_fd!=STDOUT_FILENO)
131 dup2(stdout_fd, STDOUT_FILENO);
132 execvp(what.c_str(), _argv);
140 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
145 while(waitpid(childpid, &status, 0)==-1)
150 perror(
"Waiting for child process failed");
151 if(stdin_fd!=STDIN_FILENO)
153 if(stdout_fd!=STDOUT_FILENO)
158 if(stdin_fd!=STDIN_FILENO)
160 if(stdout_fd!=STDOUT_FILENO)
163 return WEXITSTATUS(status);
169 sigprocmask(SIG_SETMASK, &old_mask,
nullptr);
171 if(stdin_fd!=STDIN_FILENO)
173 if(stdout_fd!=STDOUT_FILENO)
std::wstring widen(const char *s)
void remove_signal_catcher()
int run_shell(const std::string &command)
int run(const std::string &what, const std::vector< std::string > &argv, const std::string &std_input, const std::string &std_output)