/* * Spawn services built on fork() for those libc's that lack spawning. * $Id$ * Copyright (c) 1997 by Tycho Softworks. * For conditions of distribution and reuse see product license. */ #include #include static void spawn_redirect(int io, int mode) { int fd = open("/dev/null", mode); if(fd < 0) exit(EX_OSFILE); if(fd != io) { dup2(fd, io); close(fd); } } static int spawn_wait(pid_t pid, int mode) { int waitflag = mode & P_WAIT; /* -1 on fork failure */ if(pid == -1) return -1; if(!waitflag) return pid; waitpid(pid, &waitflag, 0); return WEXITSTATUS(waitflag); } static void spawn_mode(int mode) { int i; if(mode & P_BACKGROUND) { spawn_redirect(0, O_RDONLY); spawn_redirect(1, O_WRONLY); spawn_redirect(2, O_WRONLY); } for(i = 3; i < OPEN_MAX; ++i) close(i); if(mode & P_SESSION) setsid(); } int spawnv(const int mode, const char *path, char *const argv[]) { pid_t pid = 0; int status; if(!(mode & P_OVERLAY)) pid = fork(); if(pid) return spawn_wait(pid, mode); spawn_mode(mode); execv(path, argv); exit(EX_UNAVAILABLE); return -1; } int spawnvp(const int mode, const char *path, char *const argv[]) { pid_t pid = 0; int status; if(!(mode & P_OVERLAY)) pid = fork(); if(pid) return spawn_wait(pid, mode); spawn_mode(mode); execvp(path, argv); exit(EX_UNAVAILABLE); return -1; }