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 split out the child runner.



details:   https://anonhg.NetBSD.org/src/rev/e2a71852c9ae
branches:  trunk
changeset: 829491:e2a71852c9ae
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Feb 04 03:37:59 2018 +0000

description:
split out the child runner.

diffstat:

 external/bsd/cron/dist/do_command.c |  210 +++++++++++++++++++----------------
 1 files changed, 111 insertions(+), 99 deletions(-)

diffs (265 lines):

diff -r f6ff6b20641d -r e2a71852c9ae external/bsd/cron/dist/do_command.c
--- a/external/bsd/cron/dist/do_command.c       Sun Feb 04 03:19:51 2018 +0000
+++ b/external/bsd/cron/dist/do_command.c       Sun Feb 04 03:37:59 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: do_command.c,v 1.11 2017/09/28 02:32:51 christos Exp $ */
+/*     $NetBSD: do_command.c,v 1.12 2018/02/04 03:37:59 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.11 2017/09/28 02:32:51 christos Exp $");
+__RCSID("$NetBSD: do_command.c,v 1.12 2018/02/04 03:37:59 christos Exp $");
 #endif
 #endif
 
@@ -272,101 +272,15 @@
 
 extern char **environ;
 static int
-child_process(entry *e) {
-       int stdin_pipe[2], stdout_pipe[2];
-       char * volatile input_data;
-       char *homedir, *usernm, * volatile mailto;
-       struct sigaction sact;
-       char **envp = e->envp;
-       int retval = OK_EXIT;
-
-       Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd));
-
-       setproctitle("running job");
-
-       /* discover some useful and important environment settings
-        */
-       usernm = e->pwd->pw_name;
-       mailto = env_get("MAILTO", envp);
-
-       memset(&sact, 0, sizeof(sact));
-       sigemptyset(&sact.sa_mask);
-       sact.sa_flags = 0;
-#ifdef SA_RESTART
-       sact.sa_flags |= SA_RESTART;
-#endif
-       sact.sa_handler = sigchld_handler;
-       (void) sigaction(SIGCHLD, &sact, NULL);
+exec_user_command(entry *e, char **envp, char *usernm, int *stdin_pipe,
+    int *stdout_pipe)
+{
+       char *homedir;
+       char * volatile *ep = envp;
 
-       /* create some pipes to talk to our future child
-        */
-       if (pipe(stdin_pipe) == -1)     /* child's stdin */
-               log_it("CRON", getpid(), "error", "create child stdin pipe");
-       if (pipe(stdout_pipe) == -1)    /* child's stdout */
-               log_it("CRON", getpid(), "error", "create child stdout pipe");
-       
-       /* since we are a forked process, we can diddle the command string
-        * we were passed -- nobody else is going to use it again, right?
-        *
-        * if a % is present in the command, previous characters are the
-        * command, and subsequent characters are the additional input to
-        * the command.  An escaped % will have the escape character stripped
-        * from it.  Subsequent %'s will be transformed into newlines,
-        * but that happens later.
-        */
-       /*local*/{
-               int escaped = FALSE;
-               int ch;
-               char *p;
-
-               /* translation:
-                *      \% -> %
-                *      %  -> end of command, following is command input.
-                *      \x -> \x        for all x != %
-                */
-               input_data = p = e->cmd;
-               while ((ch = *input_data++) != '\0') {
-                       if (escaped) {
-                               if (ch != '%')
-                                       *p++ = '\\';
-                       } else {
-                               if (ch == '%') {
-                                       break;
-                               }
-                       }
-
-                       if (!(escaped = (ch == '\\'))) {
-                               *p++ = (char)ch;
-                       }
-               }
-               if (ch == '\0') {
-                       /* move pointer back, so that code below
-                        * won't think we encountered % sequence */
-                       input_data--;
-               }
-               if (escaped)
-                       *p++ = '\\';
-
-               *p = '\0';
-       }
-
-#ifdef USE_PAM
-       if (!cron_pam_start(usernm))
-               return ERROR_EXIT;
-
-       if (!(envp = cron_pam_getenvlist(envp))) {
-               retval = ERROR_EXIT;
-               goto child_process_end;
-       }
-#endif
-
-       /* fork again, this time so we can exec the user's command.
-        */
        switch (vfork()) {
        case -1:
-               retval = ERROR_EXIT;
-               goto child_process_end;
-               /*NOTREACHED*/
+               return -1;
        case 0:
                Debug(DPROC, ("[%ld] grandchild process vfork()'ed\n",
                              (long)getpid()));
@@ -456,7 +370,7 @@
                         */
                        if (env_get("PATH", envp) == NULL && environ != NULL) {
                                if ((p = getenv("PATH")) != NULL)
-                                       envp = env_set(envp, p);
+                                       ep = env_set(envp, p);
                        }
                }
 #else
@@ -489,7 +403,7 @@
                }
                /* we aren't root after this... */
 #endif /* LOGIN_CAP */
