Add -s (SINGLE_JOB) from OpenBSD.
This commit is contained in:
parent
3fba244ae4
commit
cd11565244
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cron.c,v 1.10 2017/06/09 17:36:30 christos Exp $ */
|
||||
/* $NetBSD: cron.c,v 1.11 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
* All rights reserved
|
||||
|
@ -25,7 +25,7 @@
|
|||
#if 0
|
||||
static char rcsid[] = "Id: cron.c,v 1.12 2004/01/23 18:56:42 vixie Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: cron.c,v 1.10 2017/06/09 17:36:30 christos Exp $");
|
||||
__RCSID("$NetBSD: cron.c,v 1.11 2020/04/18 19:32:19 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -532,6 +532,7 @@ sigchld_reaper(void) {
|
|||
Debug(DPROC,
|
||||
("[%ld] sigchld...pid #%ld died, stat=%d\n",
|
||||
(long)getpid(), (long)pid, WEXITSTATUS(waiter)));
|
||||
job_exit(pid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: crontab.5,v 1.9 2020/04/17 19:42:14 pgoyette Exp $
|
||||
.\" $NetBSD: crontab.5,v 1.10 2020/04/18 19:32:19 christos Exp $
|
||||
.\"
|
||||
.\"/* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
.\" * All rights reserved
|
||||
|
@ -227,6 +227,13 @@ option is an attempt to cure potentially copious volumes of mail coming from
|
|||
.Xr cron 8 .
|
||||
.It Fl q Ar command
|
||||
Execution will not be logged.
|
||||
.It Fl s Ar command
|
||||
Only a single instance of
|
||||
.Ar command
|
||||
will be run concurrently.
|
||||
Additional instances of
|
||||
.Ar command
|
||||
will not be scheduled until the earlier one completes.
|
||||
.El
|
||||
.Pp
|
||||
Commands are executed by
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: do_command.c,v 1.14 2019/08/03 07:06:47 christos Exp $ */
|
||||
/* $NetBSD: do_command.c,v 1.15 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
* All rights reserved
|
||||
|
@ -25,7 +25,7 @@
|
|||
#if 0
|
||||
static char rcsid[] = "Id: do_command.c,v 1.9 2004/01/23 18:56:42 vixie Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: do_command.c,v 1.14 2019/08/03 07:06:47 christos Exp $");
|
||||
__RCSID("$NetBSD: do_command.c,v 1.15 2020/04/18 19:32:19 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -35,7 +35,7 @@ __RCSID("$NetBSD: do_command.c,v 1.14 2019/08/03 07:06:47 christos Exp $");
|
|||
static int child_process(entry *);
|
||||
static int safe_p(const char *, const char *);
|
||||
|
||||
void
|
||||
pid_t
|
||||
do_command(entry *e, user *u) {
|
||||
int retval;
|
||||
|
||||
|
@ -66,9 +66,14 @@ do_command(entry *e, user *u) {
|
|||
break;
|
||||
default:
|
||||
/* parent process */
|
||||
if ((e->flags & SINGLE_JOB) == 0)
|
||||
jobpid = -1;
|
||||
break;
|
||||
}
|
||||
Debug(DPROC, ("[%ld] main process returning to work\n",(long)getpid()));
|
||||
|
||||
/* only return pid if a singleton */
|
||||
return jobpid;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: entry.c,v 1.10 2018/07/28 13:55:08 kre Exp $ */
|
||||
/* $OpenBSD: entry.c,v 1.51 2020/04/16 17:51:56 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
|
@ -26,7 +26,7 @@
|
|||
#if 0
|
||||
static char rcsid[] = "Id: entry.c,v 1.17 2004/01/23 18:56:42 vixie Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: entry.c,v 1.10 2018/07/28 13:55:08 kre Exp $");
|
||||
__RCSID("$NetBSD: entry.c,v 1.11 2020/04/18 19:32:19 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -361,6 +361,14 @@ load_entry(FILE *file, void (*error_func)(const char *), struct passwd *pw,
|
|||
}
|
||||
e->flags |= DONT_LOG;
|
||||
break;
|
||||
case 's':
|
||||
/* only allow the user to set the option once */
|
||||
if ((e->flags & SINGLE_JOB) == SINGLE_JOB) {
|
||||
ecode = e_option;
|
||||
goto eof;
|
||||
}
|
||||
e->flags |= SINGLE_JOB;
|
||||
break;
|
||||
default:
|
||||
ecode = e_option;
|
||||
goto eof;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: externs.h,v 1.2 2010/05/06 18:53:17 christos Exp $ */
|
||||
/* $NetBSD: externs.h,v 1.3 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/* Copyright 1993,1994 by Paul Vixie
|
||||
* All rights reserved
|
||||
|
@ -30,6 +30,7 @@
|
|||
#include <sys/fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <bitstring.h>
|
||||
#include <ctype.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: funcs.h,v 1.6 2018/06/14 22:04:28 christos Exp $ */
|
||||
/* $NetBSD: funcs.h,v 1.7 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Id: funcs.h,v 1.9 2004/01/23 18:56:42 vixie Exp
|
||||
|
@ -32,7 +32,8 @@ void set_cron_uid(void),
|
|||
open_logfile(void),
|
||||
sigpipe_func(void),
|
||||
job_add(entry *, user *, time_t),
|
||||
do_command(entry *, user *),
|
||||
job_remove(entry *, user *),
|
||||
job_exit(pid_t),
|
||||
link_user(cron_db *, user *),
|
||||
unlink_user(cron_db *, user *),
|
||||
free_user(user *),
|
||||
|
@ -49,6 +50,8 @@ void
|
|||
log_itx(const char *, int, const char *, const char *, ...)
|
||||
__printflike(4, 5);
|
||||
|
||||
pid_t do_command(entry *, user *);
|
||||
|
||||
int job_runqueue(void),
|
||||
set_debug_flags(const char *),
|
||||
get_char(FILE *),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: job.c,v 1.2 2010/05/06 18:53:17 christos Exp $ */
|
||||
/* $NetBSD: job.c,v 1.3 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
* All rights reserved
|
||||
|
@ -26,20 +26,21 @@
|
|||
#if 0
|
||||
static char rcsid[] = "Id: job.c,v 1.6 2004/01/23 18:56:43 vixie Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: job.c,v 1.2 2010/05/06 18:53:17 christos Exp $");
|
||||
__RCSID("$NetBSD: job.c,v 1.3 2020/04/18 19:32:19 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "cron.h"
|
||||
|
||||
typedef struct _job {
|
||||
struct _job *next;
|
||||
SIMPLEQ_ENTRY(_job) entries;
|
||||
entry *e;
|
||||
user *u;
|
||||
time_t t;
|
||||
pid_t pid;
|
||||
} job;
|
||||
|
||||
static job *jhead = NULL, *jtail = NULL;
|
||||
static SIMPLEQ_HEAD(job_queue, _job) jobs = SIMPLEQ_HEAD_INITIALIZER(jobs);
|
||||
|
||||
static int okay_to_go(job *);
|
||||
|
||||
|
@ -48,48 +49,86 @@ job_add(entry *e, user *u, time_t target_time) {
|
|||
job *j;
|
||||
|
||||
/* if already on queue, keep going */
|
||||
for (j = jhead; j != NULL; j = j->next)
|
||||
SIMPLEQ_FOREACH(j, &jobs, entries) {
|
||||
if (j->e == e && j->u == u) {
|
||||
j->t = target_time;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* build a job queue element */
|
||||
if ((j = malloc(sizeof(*j))) == NULL)
|
||||
if ((j = calloc(1, sizeof(*j))) == NULL)
|
||||
return;
|
||||
j->next = NULL;
|
||||
j->e = e;
|
||||
j->u = u;
|
||||
j->t = target_time;
|
||||
j->pid = -1;
|
||||
|
||||
/* add it to the tail */
|
||||
if (jhead == NULL)
|
||||
jhead = j;
|
||||
else
|
||||
jtail->next = j;
|
||||
jtail = j;
|
||||
SIMPLEQ_INSERT_TAIL(&jobs, j, entries);
|
||||
}
|
||||
|
||||
void
|
||||
job_remove(entry *e, user *u)
|
||||
{
|
||||
job *j, *prev = NULL;
|
||||
|
||||
SIMPLEQ_FOREACH(j, &jobs, entries) {
|
||||
if (j->e == e && j->u == u) {
|
||||
if (prev == NULL)
|
||||
SIMPLEQ_REMOVE_HEAD(&jobs, entries);
|
||||
else
|
||||
SIMPLEQ_REMOVE_AFTER(&jobs, prev, entries);
|
||||
free(j);
|
||||
break;
|
||||
}
|
||||
prev = j;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
job_exit(pid_t jobpid)
|
||||
{
|
||||
job *j, *prev = NULL;
|
||||
|
||||
/* If a singleton exited, remove and free it. */
|
||||
SIMPLEQ_FOREACH(j, &jobs, entries) {
|
||||
if (jobpid == j->pid) {
|
||||
if (prev == NULL)
|
||||
SIMPLEQ_REMOVE_HEAD(&jobs, entries);
|
||||
else
|
||||
SIMPLEQ_REMOVE_AFTER(&jobs, prev, entries);
|
||||
free(j);
|
||||
break;
|
||||
}
|
||||
prev = j;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
job_runqueue(void) {
|
||||
job *j, *jn;
|
||||
struct job_queue singletons = SIMPLEQ_HEAD_INITIALIZER(singletons);
|
||||
job *j;
|
||||
int run = 0;
|
||||
|
||||
for (j = jhead; j; j = jn) {
|
||||
if (okay_to_go(j))
|
||||
do_command(j->e, j->u);
|
||||
else {
|
||||
while ((j = SIMPLEQ_FIRST(&jobs))) {
|
||||
SIMPLEQ_REMOVE_HEAD(&jobs, entries);
|
||||
if (okay_to_go(j)) {
|
||||
j->pid = do_command(j->e, j->u);
|
||||
run++;
|
||||
} else {
|
||||
char *x = mkprints(j->e->cmd, strlen(j->e->cmd));
|
||||
char *usernm = env_get("LOGNAME", j->e->envp);
|
||||
|
||||
log_it(usernm, getpid(), "CMD (skipped)", x);
|
||||
free(x);
|
||||
}
|
||||
jn = j->next;
|
||||
free(j);
|
||||
run++;
|
||||
if (j->pid != -1)
|
||||
SIMPLEQ_INSERT_TAIL(&singletons, j, entries);
|
||||
else
|
||||
free(j);
|
||||
}
|
||||
jhead = jtail = NULL;
|
||||
SIMPLEQ_CONCAT(&jobs, &singletons);
|
||||
return (run);
|
||||
}
|
||||
|
||||
|
@ -100,6 +139,9 @@ okay_to_go(job *j)
|
|||
char *within, *t;
|
||||
long delta;
|
||||
|
||||
if (j->pid != -1)
|
||||
return 0;
|
||||
|
||||
if (j->e->flags & WHEN_REBOOT)
|
||||
return (1);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct _entry {
|
|||
#define WHEN_REBOOT 0x10
|
||||
#define DONT_LOG 0x20
|
||||
#define MAIL_WHEN_ERR 0x40
|
||||
#define SINGLE_JOB 0x80
|
||||
} entry;
|
||||
|
||||
/* the crontab database will be a list of the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: user.c,v 1.2 2010/05/06 18:53:17 christos Exp $ */
|
||||
/* $NetBSD: user.c,v 1.3 2020/04/18 19:32:19 christos Exp $ */
|
||||
|
||||
/* Copyright 1988,1990,1993,1994 by Paul Vixie
|
||||
* All rights reserved
|
||||
|
@ -25,7 +25,7 @@
|
|||
#if 0
|
||||
static char rcsid[] = "Id: user.c,v 1.5 2004/01/23 18:56:43 vixie Exp";
|
||||
+#else
|
||||
+__RCSID("$NetBSD: user.c,v 1.2 2010/05/06 18:53:17 christos Exp $");
|
||||
+__RCSID("$NetBSD: user.c,v 1.3 2020/04/18 19:32:19 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -41,6 +41,7 @@ free_user(user *u) {
|
|||
free(u->name);
|
||||
for (e = u->crontab; e != NULL; e = ne) {
|
||||
ne = e->next;
|
||||
job_remove(e, u);
|
||||
free_entry(e);
|
||||
}
|
||||
free(u);
|
||||
|
|
Loading…
Reference in New Issue