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