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:
Pawel Jakub Dawidek 2005-08-24 17:51:36 +00:00
parent 73dcba4b4b
commit 78735592f5
4 changed files with 29 additions and 63 deletions

View File

@ -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;

View File

@ -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[];

View File

@ -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);

View File

@ -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