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