pid_t __wait(int *istat) { #ifdef VARIANT_CANCELABLE return (__wait4(WAIT_ANY, istat, 0, (struct rusage *)0)); #else /* !VARIANT_CANCELABLE */ return (__wait4_nocancel(WAIT_ANY, istat, 0, (struct rusage *)0)); #endif /* VARIANT_CANCELABLE */ }
/* Wait for a child to exit. When one does, put its status in *STAT_LOC and return its process ID. For errors return (pid_t) -1. If USAGE is not nil, store information about the child's resource usage (as a `struct rusage') there. If the WUNTRACED bit is set in OPTIONS, return status for stopped children; otherwise don't. */ pid_t __wait3 (__WAIT_STATUS stat_loc, int options, struct rusage *usage) { return __wait4 (WAIT_ANY, stat_loc, options, usage); }
/* Wait for a child matching PID to die. If PID is greater than 0, match any process whose process ID is PID. If PID is (pid_t) -1, match any process. If PID is (pid_t) 0, match any process with the same process group as the current process. If PID is less than -1, match any process whose process group is the absolute value of PID. If the WNOHANG bit is set in OPTIONS, and that child is not already dead, return (pid_t) 0. If successful, return PID and store the dead child's status in STAT_LOC. Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS, return status for stopped children; otherwise don't. */ pid_t __libc_waitpid (pid_t pid, int *stat_loc, int options) { return __wait4 (pid, (union wait *) stat_loc, options, NULL); }
static int internal_function key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt, char *rslt) { XDR xdrargs; XDR xdrrslt; FILE *fargs; FILE *frslt; sigset_t oldmask, mask; union wait status; int pid; int success; uid_t ruid; uid_t euid; static const char MESSENGER[] = "/usr/etc/keyenvoy"; success = 1; sigemptyset (&mask); sigaddset (&mask, SIGCHLD); __sigprocmask (SIG_BLOCK, &mask, &oldmask); /* * We are going to exec a set-uid program which makes our effective uid * zero, and authenticates us with our real uid. We need to make the * effective uid be the real uid for the setuid program, and * the real uid be the effective uid so that we can change things back. */ euid = __geteuid (); ruid = __getuid (); __setreuid (euid, ruid); pid = _openchild (MESSENGER, &fargs, &frslt); __setreuid (ruid, euid); if (pid < 0) { debug ("open_streams"); __sigprocmask (SIG_SETMASK, &oldmask, NULL); return (0); } xdrstdio_create (&xdrargs, fargs, XDR_ENCODE); xdrstdio_create (&xdrrslt, frslt, XDR_DECODE); if (!INTUSE(xdr_u_long) (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg)) { debug ("xdr args"); success = 0; } fclose (fargs); if (success && !(*xdr_rslt) (&xdrrslt, rslt)) { debug ("xdr rslt"); success = 0; } fclose(frslt); wait_again: if (__wait4 (pid, &status, 0, NULL) < 0) { if (errno == EINTR) goto wait_again; debug ("wait4"); if (errno == ECHILD || errno == ESRCH) perror ("wait"); else success = 0; } else if (status.w_retcode) { debug ("wait4 1"); success = 0; } __sigprocmask (SIG_SETMASK, &oldmask, NULL); return success; }
/* Wait for a child to die. When one does, put its status in *STAT_LOC and return its process ID. For errors, return (pid_t) -1. */ __pid_t __libc_wait (__WAIT_STATUS_DEFN stat_loc) { return __wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); }
/* Wait for a child matching PID to die. If PID is greater than 0, match any process whose process ID is PID. If PID is (pid_t) -1, match any process. If PID is (pid_t) 0, match any process with the same process group as the current process. If PID is less than -1, match any process whose process group is the absolute value of PID. If the WNOHANG bit is set in OPTIONS, and that child is not already dead, return (pid_t) 0. If successful, return PID and store the dead child's status in STAT_LOC. Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS, return status for stopped children; otherwise don't. */ pid_t __waitpid (pid_t pid, int *stat_loc, int options) { return __wait4 (pid, stat_loc, options, NULL); }