Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/syslogd/syslogd.c
Show First 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | static const int sigcatch[] = { | ||||
SIGINT, | SIGINT, | ||||
SIGQUIT, | SIGQUIT, | ||||
SIGPIPE, | SIGPIPE, | ||||
SIGALRM, | SIGALRM, | ||||
SIGTERM, | SIGTERM, | ||||
SIGCHLD, | SIGCHLD, | ||||
}; | }; | ||||
static int nulldesc; /* /dev/null descriptor */ | |||||
static bool Debug; /* debug flag */ | static bool Debug; /* debug flag */ | ||||
static bool Foreground = false; /* Run in foreground, instead of daemonizing */ | static bool Foreground = false; /* Run in foreground, instead of daemonizing */ | ||||
static bool resolve = true; /* resolve hostname */ | static bool resolve = true; /* resolve hostname */ | ||||
static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ | static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */ | ||||
static const char *LocalDomain; /* our local domain name */ | static const char *LocalDomain; /* our local domain name */ | ||||
static bool Initialized; /* set when we have initialized ourselves */ | static bool Initialized; /* set when we have initialized ourselves */ | ||||
static int MarkInterval = 20 * 60; /* interval between marks in seconds */ | static int MarkInterval = 20 * 60; /* interval between marks in seconds */ | ||||
static int MarkSeq; /* mark sequence number */ | static int MarkSeq; /* mark sequence number */ | ||||
▲ Show 20 Lines • Show All 389 Lines • ▼ Show 20 Lines | #endif | ||||
/* Listen by default: /var/run/logpriv if no -S flag. */ | /* Listen by default: /var/run/logpriv if no -S flag. */ | ||||
if (Sflag == 0) | if (Sflag == 0) | ||||
addsock(_PATH_LOG_PRIV, NULL, S_IRUSR | S_IWUSR); | addsock(_PATH_LOG_PRIV, NULL, S_IRUSR | S_IWUSR); | ||||
consfile.f_type = F_CONSOLE; | consfile.f_type = F_CONSOLE; | ||||
consfile.f_file = -1; | consfile.f_file = -1; | ||||
(void)strlcpy(consfile.fu_fname, _PATH_CONSOLE + sizeof(_PATH_DEV) - 1, | (void)strlcpy(consfile.fu_fname, _PATH_CONSOLE + sizeof(_PATH_DEV) - 1, | ||||
sizeof(consfile.fu_fname)); | sizeof(consfile.fu_fname)); | ||||
nulldesc = open(_PATH_DEVNULL, O_RDWR); | |||||
if (nulldesc == -1) { | |||||
warn("cannot open %s", _PATH_DEVNULL); | |||||
pidfile_remove(pfh); | |||||
exit(1); | |||||
} | |||||
(void)strlcpy(bootfile, getbootfile(), sizeof(bootfile)); | (void)strlcpy(bootfile, getbootfile(), sizeof(bootfile)); | ||||
if ((!Foreground) && (!Debug)) { | if ((!Foreground) && (!Debug)) { | ||||
ppid = waitdaemon(30); | ppid = waitdaemon(30); | ||||
if (ppid < 0) { | if (ppid < 0) { | ||||
warn("could not become daemon"); | warn("could not become daemon"); | ||||
pidfile_remove(pfh); | pidfile_remove(pfh); | ||||
exit(1); | exit(1); | ||||
Show All 40 Lines | #endif | ||||
} | } | ||||
/* tuck my process id away */ | /* tuck my process id away */ | ||||
pidfile_write(pfh); | pidfile_write(pfh); | ||||
dprintf("off & running....\n"); | dprintf("off & running....\n"); | ||||
init(false); | init(false); | ||||
for (;;) { | for (;;) { | ||||
if (needdofsync) { | if (needdofsync) { | ||||
markj: I think you could reasonably abort the process if /dev/null isn't accessible. Then you don't… | |||||
dofsync(); | dofsync(); | ||||
if (ppid != -1) { | if (ppid != -1) { | ||||
kill(ppid, SIGALRM); | kill(ppid, SIGALRM); | ||||
ppid = -1; | ppid = -1; | ||||
} | } | ||||
} | } | ||||
if (kevent(kq, NULL, 0, &ev, 1, NULL) == -1) { | if (kevent(kq, NULL, 0, &ev, 1, NULL) == -1) { | ||||
if (errno != EINTR) | if (errno != EINTR) | ||||
▲ Show 20 Lines • Show All 2,359 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* fork off and become a daemon, but wait for the child to come online | * fork off and become a daemon, but wait for the child to come online | ||||
* before returning to the parent, or we get disk thrashing at boot etc. | * before returning to the parent, or we get disk thrashing at boot etc. | ||||
* Set a timer so we don't hang forever if it wedges. | * Set a timer so we don't hang forever if it wedges. | ||||
*/ | */ | ||||
static int | static int | ||||
waitdaemon(int maxwait) | waitdaemon(int maxwait) | ||||
{ | { | ||||
int fd; | |||||
int status; | int status; | ||||
pid_t pid, childpid; | pid_t pid, childpid; | ||||
switch (childpid = fork()) { | switch (childpid = fork()) { | ||||
case -1: | case -1: | ||||
return (-1); | return (-1); | ||||
case 0: | case 0: | ||||
break; | break; | ||||
Show All 14 Lines | default: | ||||
} | } | ||||
exit(0); | exit(0); | ||||
} | } | ||||
if (setsid() == -1) | if (setsid() == -1) | ||||
return (-1); | return (-1); | ||||
(void)chdir("/"); | (void)chdir("/"); | ||||
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { | (void)dup2(nulldesc, STDIN_FILENO); | ||||
(void)dup2(fd, STDIN_FILENO); | (void)dup2(nulldesc, STDOUT_FILENO); | ||||
(void)dup2(fd, STDOUT_FILENO); | (void)dup2(nulldesc, STDERR_FILENO); | ||||
(void)dup2(fd, STDERR_FILENO); | |||||
if (fd > STDERR_FILENO) | |||||
(void)close(fd); | |||||
} | |||||
return (getppid()); | return (getppid()); | ||||
} | } | ||||
/* | /* | ||||
* We get a SIGALRM from the child when it's running and finished doing it's | * We get a SIGALRM from the child when it's running and finished doing it's | ||||
* fsync()'s or O_SYNC writes for all the boot messages. | * fsync()'s or O_SYNC writes for all the boot messages. | ||||
* | * | ||||
* We also get a signal from the kernel if the timer expires, so check to | * We also get a signal from the kernel if the timer expires, so check to | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Fairly similar to popen(3), but returns an open descriptor, as | * Fairly similar to popen(3), but returns an open descriptor, as | ||||
* opposed to a FILE *. | * opposed to a FILE *. | ||||
*/ | */ | ||||
static int | static int | ||||
p_open(const char *prog, int *rpd) | p_open(const char *prog, int *rpd) | ||||
{ | { | ||||
sigset_t sigset = { }; | sigset_t sigset = { }; | ||||
int nulldesc, pfd[2], pd; | int pfd[2], pd; | ||||
pid_t pid; | pid_t pid; | ||||
char *argv[4]; /* sh -c cmd NULL */ | char *argv[4]; /* sh -c cmd NULL */ | ||||
char errmsg[200]; | char errmsg[200]; | ||||
if (pipe(pfd) == -1) | if (pipe(pfd) == -1) | ||||
return (-1); | return (-1); | ||||
if ((nulldesc = open(_PATH_DEVNULL, O_RDWR)) == -1) | |||||
/* we are royally screwed anyway */ | |||||
return (-1); | |||||
switch ((pid = pdfork(&pd, PD_CLOEXEC))) { | switch ((pid = pdfork(&pd, PD_CLOEXEC))) { | ||||
case -1: | case -1: | ||||
close(nulldesc); | |||||
return (-1); | return (-1); | ||||
Not Done Inline ActionsThere is a pre-existing buglet here in that pfd[0] and [1] are not closed if pdfork() fails. markj: There is a pre-existing buglet here in that pfd[0] and [1] are not closed if pdfork() fails. | |||||
case 0: | case 0: | ||||
(void)setsid(); /* Avoid catching SIGHUPs. */ | (void)setsid(); /* Avoid catching SIGHUPs. */ | ||||
argv[0] = strdup("sh"); | argv[0] = strdup("sh"); | ||||
argv[1] = strdup("-c"); | argv[1] = strdup("-c"); | ||||
argv[2] = strdup(prog); | argv[2] = strdup(prog); | ||||
argv[3] = NULL; | argv[3] = NULL; | ||||
if (argv[0] == NULL || argv[1] == NULL || argv[2] == NULL) { | if (argv[0] == NULL || argv[1] == NULL || argv[2] == NULL) { | ||||
Show All 13 Lines | case 0: | ||||
dup2(pfd[0], STDIN_FILENO); | dup2(pfd[0], STDIN_FILENO); | ||||
dup2(nulldesc, STDOUT_FILENO); | dup2(nulldesc, STDOUT_FILENO); | ||||
dup2(nulldesc, STDERR_FILENO); | dup2(nulldesc, STDERR_FILENO); | ||||
closefrom(STDERR_FILENO + 1); | closefrom(STDERR_FILENO + 1); | ||||
(void)execvp(_PATH_BSHELL, argv); | (void)execvp(_PATH_BSHELL, argv); | ||||
_exit(255); | _exit(255); | ||||
} | } | ||||
close(nulldesc); | |||||
close(pfd[0]); | close(pfd[0]); | ||||
/* | /* | ||||
* Avoid blocking on a hung pipe. With O_NONBLOCK, we are | * Avoid blocking on a hung pipe. With O_NONBLOCK, we are | ||||
* supposed to get an EWOULDBLOCK on writev(2), which is | * supposed to get an EWOULDBLOCK on writev(2), which is | ||||
* caught by the logic above anyway, which will in turn close | * caught by the logic above anyway, which will in turn close | ||||
* the pipe, and fork a new logging subprocess if necessary. | * the pipe, and fork a new logging subprocess if necessary. | ||||
* The stale subprocess will be killed some time later unless | * The stale subprocess will be killed some time later unless | ||||
* it terminated itself due to closing its input pipe (so we | * it terminated itself due to closing its input pipe (so we | ||||
▲ Show 20 Lines • Show All 166 Lines • Show Last 20 Lines |
I think you could reasonably abort the process if /dev/null isn't accessible. Then you don't need those nulldesc >= 0 checks.