Get rid of grandchild hack, it was causing problems and there is really

no need for it.  This fixes a bug where we spin eating up CPU when the
user runs a long-running process like a shell.
This commit is contained in:
Todd C. Miller
2000-03-13 16:05:05 +00:00
parent 5684831592
commit a6ad7f071c

View File

@@ -403,16 +403,24 @@ send_mail(line)
{ {
FILE *mail; FILE *mail;
char *p; char *p;
int pfd[2], pid; int pfd[2], pid, status;
#ifdef POSIX_SIGNALS
sigset_t set, oset;
#else
int omask;
#endif /* POSIX_SIGNALS */
/* Just return if mailer is disabled. */ /* Just return if mailer is disabled. */
if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO)) if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO))
return; return;
if ((pid = fork()) > 0) { /* Child. */ #ifdef POSIX_SIGNALS
(void) sigemptyset(&set);
/* We do an explicit wait() later on... */ (void) sigaddset(&set, SIGCHLD);
(void) signal(SIGCHLD, SIG_IGN); (void) sigprocmask(SIG_BLOCK, &set, &oset);
#else
omask = sigblock(sigmask(SIGCHLD));
#endif /* POSIX_SIGNALS */
if (pipe(pfd) == -1) { if (pipe(pfd) == -1) {
(void) fprintf(stderr, "%s: cannot open pipe: %s\n", (void) fprintf(stderr, "%s: cannot open pipe: %s\n",
@@ -423,8 +431,6 @@ send_mail(line)
switch (pid = fork()) { switch (pid = fork()) {
case -1: case -1:
/* Error. */ /* Error. */
/* XXX - parent will continue, return an exit val to
let parent know and abort? */
(void) fprintf(stderr, "%s: cannot fork: %s\n", (void) fprintf(stderr, "%s: cannot fork: %s\n",
Argv[0], strerror(errno)); Argv[0], strerror(errno));
exit(1); exit(1);
@@ -435,7 +441,7 @@ send_mail(line)
char *mpath, *mflags; char *mpath, *mflags;
int i; int i;
/* Grandchild. */ /* Child. */
(void) close(pfd[1]); (void) close(pfd[1]);
(void) dup2(pfd[0], STDIN_FILENO); (void) dup2(pfd[0], STDIN_FILENO);
(void) close(pfd[0]); (void) close(pfd[0]);
@@ -490,16 +496,16 @@ send_mail(line)
(void) fprintf(mail, "\n\n%s : %s : %s : %s\n\n", user_host, (void) fprintf(mail, "\n\n%s : %s : %s : %s\n\n", user_host,
get_timestr(), user_name, line); get_timestr(), user_name, line);
fclose(mail); fclose(mail);
reapchild(0);
_exit(0); /* If mailer is done, wait for it now. If not reapchild will get it. */
} else { #ifdef sudo_waitpid
/* Parent, just return unless there is an error. */ (void) sudo_waitpid(pid, &status, WNOHANG);
if (pid == -1) { #endif
(void) fprintf(stderr, "%s: cannot fork: %s\n", #ifdef POSIX_SIGNALS
Argv[0], strerror(errno)); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
exit(1); #else
} (void) sigsetmask(omask);
} #endif /* POSIX_SIGNALS */
} }
/* /*
@@ -540,7 +546,7 @@ reapchild(sig)
int status, serrno = errno; int status, serrno = errno;
#ifdef sudo_waitpid #ifdef sudo_waitpid
while (sudo_waitpid(-1, &status, WNOHANG) != -1) while (sudo_waitpid(-1, &status, WNOHANG) != -1 && errno == EINTR)
; ;
#else #else
(void) wait(&status); (void) wait(&status);