J
James Thornton
How do you inherit the stdin and stdout file descriptors from a parent
process? Specifically, the following function "run_filters" forks and
calls several perl scripts via execvp.
One of the perl scripts needs to execute a virus scanner on the file
pointed to by the parent file descriptor, modifying the file as
needed. The virus scanner will be invoked via a system call where
$file is the file name associated with the file parent file
descriptor:
system $virus_binary $file;
// C program that forks and executes several
// Perl scripts via execvp
int run_filters(command* first, int fdin)
{
command* c;
for(c = first; c; c = c->next) {
pid_t pid;
int status;
int fdout;
fdout = mktmpfile();
if(fdout == -1)
return -QQ_WRITE_ERROR;
pid = fork();
if(pid == -1)
return -QQ_OOM;
if(pid == 0) {
if(close(0) == -1 ||
dup2(fdin, 0) != 0 ||
close(1) == -1 ||
dup2(fdout, 1) != 1)
exit(QQ_WRITE_ERROR);
execvp(c->argv[0], c->argv);
exit(QQ_INTERNAL);
}
if(waitpid(pid, &status, WUNTRACED) == -1)
return -QQ_INTERNAL;
if(!WIFEXITED(status))
return -QQ_INTERNAL;
if(WEXITSTATUS(status))
return -WEXITSTATUS(status);
close(fdin);
if(lseek(fdout, 0, SEEK_SET) != 0)
return -QQ_WRITE_ERROR;
fdin = fdout;
}
return fdin;
}
process? Specifically, the following function "run_filters" forks and
calls several perl scripts via execvp.
One of the perl scripts needs to execute a virus scanner on the file
pointed to by the parent file descriptor, modifying the file as
needed. The virus scanner will be invoked via a system call where
$file is the file name associated with the file parent file
descriptor:
system $virus_binary $file;
// C program that forks and executes several
// Perl scripts via execvp
int run_filters(command* first, int fdin)
{
command* c;
for(c = first; c; c = c->next) {
pid_t pid;
int status;
int fdout;
fdout = mktmpfile();
if(fdout == -1)
return -QQ_WRITE_ERROR;
pid = fork();
if(pid == -1)
return -QQ_OOM;
if(pid == 0) {
if(close(0) == -1 ||
dup2(fdin, 0) != 0 ||
close(1) == -1 ||
dup2(fdout, 1) != 1)
exit(QQ_WRITE_ERROR);
execvp(c->argv[0], c->argv);
exit(QQ_INTERNAL);
}
if(waitpid(pid, &status, WUNTRACED) == -1)
return -QQ_INTERNAL;
if(!WIFEXITED(status))
return -QQ_INTERNAL;
if(WEXITSTATUS(status))
return -WEXITSTATUS(status);
close(fdin);
if(lseek(fdout, 0, SEEK_SET) != 0)
return -QQ_WRITE_ERROR;
fdin = fdout;
}
return fdin;
}