Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/cron/dist Add -n (don't send mail if command ex...
details: https://anonhg.NetBSD.org/src/rev/5f676bf8a30d
branches: trunk
changeset: 319894:5f676bf8a30d
user: christos <christos%NetBSD.org@localhost>
date: Thu Jun 14 22:04:28 2018 +0000
description:
Add -n (don't send mail if command exited normally) option. From OpenBSD via
Job Snidjers.
diffstat:
external/bsd/cron/dist/do_command.c | 68 +++++++++++++++++++++++++++---------
external/bsd/cron/dist/entry.c | 26 +++++++++++--
external/bsd/cron/dist/funcs.h | 3 +-
external/bsd/cron/dist/popen.c | 33 ++++++++++++++---
external/bsd/cron/dist/structs.h | 3 +-
5 files changed, 102 insertions(+), 31 deletions(-)
diffs (297 lines):
diff -r a2dadc5b5cc6 -r 5f676bf8a30d external/bsd/cron/dist/do_command.c
--- a/external/bsd/cron/dist/do_command.c Thu Jun 14 22:02:57 2018 +0000
+++ b/external/bsd/cron/dist/do_command.c Thu Jun 14 22:04:28 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: do_command.c,v 1.12 2018/02/04 03:37:59 christos Exp $ */
+/* $NetBSD: do_command.c,v 1.13 2018/06/14 22:04:28 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.12 2018/02/04 03:37:59 christos Exp $");
+__RCSID("$NetBSD: do_command.c,v 1.13 2018/06/14 22:04:28 christos Exp $");
#endif
#endif
@@ -50,7 +50,9 @@
* vfork() is unsuitable, since we have much to do, and the parent
* needs to be able to run off and fork other processes.
*/
- switch (fork()) {
+
+ pid_t jobpid;
+ switch (jobpid = fork()) {
case -1:
log_it("CRON", getpid(), "error", "can't fork");
break;
@@ -144,7 +146,7 @@
static int
read_data(entry *e, const char *mailto, const char *usernm, char **envp,
- int *stdout_pipe)
+ int *stdout_pipe, pid_t jobpid)
{
FILE *in = fdopen(stdout_pipe[READ_PIPE], "r");
FILE *mail = NULL;
@@ -241,14 +243,43 @@
*/
if (mailto) {
- Debug(DPROC, ("[%ld] closing pipe to mail\n", (long)getpid()));
- /* Note: the pclose will probably see
- * the termination of the grandchild
- * in addition to the mail process, since
- * it (the grandchild) is likely to exit
- * after closing its stdout.
- */
- status = cron_pclose(mail);
+ if (e->flags & MAIL_WHEN_ERR) {
+ int jstatus = -1;
+ if (jobpid <= 0)
+ log_it("CRON", getpid(), "error",
+ "no job pid");
+ else {
+ while (waitpid(jobpid, &jstatus, WNOHANG) == -1)
+ if (errno != EINTR) {
+ log_it("CRON", getpid(),
+ "error", "no job pid");
+ break;
+ }
+ }
+ /* If everything went well, and -n was set, _and_ we
+ * have mail, we won't be mailing... so shoot the
+ * messenger!
+ */
+ if (WIFEXITED(jstatus) && WEXITSTATUS(jstatus) == 0) {
+ Debug(DPROC, ("[%ld] aborting pipe to mail\n",
+ (long)getpid()));
+ status = cron_pabort(mail);
+ mailto = NULL;
+ }
+ }
+
+ if (mailto) {
+ Debug(DPROC, ("[%ld] closing pipe to mail\n",
+ (long)getpid()));
+ /* Note: the pclose will probably see
+ * the termination of the grandchild
+ * in addition to the mail process, since
+ * it (the grandchild) is likely to exit
+ * after closing its stdout.
+ */
+ status = cron_pclose(mail);
+ mail = NULL;
+ }
(void) signal(SIGCHLD, oldchld);
}
@@ -273,15 +304,16 @@
extern char **environ;
static int
exec_user_command(entry *e, char **envp, char *usernm, int *stdin_pipe,
- int *stdout_pipe)
+ int *stdout_pipe, pid_t *jobpid)
{
char *homedir;
- char * volatile *ep = envp;
+ char * volatile *ep;
- switch (vfork()) {
+ switch (*jobpid = vfork()) {
case -1:
return -1;
case 0:
+ ep = envp;
Debug(DPROC, ("[%ld] grandchild process vfork()'ed\n",
(long)getpid()));
@@ -455,6 +487,7 @@
struct sigaction sact;
char **envp = e->envp;
int retval = OK_EXIT;
+ pid_t jobpid = 0;
Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd));
@@ -538,7 +571,8 @@
/* fork again, this time so we can exec the user's command.
*/
- if (exec_user_command(e, envp, usernm, stdin_pipe, stdout_pipe) == -1) {
+ if (exec_user_command(e, envp, usernm, stdin_pipe, stdout_pipe,
+ &jobpid) == -1) {
retval = ERROR_EXIT;
goto child_process_end;
}
@@ -595,7 +629,7 @@
Debug(DPROC, ("[%ld] child reading output from grandchild\n",
(long)getpid()));
- retval = read_data(e, mailto, usernm, envp, stdout_pipe);
+ retval = read_data(e, mailto, usernm, envp, stdout_pipe, jobpid);
if (retval)
goto child_process_end;
diff -r a2dadc5b5cc6 -r 5f676bf8a30d external/bsd/cron/dist/entry.c
--- a/external/bsd/cron/dist/entry.c Thu Jun 14 22:02:57 2018 +0000
+++ b/external/bsd/cron/dist/entry.c Thu Jun 14 22:04:28 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: entry.c,v 1.7 2015/11/20 23:43:52 christos Exp $ */
+/* $NetBSD: entry.c,v 1.8 2018/06/14 22:04:28 christos 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.7 2015/11/20 23:43:52 christos Exp $");
+__RCSID("$NetBSD: entry.c,v 1.8 2018/06/14 22:04:28 christos Exp $");
#endif
#endif
@@ -342,16 +342,34 @@
/* If the first character of the command is '-' it is a cron option.
*/
- while ((ch = get_char(file)) == '-') {
+ ch = get_char(file);
+ while (ch == '-') {
switch (ch = get_char(file)) {
+ case 'n':
+ /* only allow the user to set the option once */
+ if ((e->flags & MAIL_WHEN_ERR) == MAIL_WHEN_ERR) {
+ ecode = e_option;
+ goto eof;
+ }
+ e->flags |= MAIL_WHEN_ERR;
+ break;
case 'q':
+ /* only allow the user to set the option once */
+ if ((e->flags & DONT_LOG) == DONT_LOG) {
+ ecode = e_option;
+ goto eof;
+ }
e->flags |= DONT_LOG;
- Skip_Nonblanks(ch, file);
break;
default:
ecode = e_option;
goto eof;
}
+ ch = get_char(file);
+ if (ch != '\t' && ch != ' ') {
+ ecode = e_option;
+ goto eof;
+ }
Skip_Blanks(ch, file);
if (ch == EOF || ch == '\n') {
ecode = e_cmd;
diff -r a2dadc5b5cc6 -r 5f676bf8a30d external/bsd/cron/dist/funcs.h
--- a/external/bsd/cron/dist/funcs.h Thu Jun 14 22:02:57 2018 +0000
+++ b/external/bsd/cron/dist/funcs.h Thu Jun 14 22:04:28 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: funcs.h,v 1.5 2017/08/17 08:53:00 christos Exp $ */
+/* $NetBSD: funcs.h,v 1.6 2018/06/14 22:04:28 christos Exp $ */
/*
* Id: funcs.h,v 1.9 2004/01/23 18:56:42 vixie Exp
@@ -55,6 +55,7 @@
get_string(char *, int, FILE *, const char *),
load_env(char *, FILE *),
cron_pclose(FILE *),
+ cron_pabort(FILE *),
glue_strings(char *, size_t, const char *, const char *, char),
strcmp_until(const char *, const char *, char),
strdtb(char *);
diff -r a2dadc5b5cc6 -r 5f676bf8a30d external/bsd/cron/dist/popen.c
--- a/external/bsd/cron/dist/popen.c Thu Jun 14 22:02:57 2018 +0000
+++ b/external/bsd/cron/dist/popen.c Thu Jun 14 22:04:28 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: popen.c,v 1.5 2017/06/09 17:36:30 christos Exp $ */
+/* $NetBSD: popen.c,v 1.6 2018/06/14 22:04:28 christos Exp $ */
/*
* Copyright (c) 1988, 1993, 1994
@@ -44,7 +44,7 @@
static sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
static char rcsid[] = "Id: popen.c,v 1.6 2003/02/16 04:40:01 vixie Exp";
#else
-__RCSID("$NetBSD: popen.c,v 1.5 2017/06/09 17:36:30 christos Exp $");
+__RCSID("$NetBSD: popen.c,v 1.6 2018/06/14 22:04:28 christos Exp $");
#endif
#endif /* not lint */
@@ -163,8 +163,8 @@
return (iop);
}
-int
-cron_pclose(FILE *iop) {
+static int
+cron_finalize(FILE *iop, int sig) {
int fdes;
PID_T pid;
WAIT_T status;
@@ -176,7 +176,13 @@
*/
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
return (-1);
- (void)fclose(iop);
+
+ if (sig) {
+ if (kill(pids[fdes], sig) == -1)
+ return -1;
+ } else {
+ (void)fclose(iop);
+ }
(void)sigemptyset(&sset);
(void)sigaddset(&sset, SIGINT);
(void)sigaddset(&sset, SIGQUIT);
@@ -185,11 +191,24 @@
while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
continue;
(void)sigprocmask(SIG_SETMASK, &osset, NULL);
+ if (sig)
+ (void)fclose(iop);
pids[fdes] = 0;
if (pid < 0)
- return (pid);
+ return pid;
if (WIFEXITED(status))
- return (WEXITSTATUS(status));
+ return WEXITSTATUS(status);
else
return WTERMSIG(status);
}
+
+int
+cron_pclose(FILE *iop) {
+ return cron_finalize(iop, 0);
+}
+
+int
+cron_pabort(FILE *iop) {
+ int e = cron_finalize(iop, SIGKILL);
+ return e == SIGKILL ? 0 : e;
+}
diff -r a2dadc5b5cc6 -r 5f676bf8a30d external/bsd/cron/dist/structs.h
--- a/external/bsd/cron/dist/structs.h Thu Jun 14 22:02:57 2018 +0000
+++ b/external/bsd/cron/dist/structs.h Thu Jun 14 22:04:28 2018 +0000
@@ -1,5 +1,3 @@
-/* $NetBSD: structs.h,v 1.2 2010/05/06 18:53:17 christos Exp $ */
-
/*
* Id: structs.h,v 1.7 2004/01/23 18:56:43 vixie Exp
*/
@@ -38,6 +36,7 @@
#define DOW_STAR 0x08
#define WHEN_REBOOT 0x10
#define DONT_LOG 0x20
+#define MAIL_WHEN_ERR 0x40
} entry;
/* the crontab database will be a list of the
Home |
Main Index |
Thread Index |
Old Index