-/* $OpenBSD: cron.c,v 1.54 2015/10/03 12:46:54 tedu Exp $ */
+/* $OpenBSD: cron.c,v 1.55 2015/10/25 21:30:11 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
sigchld_handler(int),
sighup_handler(int),
sigchld_reaper(void),
- quit(int),
parse_args(int c, char *v[]);
static volatile sig_atomic_t got_sighup, got_sigchld;
(void) sigaction(SIGCHLD, &sact, NULL);
sact.sa_handler = sighup_handler;
(void) sigaction(SIGHUP, &sact, NULL);
- sact.sa_handler = quit;
- (void) sigaction(SIGINT, &sact, NULL);
- (void) sigaction(SIGTERM, &sact, NULL);
sact.sa_handler = SIG_IGN;
(void) sigaction(SIGPIPE, &sact, NULL);
- acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();
+ cronSock = open_socket();
+
if (putenv("PATH="_PATH_DEFPATH) < 0) {
log_it("CRON", getpid(), "DEATH", "can't malloc");
exit(EXIT_FAILURE);
}
if (NoFork == 0) {
- switch (fork()) {
- case -1:
+ if (daemon(1, 0) == -1) {
log_it("CRON",getpid(),"DEATH","can't fork");
exit(EXIT_FAILURE);
- break;
- case 0:
- /* child process */
- (void) setsid();
- if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) >= 0) {
- (void) dup2(fd, STDIN_FILENO);
- (void) dup2(fd, STDOUT_FILENO);
- (void) dup2(fd, STDERR_FILENO);
- if (fd != STDERR_FILENO)
- (void) close(fd);
- }
- log_it("CRON",getpid(),"STARTUP",CRON_VERSION);
- break;
- default:
- /* parent process should just die */
- _exit(EXIT_SUCCESS);
}
+ log_it("CRON",getpid(),"STARTUP",CRON_VERSION);
}
- acquire_daemonlock(0);
- cronSock = open_socket();
database.head = NULL;
database.tail = NULL;
database.mtime = 0;
got_sigchld = 1;
}
-static void
-quit(int x)
-{
- (void) unlink(_PATH_CRON_PID);
- _exit(0);
-}
-
static void
sigchld_reaper(void)
{
-/* $OpenBSD: misc.c,v 1.57 2015/10/23 18:42:55 tedu Exp $ */
+/* $OpenBSD: misc.c,v 1.58 2015/10/25 21:30:11 millert Exp $ */
/* Copyright 1988,1990,1993,1994 by Paul Vixie
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
}
}
-/* acquire_daemonlock() - write our PID into /var/run/cron.pid, unless
- * another daemon is already running, which we detect here.
- *
- * note: main() calls us twice; once before forking, once after.
- * we maintain static storage of the file pointer so that we
- * can rewrite our PID into _PATH_CRON_PID after the fork.
- */
-void
-acquire_daemonlock(int closeflag)
-{
- static int fd = -1;
- char buf[3*MAX_FNAME];
- const char *pidfile;
- char *ep;
- long otherpid;
- ssize_t num;
-
- if (closeflag) {
- /* close stashed fd for child so we don't leak it. */
- if (fd != -1) {
- close(fd);
- fd = -1;
- }
- return;
- }
-
- if (fd == -1) {
- pidfile = _PATH_CRON_PID;
- fd = open(pidfile,
- O_RDWR|O_CREAT|O_EXLOCK|O_NONBLOCK|O_CLOEXEC, 0644);
- if (fd == -1) {
- int save_errno = errno;
-
- if (errno != EWOULDBLOCK) {
- snprintf(buf, sizeof buf,
- "can't open or create %s: %s", pidfile,
- strerror(save_errno));
- fprintf(stderr, "%s: %s\n", ProgramName, buf);
- log_it("CRON", getpid(), "DEATH", buf);
- exit(EXIT_FAILURE);
- }
-
- /* couldn't lock the pid file, try to read existing. */
- bzero(buf, sizeof(buf));
- if ((fd = open(pidfile, O_RDONLY, 0)) >= 0 &&
- (num = read(fd, buf, sizeof(buf) - 1)) > 0 &&
- (otherpid = strtol(buf, &ep, 10)) > 0 &&
- ep != buf && *ep == '\n' && otherpid != LONG_MAX) {
- snprintf(buf, sizeof buf,
- "can't lock %s, otherpid may be %ld: %s",
- pidfile, otherpid, strerror(save_errno));
- } else {
- snprintf(buf, sizeof buf,
- "can't lock %s, otherpid unknown: %s",
- pidfile, strerror(save_errno));
- }
- fprintf(stderr, "%s: %s\n", ProgramName, buf);
- log_it("CRON", getpid(), "DEATH", buf);
- exit(EXIT_FAILURE);
- }
- /* fd must be > STDERR_FILENO since we dup fd 0-2 to /dev/null */
- if (fd <= STDERR_FILENO) {
- int newfd;
-
- newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
- if (newfd < 0) {
- snprintf(buf, sizeof buf,
- "can't dup pid fd: %s", strerror(errno));
- fprintf(stderr, "%s: %s\n", ProgramName, buf);
- log_it("CRON", getpid(), "DEATH", buf);
- exit(EXIT_FAILURE);
- }
- close(fd);
- fd = newfd;
- }
- }
-
- snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
- (void) lseek(fd, 0, SEEK_SET);
- num = write(fd, buf, strlen(buf));
- (void) ftruncate(fd, num);
-
- /* abandon fd even though the file is open. we need to keep
- * it open and locked, but we don't need the handles elsewhere.
- */
-}
-
/* get_char(file) : like getc() but increment LineNumber on newlines
*/
int
* If the local pointer is non-NULL it *must* point to a local copy.
*/
-/* void open_socket(void)
+/* int open_socket(void)
* opens a UNIX domain socket that crontab uses to poke cron.
+ * If the socket is already in use, return an error.
*/
int
open_socket(void)
log_it("CRON", getpid(), "DEATH", "path too long");
exit(EXIT_FAILURE);
}
- unlink(s_un.sun_path);
s_un.sun_family = AF_UNIX;
s_un.sun_len = SUN_LEN(&s_un);
+ if (connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == 0) {
+ fprintf(stderr, "%s: already running\n", ProgramName);
+ log_it("CRON", getpid(), "DEATH", "already running");
+ exit(EXIT_FAILURE);
+ }
+ if (errno != ENOENT)
+ unlink(s_un.sun_path);
+
omask = umask(007);
if (bind(sock, (struct sockaddr *)&s_un, sizeof(s_un))) {
fprintf(stderr, "%s: can't bind socket: %s\n",