-               homedir = env_get("HOME", envp);
+               homedir = env_get("HOME", __UNVOLATILE(ep));
                if (chdir(homedir) != 0) {
                        syslog(LOG_ERR, "chdir(%s) $HOME failed for %s: %m",
                            homedir, e->pwd->pw_name);
@@ -511,7 +425,7 @@
                 * Exec the command.
                 */
                {
-                       char    *shell = env_get("SHELL", envp);
+                       char    *shell = env_get("SHELL", __UNVOLATILE(ep));
 
 # if DEBUGGING
                        if (DebugFlags & DTEST) {
@@ -526,11 +440,109 @@
                        warn("execl: couldn't exec `%s'", shell);
                        _exit(ERROR_EXIT);
                }
-               break;
+               return 0;
        default:
                /* parent process */
-               break;
+               return 0;
        }
+}
+
+static int
+child_process(entry *e) {
+       int stdin_pipe[2], stdout_pipe[2];
+       char * volatile input_data;
+       char *usernm, * volatile mailto;
+       struct sigaction sact;
+       char **envp = e->envp;
+       int retval = OK_EXIT;
+
+       Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd));
+
+       setproctitle("running job");
+
+       /* discover some useful and important environment settings
+        */
+       usernm = e->pwd->pw_name;
+       mailto = env_get("MAILTO", envp);
+
+       memset(&sact, 0, sizeof(sact));
+       sigemptyset(&sact.sa_mask);
+       sact.sa_flags = 0;
+#ifdef SA_RESTART
+       sact.sa_flags |= SA_RESTART;
+#endif
+       sact.sa_handler = sigchld_handler;
+       (void) sigaction(SIGCHLD, &sact, NULL);
+
+       /* create some pipes to talk to our future child
+        */
+       if (pipe(stdin_pipe) == -1)     /* child's stdin */
+               log_it("CRON", getpid(), "error", "create child stdin pipe");
+       if (pipe(stdout_pipe) == -1)    /* child's stdout */
+               log_it("CRON", getpid(), "error", "create child stdout pipe");
+       
+       /* since we are a forked process, we can diddle the command string
+        * we were passed -- nobody else is going to use it again, right?
+        *
+        * if a % is present in the command, previous characters are the
+        * command, and subsequent characters are the additional input to
+        * the command.  An escaped % will have the escape character stripped
+        * from it.  Subsequent %'s will be transformed into newlines,
+        * but that happens later.
+        */
+       /*local*/{
+               int escaped = FALSE;
+               int ch;
+               char *p;
+
+               /* translation:
+                *      \% -> %
+                *      %  -> end of command, following is command input.
+                *      \x -> \x        for all x != %
+                */
+               input_data = p = e->cmd;
+               while ((ch = *input_data++) != '\0') {
+                       if (escaped) {
+                               if (ch != '%')
+                                       *p++ = '\\';
+                       } else {
+                               if (ch == '%') {
+                                       break;
+                               }
+                       }
+
+                       if (!(escaped = (ch == '\\'))) {
+                               *p++ = (char)ch;
+                       }
+               }
+               if (ch == '\0') {
+                       /* move pointer back, so that code below
+                        * won't think we encountered % sequence */
+                       input_data--;
+               }
+               if (escaped)
+                       *p++ = '\\';
+
+               *p = '\0';
+       }
+
+#ifdef USE_PAM
+       if (!cron_pam_start(usernm))
+               return ERROR_EXIT;
+
+       if (!(envp = cron_pam_getenvlist(envp))) {
+               retval = ERROR_EXIT;
+               goto child_process_end;
+       }
+#endif
+
+       /* fork again, this time so we can exec the user's command.
+        */
+       if (exec_user_command(e, envp, usernm, stdin_pipe, stdout_pipe) == -1) {
+               retval = ERROR_EXIT;
+               goto child_process_end;
+       }
+
 
        /* middle process, child of original cron, parent of process running
         * the user's command.



Home | Main Index | Thread Index | Old Index