#include #include #include #include #define NODEFINE #include #include #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); }