diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -109,6 +109,7 @@ #include #include #include +#include #include #include #include @@ -288,7 +289,7 @@ } f_forw; /* F_FORW */ struct { char f_pname[MAXPATHLEN]; - pid_t f_pid; + int f_procdesc; } f_pipe; /* F_PIPE */ } f_un; #define fu_uname f_un.f_uname @@ -296,7 +297,7 @@ #define fu_forw_hname f_un.f_forw.f_hname #define fu_forw_addr f_un.f_forw.f_addr #define fu_pipe_pname f_un.f_pipe.f_pname -#define fu_pipe_pid f_un.f_pipe.f_pid +#define fu_pipe_pd f_un.f_pipe.f_procdesc /* Book-keeping. */ char f_prevline[MAXSVLINE]; /* last message logged */ @@ -317,7 +318,7 @@ * Queue of about-to-be dead processes we should watch out for. */ struct deadq_entry { - pid_t dq_pid; + int dq_procdesc; int dq_timeout; TAILQ_ENTRY(deadq_entry) dq_entries; }; @@ -426,8 +427,8 @@ static void addsock(const char *, const char *, mode_t); static void cfline(const char *, const char *, const char *, const char *); static const char *cvthname(struct sockaddr *); -static void deadq_enter(pid_t, const char *); -static int deadq_remove(struct deadq_entry *); +static void deadq_enter(int); +static void deadq_remove(struct deadq_entry *); static int decode(const char *, const CODE *); static void die(int) __dead2; static void dofsync(void); @@ -439,7 +440,6 @@ static void logerror(const char *); static void logmsg(int, const struct logtime *, const char *, const char *, const char *, const char *, const char *, const char *, int); -static void log_deadchild(pid_t, int, const char *); static void markit(void); static struct socklist *socksetup(struct addrinfo *, const char *, mode_t); static int socklist_recv_file(struct socklist *); @@ -481,7 +481,10 @@ f->f_type = F_UNUSED; break; case F_PIPE: - f->fu_pipe_pid = 0; + if (f->fu_pipe_pd != -1) { + (void)close(f->fu_pipe_pd); + f->fu_pipe_pd = -1; + } break; default: break; @@ -1916,17 +1919,16 @@ case F_PIPE: dprintf(" %s\n", f->fu_pipe_pname); iovlist_append(il, "\n"); - if (f->fu_pipe_pid == 0) { + if (f->fu_pipe_pd == -1) { if ((f->f_file = p_open(f->fu_pipe_pname, - &f->fu_pipe_pid)) < 0) { + &f->fu_pipe_pd)) < 0) { logerror(f->fu_pipe_pname); break; } } if (writev(f->f_file, il->iov, il->iovcnt) < 0) { int e = errno; - - deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname); + deadq_enter(f->fu_pipe_pd); close_filed(f); errno = e; logerror(f->fu_pipe_pname); @@ -2300,7 +2302,7 @@ /* flush any pending output */ if (f->f_prevcount) fprintlog_successive(f, 0); - if (f->f_type == F_PIPE && f->fu_pipe_pid > 0) + if (f->f_type == F_PIPE && f->fu_pipe_pd >= 0) close_filed(f); } if (signo) { @@ -2557,7 +2559,7 @@ close_filed(f); break; case F_PIPE: - deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname); + deadq_enter(f->fu_pipe_pd); close_filed(f); break; default: @@ -3084,7 +3086,7 @@ break; case '|': - f->fu_pipe_pid = 0; + f->fu_pipe_pd = -1; (void)strlcpy(f->fu_pipe_pname, p + 1, sizeof(f->fu_pipe_pname)); f->f_type = F_PIPE; @@ -3169,12 +3171,12 @@ switch (dq->dq_timeout) { case 0: /* Already signalled once, try harder now. */ - (void)kill(dq->dq_pid, SIGKILL); + (void)pdkill(dq->dq_procdesc, SIGKILL); (void)deadq_remove(dq); break; case 1: - if (kill(dq->dq_pid, SIGTERM) != 0) + if (pdkill(dq->dq_procdesc, SIGTERM) != 0) (void)deadq_remove(dq); else dq->dq_timeout--; @@ -3551,10 +3553,10 @@ * opposed to a FILE *. */ static int -p_open(const char *prog, pid_t *rpid) +p_open(const char *prog, int *rpd) { sigset_t sigset = { }; - int pfd[2], nulldesc; + int nulldesc, pfd[2], pd; pid_t pid; char *argv[4]; /* sh -c cmd NULL */ char errmsg[200]; @@ -3565,7 +3567,7 @@ /* we are royally screwed anyway */ return (-1); - switch ((pid = fork())) { + switch ((pid = pdfork(&pd, PD_CLOEXEC))) { case -1: close(nulldesc); return (-1); @@ -3617,74 +3619,36 @@ (int)pid); logerror(errmsg); } - *rpid = pid; + *rpd = pd; return (pfd[1]); } static void -deadq_enter(pid_t pid, const char *name) +deadq_enter(int pd) { struct deadq_entry *dq; - int status; - if (pid == 0) - return; - /* - * Be paranoid, if we can't signal the process, don't enter it - * into the dead queue (perhaps it's already dead). If possible, - * we try to fetch and log the child's status. - */ - if (kill(pid, 0) != 0) { - if (waitpid(pid, &status, WNOHANG) > 0) - log_deadchild(pid, status, name); + if (pd == -1) return; - } dq = malloc(sizeof(*dq)); if (dq == NULL) { logerror("malloc"); exit(1); } - *dq = (struct deadq_entry){ - .dq_pid = pid, - .dq_timeout = DQ_TIMO_INIT - }; + + dq->dq_procdesc = pd; + dq->dq_timeout = DQ_TIMO_INIT; TAILQ_INSERT_TAIL(&deadq_head, dq, dq_entries); } -static int +static void deadq_remove(struct deadq_entry *dq) { if (dq != NULL) { TAILQ_REMOVE(&deadq_head, dq, dq_entries); free(dq); - return (1); - } - - return (0); -} - -static void -log_deadchild(pid_t pid, int status, const char *name) -{ - int code; - char buf[256]; - const char *reason; - - errno = 0; /* Keep strerror() stuff out of logerror messages. */ - if (WIFSIGNALED(status)) { - reason = "due to signal"; - code = WTERMSIG(status); - } else { - reason = "with status"; - code = WEXITSTATUS(status); - if (code == 0) - return; } - (void)snprintf(buf, sizeof buf, - "Logging subprocess %d (%s) exited %s %d.", - pid, name, reason, code); - logerror(buf); } static struct socklist *