Add -s (SINGLE_JOB) from OpenBSD.

This commit is contained in:
christos 2020-04-18 19:32:19 +00:00
parent 3fba244ae4
commit cd11565244
9 changed files with 103 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 *),

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

View File

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

View File

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