Use pidfile(3) in cron(8).
Note, that when cron(8) cannot create pidfile, it'll exit. I didn't changed this behaviour, but its better to ignore errors other than EEXIST, so daemon can be started on systems where /var/ file system doesn't support locking (like NFS without rpc.lockd(8)).
This commit is contained in:
parent
73dcba4b4b
commit
78735592f5
@ -46,6 +46,7 @@ static void usage __P((void)),
|
||||
|
||||
static time_t last_time = 0;
|
||||
static int dst_enabled = 0;
|
||||
struct pidfh *pfh;
|
||||
|
||||
static void
|
||||
usage() {
|
||||
@ -63,6 +64,28 @@ usage() {
|
||||
exit(ERROR_EXIT);
|
||||
}
|
||||
|
||||
static void
|
||||
open_pidfile(void)
|
||||
{
|
||||
char pidfile[MAX_FNAME];
|
||||
char buf[MAX_TEMPSTR];
|
||||
int otherpid;
|
||||
|
||||
(void) snprintf(pidfile, sizeof(pidfile), PIDFILE, PIDDIR);
|
||||
pfh = pidfile_open(pidfile, 0644, &otherpid);
|
||||
if (pfh == NULL) {
|
||||
if (errno == EEXIST) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
"cron already running, pid: %d", otherpid);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf),
|
||||
"can't open or create %s: %s", pidfile,
|
||||
strerror(errno));
|
||||
}
|
||||
log_it("CRON", getpid(), "DEATH", buf);
|
||||
errx(ERROR_EXIT, "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -87,7 +110,7 @@ main(argc, argv)
|
||||
#endif
|
||||
(void) signal(SIGHUP, sighup_handler);
|
||||
|
||||
acquire_daemonlock(0);
|
||||
open_pidfile();
|
||||
set_cron_uid();
|
||||
set_cron_cwd();
|
||||
|
||||
@ -105,12 +128,13 @@ main(argc, argv)
|
||||
(void) fprintf(stderr, "[%d] cron started\n", getpid());
|
||||
} else {
|
||||
if (daemon(1, 0) == -1) {
|
||||
pidfile_remove(pfh);
|
||||
log_it("CRON",getpid(),"DEATH","can't become daemon");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
acquire_daemonlock(0);
|
||||
pidfile_write(pfh);
|
||||
database.head = NULL;
|
||||
database.tail = NULL;
|
||||
database.mtime = (time_t) 0;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <libutil.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -210,7 +211,6 @@ void set_cron_uid __P((void)),
|
||||
env_free __P((char **)),
|
||||
unget_char __P((int, FILE *)),
|
||||
free_entry __P((entry *)),
|
||||
acquire_daemonlock __P((int)),
|
||||
skip_comments __P((FILE *)),
|
||||
log_it __P((char *, int, char *, char *)),
|
||||
log_close __P((void));
|
||||
@ -289,6 +289,7 @@ extern int LineNumber;
|
||||
extern unsigned Jitter,
|
||||
RootJitter;
|
||||
extern time_t TargetTime;
|
||||
extern struct pidfh *pfh;
|
||||
# if DEBUGGING
|
||||
extern int DebugFlags;
|
||||
extern char *DebugFlagNames[];
|
||||
|
@ -59,7 +59,7 @@ do_command(e, u)
|
||||
break;
|
||||
case 0:
|
||||
/* child process */
|
||||
acquire_daemonlock(1);
|
||||
pidfile_close(pfh);
|
||||
child_process(e, u);
|
||||
Debug(DPROC, ("[%d] child process done, exiting\n", getpid()))
|
||||
_exit(OK_EXIT);
|
||||
|
@ -222,65 +222,6 @@ set_cron_cwd()
|
||||
}
|
||||
|
||||
|
||||
/* acquire_daemonlock() - write our PID into /etc/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 the PIDFILE after the fork.
|
||||
*
|
||||
* it would be great if fflush() disassociated the file buffer.
|
||||
*/
|
||||
void
|
||||
acquire_daemonlock(closeflag)
|
||||
int closeflag;
|
||||
{
|
||||
static FILE *fp = NULL;
|
||||
|
||||
if (closeflag && fp) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fp) {
|
||||
char pidfile[MAX_FNAME];
|
||||
char buf[MAX_TEMPSTR];
|
||||
int fd, otherpid;
|
||||
|
||||
(void) sprintf(pidfile, PIDFILE, PIDDIR);
|
||||
if ((-1 == (fd = open(pidfile, O_RDWR|O_CREAT, 0644)))
|
||||
|| (NULL == (fp = fdopen(fd, "r+")))
|
||||
) {
|
||||
sprintf(buf, "can't open or create %s: %s",
|
||||
pidfile, strerror(errno));
|
||||
log_it("CRON", getpid(), "DEATH", buf);
|
||||
errx(ERROR_EXIT, "%s", buf);
|
||||
}
|
||||
|
||||
if (flock(fd, LOCK_EX|LOCK_NB) < OK) {
|
||||
int save_errno = errno;
|
||||
|
||||
fscanf(fp, "%d", &otherpid);
|
||||
sprintf(buf, "can't lock %s, otherpid may be %d: %s",
|
||||
pidfile, otherpid, strerror(save_errno));
|
||||
log_it("CRON", getpid(), "DEATH", buf);
|
||||
errx(ERROR_EXIT, "%s", buf);
|
||||
}
|
||||
|
||||
(void) fcntl(fd, F_SETFD, 1);
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
fprintf(fp, "%d\n", getpid());
|
||||
fflush(fp);
|
||||
(void) ftruncate(fileno(fp), ftell(fp));
|
||||
|
||||
/* abandon fd and fp 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
|
||||
|
Loading…
Reference in New Issue
Block a user