/*
* LIB/RUNPROG.C
*
* (c)Copyright 1998, Matthew Dillon, All Rights Reserved. Refer to
* the COPYRIGHT file in the base directory of this distribution
* for specific rights granted.
*/
#include "defs.h"
Prototype pid_t RunProgramPipe(int rfds[3], int flags, char **argv, char **env);
void SetDevNull(int dfd);
#define MASTER_IN 0
#define SLAVE_OUT 1
#define SLAVE_IN 2
#define MASTER_OUT 3
#define MASTER_ERR_IN 4
#define SLAVE_ERR_OUT 5
pid_t
RunProgramPipe(int rfds[3], int flags, char **argv, char **env)
{
pid_t pid = 0;
int fds[6] = { -1, -1, -1, -1, -1, -1 };
if (((flags & RPF_STDIN) ? pipe(&fds[0]) : 0) == 0 &&
((flags & RPF_STDOUT) ? pipe(&fds[2]) : 0) == 0 &&
((flags & RPF_STDERR) ? pipe(&fds[4]) : 0) == 0
) {
fflush(stdout);
fflush(stderr);
if ((pid = fork()) == 0) {
/*
* exec pgpverify w/ stdin and stdout
*/
int fd;
int i;
if (flags & RPF_STDOUT) {
dup2(fds[SLAVE_IN], 0);
} else {
SetDevNull(0);
}
if (flags & RPF_STDIN) {
dup2(fds[SLAVE_OUT], 1);
} else {
SetDevNull(1);
}
if (flags & RPF_STDERR) {
dup2(fds[SLAVE_ERR_OUT], 2);
} else {
SetDevNull(2);
}
for (i = 0; i < arysize(fds); ++i) {
if (fds[i] >= 0)
close(fds[i]);
}
for (fd = 3; fd < MAXFDS; ++fd)
close(fd);
if (env == NULL)
execv(argv[0], argv + 1);
else
execve(argv[0], argv + 1, env);
_exit(9);
}
if (pid > 0) {
if (flags & RPF_STDIN) {
rfds[0] = fds[MASTER_IN];
fds[MASTER_IN] = -1;
}
if (flags & RPF_STDOUT) {
rfds[1] = fds[MASTER_OUT];
fds[MASTER_OUT] = -1;
}
if (flags & RPF_STDERR) {
rfds[2] = fds[MASTER_ERR_IN];
fds[MASTER_ERR_IN] = -1;
}
}
}
{
int i;
for (i = 0; i < arysize(fds); ++i) {
if (fds[i] >= 0)
close(fds[i]);
}
}
return(pid);
}
void
SetDevNull(int dfd)
{
int fd = open("/dev/null", O_RDWR);
if (fd >= 0) {
if (fd != dfd) {
dup2(fd, dfd);
close(fd);
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1