void spawn_command(const char *cmd) { char *shell, *p; if(doublefork() == 0) { if((p = pathsearch(getenv("WMII_CONFPATH"), cmd, true))) cmd = p; if(setsid() == -1) fatal("Can't setsid: %r"); /* Run through the user's shell as a login shell */ shell = passwd->pw_shell; if(shell[0] != '/') fatal("Shell is not an absolute path: %s", shell); p = smprint("-%s", strrchr(shell, '/') + 1); close(0); open("/dev/null", O_RDONLY); execl(shell, p, "-c", cmd, nil); fatal("Can't exec '%s': %r", cmd); /* NOTREACHED */ } }
int main (int argc, char const *const *argv, char const *const *envp) { char const *s = env_get2(envp, VAR) ; unsigned int fd = 1 ; unsigned int timeout = 0 ; int df = 1, keep = 0 ; PROG = "sdnotify-wrapper" ; { subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { register int opt = subgetopt_r(argc, argv, "d:ft:k", &l) ; if (opt == -1) break ; switch (opt) { case 'd' : if (!uint0_scan(l.arg, &fd)) dieusage() ; break ; case 'f' : df = 0 ; break ; case 't' : if (!uint0_scan(l.arg, &timeout)) dieusage() ; break ; case 'k' : keep = 1 ; break ; default : dieusage() ; } } argc -= l.ind ; argv += l.ind ; } if (!argc) dieusage() ; if (!s) xpathexec_run(argv[0], argv, envp) ; else { pid_t parent = getpid() ; pid_t child ; int p[2] ; if (pipe(p) < 0) strerr_diefu1sys(111, "pipe") ; child = df ? doublefork() : fork() ; if (child < 0) strerr_diefu1sys(111, df ? "doublefork" : "fork") ; else if (!child) { PROG = "sdnotify-wrapper (child)" ; close(p[1]) ; return run_child(p[0], timeout, parent, s) ; } close(p[0]) ; if (fd_move((int)fd, p[1]) < 0) strerr_diefu1sys(111, "move descriptor") ; if (keep) xpathexec_run(argv[0], argv, envp) ; else xpathexec_r(argv, envp, env_len(envp), VAR, sizeof(VAR)) ; } }
int main (int argc, char const *const *argv, char const *const *envp) { int df = 0 ; PROG = "heredoc" ; { subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { register int opt = subgetopt_r(argc, argv, "d", &l) ; if (opt == -1) break ; switch (opt) { case 'd' : df = 1 ; break ; default : dieusage() ; } } argc -= l.ind ; argv += l.ind ; } if (argc < 3) dieusage() ; { int fd[2] ; unsigned int fdr ; int pid ; if (!uint0_scan(argv[0], &fdr)) strerr_dieusage(100, USAGE) ; if (pipe(fd) < 0) strerr_diefu1sys(111, "pipe") ; pid = df ? doublefork() : fork() ; switch (pid) { case -1: strerr_diefu2sys(111, df ? "double" : "", "fork") ; case 0: { unsigned int len = str_len(argv[1]) ; PROG = "heredoc (child)" ; fd_close(fd[0]) ; if (allwrite(fd[1], argv[1], len) < len) strerr_diefu1sys(111, "allwrite") ; return 0 ; } } fd_close(fd[1]) ; if (fd_move((int)fdr, fd[0]) == -1) strerr_diefu2sys(111, "read on fd ", argv[0]) ; } pathexec_run(argv[2], argv+2, envp) ; strerr_dieexec(111, argv[2]) ; }
static void init_traps(void) { char buf[1]; int fd[2]; if(pipe(fd) != 0) fatal("Can't pipe(): %r"); if(doublefork() == 0) { close(fd[1]); close(ConnectionNumber(display)); setsid(); display = XOpenDisplay(nil); if(!display) fatal("Can't open display"); /* Wait for parent to exit */ read(fd[0], buf, 1); setfocus(pointerwin, RevertToPointerRoot); XCloseDisplay(display); exit(0); } close(fd[0]); sleeperfd = fd[1]; sa.sa_flags = 0; sa.sa_handler = cleanup_handler; sigaction(SIGINT, &sa, nil); sigaction(SIGTERM, &sa, nil); sigaction(SIGQUIT, &sa, nil); sigaction(SIGHUP, &sa, nil); sigaction(SIGUSR1, &sa, nil); sigaction(SIGUSR2, &sa, nil); }
int spawn3(int fd[3], const char *file, char *argv[]) { /* Some ideas from Russ Cox's libthread port. */ int p[2]; int pid; if(pipe(p) < 0) return -1; closeexec(p[1]); switch(pid = doublefork()) { case 0: dup2(fd[0], 0); dup2(fd[1], 1); dup2(fd[2], 2); execvp(file, argv); write(p[1], &errno, sizeof errno); exit(1); break; default: close(p[1]); if(read(p[0], &errno, sizeof errno) == sizeof errno) pid = -1; close(p[0]); break; case -1: /* can't happen */ break; } close(fd[0]); /* These could fail if any of these was also a previous fd. */ close(fd[1]); close(fd[2]); return pid; }