#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
#define NODEFINE
#include <u.h>
#include <libc.h>
#include "../9syscall/fd.h"
int
pm_procexec(char *prog, char *args[], int *fd, char **env)
{
int i, pid;
int ufd[3];
if(access(prog, 01) < 0){
pm_oserror();
if(pm_debug & PmDebugExec)
pm_fprint(2, "pm_procexec %s: access failed: %r\n", prog);
return -1;
}
switch(pid = fork()){
case -1:
if(pm_debug & PmDebugExec)
pm_fprint(2, "pm_procexec %s: fork failed\n", prog);
pm_oserror();
return -1;
case 0:
break;
default:
return pid;
}
for(i=0; i<3; i++)
ufd[i] = pm_pmfd2ufd(fd[i]);
/*
* ufd0, ufd1, ufd2 could be 0, 1, or 2.
* if the wrong things happen, we might close
* a file descriptor before we need one.
* rather than figure out the dependencies (which
* could be circular anyway), we just dup once at the
* beginning to make sure they're not 0, 1, and 2.
*/
/* use up 0, 1, 2 if empty */
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDONLY);
/* reposition ufd0, ufd1, ufd2 */
for(i=0; i<3; i++)
if(0 <= ufd[i] && ufd[i] < 3)
ufd[i] = dup(ufd[i]);
/* now ufd0, ufd1, ufd2 must be >= 3, safe to dup */
for(i=0; i<3; i++)
if(ufd[i] >= 0)
dup2(ufd[i], i);
else
close(i);
for(i=3; i<=100; i++)
close(i);
if(env)
execve(prog, args, env);
else
execv(prog, args);
pm_oserror();
if(pm_debug & PmDebugExec)
pm_fprint(2, "pm_procexec %s: %r\n", prog);
_exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1