#include #include #include #include #include #include int spawn(char *command, char **args) { /* sample usage: * * char *args[3]; * * args[0] = "sh"; * args[1] = "/path/to/script"; * args[2] = NULL; * spawn("/bin/sh", args); */ struct sigaction act, intr, quit; sigset_t block, oldmask; int status = -1; pid_t pid; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; act.sa_handler = SIG_IGN; if (sigaction(SIGINT, &act, &intr) < 0) goto error_1; if (sigaction(SIGQUIT, &act, &quit) < 0) goto error_2; sigemptyset(&block); sigaddset(&block, SIGCHLD); if (sigprocmask(SIG_BLOCK, &block, &oldmask) < 0) goto error_3; pid = fork(); if (pid < 0) { fprintf(stderr, "unable to create a new process"); goto error_4; } if (pid == 0) { sigaction(SIGINT, &intr, NULL); sigaction(SIGQUIT, &quit, NULL); execvp(command, args); /* if we reach this point, execvp() failed */ fprintf(stderr, "unable to execute command"); _exit(127); } else { pid_t n; do n = waitpid(pid, &status, 0); while (n == (pid_t) -1 && errno == EINTR); if (n != pid) status = -1; } error_4: sigprocmask(SIG_SETMASK, &oldmask, NULL); error_3: sigaction(SIGQUIT, &quit, NULL); error_2: sigaction(SIGINT, &intr, NULL); error_1: return status; }