system in C++ like perl’s system
Small tricks, haven’t tested these yet, perhaps a bit of more error handling in fork or exec. I don’t like system (3) shell interpolation. In this case one can do system_exec(”ls”,”/tmp”,NULL) or special chars in args that won’t get interpolated by the shell.
int system_exec(char* cmd, ...)
{
va_list ap;
vector arglist;
arglist.push_back(cmd);
char* cur;
va_start(ap,cmd);
while( (cur=va_arg(ap,char*)) != NULL)
arglist.push_back(strdup(cur));
va_end(ap);
arglist.push_back(NULL);
int res;
pid_t chld;
if( (chld = fork()) ) {
for(vector::iterator i = arglist.begin()+1; i != arglist.end(); ++i)
free(*i);
wait(&res);
} else {
execvp(cmd, &arglist[0]);
}
return res;
}
#define W 1
#define R 0
int stdout2stream_system_exec(std::ostream& os, char* cmd, …)
{
va_list ap;
vector arglist;
arglist.push_back(cmd);
char* cur;
va_start(ap,cmd);
while( (cur=va_arg(ap,char*)) != NULL)
arglist.push_back(strdup(cur));
va_end(ap);
arglist.push_back(NULL);
int fd[2];
pipe(fd);
int res;
pid_t chld;
if( (chld = fork()) ) {
for(vector::iterator i = arglist.begin()+1; i != arglist.end(); ++i)
free(*i);
close(fd[W]);
char buf[1024];
ssize_t nread;
while( (nread=read(fd[R],buf,1024)) > 0 && os.good() ) {
os.write(buf,nread);
}
// TODO errors
close(fd[R]);
wait(&res);
} else {
close(fd[R]);
// no need according to manpage
//close(STDOUT_FILENO);
if( dup2(fd[W], STDOUT_FILENO) != STDOUT_FILENO) {
perror(”dup2″);
exit(EXIT_FAILURE);
}
close(fd[W]);
execvp(cmd, &arglist[0]);
perror(”execvp”);
}
return res;
}