]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Make Apache use the new ap_create_process call. This is the first of a
authorRyan Bloom <rbb@apache.org>
Mon, 11 Oct 1999 14:20:48 +0000 (14:20 +0000)
committerRyan Bloom <rbb@apache.org>
Mon, 11 Oct 1999 14:20:48 +0000 (14:20 +0000)
group of patches.  This patch, allows the core server to compile and
serve pages.  There is a set of patches which will follow to allow the
standard modules to use ap_create_process.  This change should make
writing code which spawns new processes easy to read and understand.
Submitted by: Paul Reder

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83959 13f79535-47bb-0310-9956-ffa450edef68

include/http_log.h
os/beos/os.c
os/unix/os-inline.c
os/win32/util_win32.c
server/log.c

index 61abeab01677c71b13af40c55e4c004d068835e7..575013f41e3d70affc5614256f21285e149b22ae 100644 (file)
@@ -138,7 +138,7 @@ typedef struct piped_log {
     ap_context_t *p;
 #ifndef NO_RELIABLE_PIPED_LOGS
     char *program;
-    int pid;
+    ap_proc_t *pid;
     ap_file_t fds[2];
 #else
     ap_file_t *write_f;
index 72281c296eb83772c4b6ec9e93797768539273ee..030a21bbcf1f3076bb59446ce21667c22f4e3dc9 100644 (file)
@@ -11,22 +11,6 @@ int ap_os_is_path_absolute(const char *file)
   return file[0] == '/';
 }
 
-int ap_spawnvp(const char *file, char *const argv[])
-{
-    int pid;
-
-    if ((pid = fork()) == -1) {
-        return pid;
-    } else if (pid == 0) {
-        if (execvp(file, argv) == -1)
-            return -1;
-        else
-            return -1;  /* If we get, we have a real error, but this keeps
-                           us from getting a warning during compile time. */
-    } else 
-        return pid;
-}
-
 
 /* some linkers complain unless there's at least one function in each
  * .o file... and extra prototype is for gcc -Wmissing-prototypes
index 8018bc7b92f0a5b477d21b664671e133a413ac9c..dad7a8444d5b7727fcd6260c2a1d30f760ff05fe 100644 (file)
@@ -30,20 +30,3 @@ INLINE int ap_os_is_path_absolute(const char *file)
 {
   return file[0] == '/';
 }
-
-INLINE int ap_spawnvp(const char *file, char *const argv[])
-{
-    int pid;
-
-    if ((pid = fork()) == -1) {
-        return pid;
-    } else if (pid == 0) {
-        if (execvp(file, argv) == -1)
-            return -1;
-        else
-            return -1;  /* If we get, we have a real error, but this keeps
-                           us from getting a warning during compile time. */
-    } else 
-        return pid;
-}
-    
index 1ec908f9a4fcd13a81efeabf7c4c5c2bd661a16f..3eed6ec448065b3ef5105a5049bd6f2180aa1ec0 100644 (file)
@@ -332,146 +332,6 @@ API_EXPORT(int) os_stat(const char *szPath, struct stat *pStat)
     return stat(szPath, pStat);
 }
 
-/* Fix two really crap problems with Win32 spawn[lv]e*:
- *
- *  1. Win32 doesn't deal with spaces in argv.
- *  2. Win95 doesn't like / in cmdname.
- */
-
-#undef _spawnv
-API_EXPORT(int) os_spawnv(int mode, const char *cmdname,
-                         const char *const *argv)
-{
-    int n;
-    char **aszArgs;
-    const char *szArg;
-    char *szCmd;
-    char *s;
-    
-    szCmd = _alloca(strlen(cmdname)+1);
-    strcpy(szCmd, cmdname);
-    for (s = szCmd; *s; ++s) {
-        if (*s == '/') {
-            *s = '\\';
-       }
-    }
-
-    for (n = 0; argv[n]; ++n)
-        ;
-
-    aszArgs = _alloca((n + 1) * sizeof(const char *));
-
-    for (n = 0; szArg = argv[n]; ++n) {
-        if (strchr(szArg, ' ')) {
-            int l = strlen(szArg);
-
-            aszArgs[n] = _alloca(l + 2 + 1);
-            aszArgs[n][0] = '"';
-            strcpy(&aszArgs[n][1], szArg);
-            aszArgs[n][l + 1] = '"';
-            aszArgs[n][l + 2] = '\0';
-        }
-        else {
-            aszArgs[n] = (char *)szArg;
-        }
-    }
-
-    aszArgs[n] = NULL;
-
-    return _spawnv(mode, szCmd, aszArgs);
-}
-
-#undef _spawnve
-API_EXPORT(int) os_spawnve(int mode, const char *cmdname,
-                          const char *const *argv, const char *const *envp)
-{
-    int n;
-    char **aszArgs;
-    const char *szArg;
-    char *szCmd;
-    char *s;
-    
-    szCmd = _alloca(strlen(cmdname)+1);
-    strcpy(szCmd, cmdname);
-    for (s = szCmd; *s; ++s) {
-        if (*s == '/') {
-            *s = '\\';
-       }
-    }
-    
-    for (n = 0; argv[n]; ++n)
-        ;
-
-    aszArgs = _alloca((n + 1)*sizeof(const char *));
-
-    for (n = 0; szArg = argv[n]; ++n){
-        if (strchr(szArg, ' ')) {
-            int l = strlen(szArg);
-
-            aszArgs[n] = _alloca(l + 2 + 1);
-            aszArgs[n][0] = '"';
-            strcpy(&aszArgs[n][1], szArg);
-            aszArgs[n][l + 1] = '"';
-            aszArgs[n][l + 2] = '\0';
-        }
-        else {
-            aszArgs[n] = (char *)szArg;
-        }
-    }
-
-    aszArgs[n] = NULL;
-
-    return _spawnve(mode, szCmd, aszArgs, envp);
-}
-
-API_EXPORT(int) os_spawnle(int mode, const char *cmdname, ...)
-{
-    int n;
-    va_list vlist;
-    char **aszArgs;
-    const char *szArg;
-    const char *const *aszEnv;
-    char *szCmd;
-    char *s;
-    
-    szCmd = _alloca(strlen(cmdname)+1);
-    strcpy(szCmd, cmdname);
-    for (s = szCmd; *s; ++s) {
-        if (*s == '/') {
-            *s = '\\';
-       }
-    }
-
-    va_start(vlist, cmdname);
-    for (n = 0; va_arg(vlist, const char *); ++n)
-        ;
-    va_end(vlist);
-
-    aszArgs = _alloca((n + 1) * sizeof(const char *));
-
-    va_start(vlist, cmdname);
-    for (n = 0; szArg = va_arg(vlist, const char *); ++n) {
-        if (strchr(szArg, ' ')) {
-            int l = strlen(szArg);
-
-            aszArgs[n] = _alloca(l + 2 + 1);
-            aszArgs[n][0] = '"';
-            strcpy(&aszArgs[n][1], szArg);
-            aszArgs[n][l + 1] = '"';
-            aszArgs[n][l + 2] = '\0';
-        }
-        else {
-            aszArgs[n] = (char *)szArg;
-        }
-    }
-
-    aszArgs[n] = NULL;
-
-    aszEnv = va_arg(vlist, const char *const *);
-    va_end(vlist);
-    
-    return _spawnve(mode, szCmd, aszArgs, aszEnv);
-}
 
 #undef strftime
 
index 31d7f3fff04baf077926fbb01651824e7ebbc987..28a2268d7fd42bc692a6f4688492c983f0738209 100644 (file)
@@ -156,60 +156,84 @@ static const TRANS priorities[] = {
     {NULL,     -1},
 };
 
-static int error_log_child(void *cmd, ap_child_info_t *pinfo)
+static int log_child(ap_context_t *p, const char *progname,
+                     ap_file_t **fpout, ap_file_t **fpin,
+                     ap_file_t **fperr)
 {
     /* Child process code for 'ErrorLog "|..."';
      * may want a common framework for this, since I expect it will
      * be common for other foo-loggers to want this sort of thing...
      */
-    int child_pid = 0;
+    int rc = -1;
+    ap_procattr_t *procattr;
+    ap_proc_t *procnew;
+    ap_os_proc_t fred;
 
+    ap_block_alarms();
     ap_cleanup_for_exec();
+
 #ifdef SIGHUP
     /* No concept of a child process on Win32 */
     signal(SIGHUP, SIG_IGN);
 #endif /* ndef SIGHUP */
-#if defined(WIN32)
-    child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-    return(child_pid);
-#elif defined(OS2)
-    /* For OS/2 we need to use a '/' and spawn the child rather than exec as
-     * we haven't forked */
-    child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-    return(child_pid);
-#else    
-    execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif    
-    exit(1);
-    /* NOT REACHED */
-    return(child_pid);
+
+    if ((ap_createprocattr_init(&procattr, p)          != APR_SUCCESS) ||
+        (ap_setprocattr_io(procattr,
+                           fpin  ? 1 : 0,
+                           fpout ? 1 : 0,
+                           fperr ? 1 : 0)              != APR_SUCCESS) ||
+        (ap_setprocattr_dir(procattr, progname)        != APR_SUCCESS)) {
+        /* Something bad happened, give up and go away. */
+        rc = -1;
+    }
+    else {
+        rc = ap_create_process(&procnew, p, progname, NULL, NULL, procattr);
+    
+        if (rc == APR_SUCCESS) {
+#ifndef WIN32
+            /* pjr - this is a cheap hack for now to get the basics working in
+             *       stages. ap_note_subprocess and free_proc need to be redone
+             *       to make use of ap_proc_t instead of pid.
+             */
+            ap_get_os_proc(procnew, &fred);
+            ap_note_subprocess(p, fred, kill_after_timeout);
+#endif
+            if (fpin) {
+                ap_get_childin(fpin, procnew);
+            }
+
+            if (fpout) {
+                ap_get_childout(fpout, procnew);
+            }
+
+            if (fperr) {
+                ap_get_childerr(fperr, procnew);
+            }
+        }
+    }
+
+    ap_unblock_alarms();
+
+    return(rc);
 }
 
 static void open_error_log(server_rec *s, ap_context_t *p)
 {
     const char *fname;
+    int rc;
 
     if (*s->error_fname == '|') {
-       FILE *dummy;
-        int dummyno;
-#ifdef TPF
-        TPF_FORK_CHILD cld;
-        cld.filename = s->error_fname+1;
-        cld.subprocess_env = NULL;
-        cld.prog_type = FORK_NAME;
-        if (!ap_spawn_child(p, NULL, &cld,
-                            kill_after_timeout, &dummy, NULL, NULL)) {
-#else
-       if (!ap_spawn_child(p, error_log_child, (void *)(s->error_fname+1),
-                           kill_after_timeout, &dummy, NULL, NULL)) {
-#endif /* TPF */
+       ap_file_t *dummy;
+
+        /* This starts a new process... */
+        rc = log_child (p, s->error_fname+1, NULL, &dummy, NULL);
+        if (rc != APR_SUCCESS) {
            perror("ap_spawn_child");
            fprintf(stderr, "Couldn't fork child for ErrorLog process\n");
            exit(1);
        }
 
-        dummyno = fileno(dummy);
-       ap_put_os_file(&s->error_log, &dummyno, p);
+        s->error_log = dummy;
     }
 
 #ifdef HAVE_SYSLOG
@@ -276,8 +300,7 @@ void ap_open_logs(server_rec *s_main, ap_context_t *p)
     }
 
     for (virt = s_main->next; virt; virt = virt->next) {
-       if (virt->error_fname)
-       {
+       if (virt->error_fname) {
            for (q=s_main; q != virt; q = q->next)
                if (q->error_fname != NULL &&
                    strcmp(q->error_fname, virt->error_fname) == 0)
@@ -506,7 +529,7 @@ API_EXPORT(void) ap_log_rerror(const char *file, int line, int level,
 
 void ap_log_pid(ap_context_t *p, const char *fname)
 {
-    FILE *pid_file;
+    ap_file_t *pid_file;
     struct stat finfo;
     static pid_t saved_pid = -1;
     pid_t mypid;
@@ -531,14 +554,14 @@ void ap_log_pid(ap_context_t *p, const char *fname)
                               );
     }
 
-    if(!(pid_file = fopen(fname, "w"))) {
+    if(ap_open(&pid_file, p, fname, APR_WRITE | APR_BUFFERED, APR_OS_DEFAULT) != APR_SUCCESS) {
        perror("fopen");
         fprintf(stderr, "%s: could not log pid to file %s\n",
                ap_server_argv0, fname);
         exit(1);
     }
-    fprintf(pid_file, "%ld\n", (long)mypid);
-    fclose(pid_file);
+    ap_fprintf(pid_file, "%ld\n", (long)mypid);
+    ap_close(pid_file);
     saved_pid = mypid;
 }
 
@@ -592,35 +615,42 @@ static void piped_log_maintenance(int reason, void *data, ap_wait_t status);
 
 static int piped_log_spawn(piped_log *pl)
 {
-    int pid;
-
-    pid = fork();
-    if (pid == 0) {
-       /* XXX: this needs porting to OS2 and WIN32 */
-       /* XXX: need to check what open fds the logger is actually passed,
-        * XXX: and CGIs for that matter ... cleanup_for_exec *should*
-        * XXX: close all the relevant stuff, but hey, it could be broken. */
-       RAISE_SIGSTOP(PIPED_LOG_SPAWN);
-       /* we're now in the child */
-       close(STDIN_FILENO);
-       dup2(pl->fds[0], STDIN_FILENO);
-
-       ap_cleanup_for_exec();
-       signal(SIGCHLD, SIG_DFL);       /* for HPUX */
-       signal(SIGHUP, SIG_IGN);
-       execl(SHELL_PATH, SHELL_PATH, "-c", pl->program, NULL);
+    int rc;
+    ap_procattr_t *procattr;
+    ap_os_proc_t pid;
+    ap_proc_t *procnew;
+
+    /* pjr - calls to block and unblock alarms weren't here before, was this */
+    /*       an oversight or intentional?                                    */
+/*  ap_block_alarms();   */
+
+    ap_cleanup_for_exec();
+#ifdef SIGHUP
+    signal(SIGHUP, SIG_IGN);
+#endif
+    if ((ap_createprocattr_init(pl->p, &procattr)         != APR_SUCCESS) ||
+        (ap_setprocattr_dir(procattr, pl->program)        != APR_SUCCESS) ||
+        (ap_set_childin(procattr, pl->fds[0], pl->fds[1]) != APR_SUCCESS)) {
+        /* Something bad happened, give up and go away. */
        fprintf(stderr,
            "piped_log_spawn: unable to exec %s -c '%s': %s\n",
            SHELL_PATH, pl->program, strerror (errno));
-       exit(1);
+        rc = -1;
     }
-    if (pid == -1) {
-       fprintf(stderr,
-           "piped_log_spawn: unable to fork(): %s\n", strerror (errno));
-       return -1;
+    else {
+        rc = ap_create_process(pl->p, pl->program, NULL, NULL, procattr, &procnew);
+    
+        if (rc == APR_SUCCESS) {            /* pjr - This no longer happens inside the child, */
+            RAISE_SIGSTOP(PIPED_LOG_SPAWN); /*   I am assuming that if ap_create_process was  */
+                                            /*   successful that the child is running.        */
+            pl->pid = procnew;
+            ap_get_os_proc(&procnew, &pid);
+            ap_register_other_child(pid, piped_log_maintenance, pl, pl->fds[1]);
+        }
     }
-    pl->pid = pid;
-    ap_register_other_child(pid, piped_log_maintenance, pl, pl->fds[1]);
+    
+/*  ap_unblock_alarms(); */
+    
     return 0;
 }
 
@@ -632,13 +662,13 @@ static void piped_log_maintenance(int reason, void *data, ap_wait_t status)
     switch (reason) {
     case OC_REASON_DEATH:
     case OC_REASON_LOST:
-       pl->pid = -1;
+       pl->pid = NULL;
        ap_unregister_other_child(pl);
        if (pl->program == NULL) {
            /* during a restart */
            break;
        }
-       if (piped_log_spawn(pl) == -1) {
+       if (piped_log_spawn(pl) != APR_SUCCESS) {
            /* what can we do?  This could be the error log we're having
             * problems opening up... */
            fprintf(stderr,
@@ -648,15 +678,15 @@ static void piped_log_maintenance(int reason, void *data, ap_wait_t status)
        break;
     
     case OC_REASON_UNWRITABLE:
-       if (pl->pid != -1) {
-           kill(pl->pid, SIGTERM);
+       if (pl->pid != NULL) {
+           ap_kill(pl->pid, SIGTERM);
        }
        break;
     
     case OC_REASON_RESTART:
        pl->program = NULL;
-       if (pl->pid != -1) {
-           kill(pl->pid, SIGTERM);
+       if (pl->pid != NULL) {
+           ap_kill(pl->pid, SIGTERM);
        }
        break;
 
@@ -670,8 +700,8 @@ static void piped_log_cleanup(void *data)
 {
     piped_log *pl = data;
 
-    if (pl->pid != -1) {
-       kill(pl->pid, SIGTERM);
+    if (pl->pid != NULL) {
+       ap_kill(pl->pid, SIGTERM);
     }
     ap_unregister_other_child(pl);
     ap_close(pl->fds[0]);
@@ -695,7 +725,7 @@ API_EXPORT(piped_log *) ap_open_piped_log(ap_context_t *p, const char *program)
     pl = ap_palloc(p, sizeof (*pl));
     pl->p = p;
     pl->program = ap_pstrdup(p, program);
-    pl->pid = -1;
+    pl->pid = NULL;
     if (ap_create_pipe(p, &pl->fds[0], &pl->fds[1]) != APR_SUCCESS) {
        int save_errno = errno;
        errno = save_errno;
@@ -720,60 +750,22 @@ API_EXPORT(void) ap_close_piped_log(piped_log *pl)
 }
 
 #else
-static int piped_log_child(void *cmd, ap_child_info_t *pinfo)
-{
-    /* Child process code for 'TransferLog "|..."';
-     * may want a common framework for this, since I expect it will
-     * be common for other foo-loggers to want this sort of thing...
-     */
-    int child_pid = 1;
-
-    ap_cleanup_for_exec();
-#ifdef SIGHUP
-    signal(SIGHUP, SIG_IGN);
-#endif
-#if defined(WIN32)
-    child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-    return(child_pid);
-#elif defined(OS2)
-    /* For OS/2 we need to use a '/' and spawn the child rather than exec as
-     * we haven't forked */
-    child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-    return(child_pid);
-#else
-    execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
-    perror("exec");
-    fprintf(stderr, "Exec of shell for logging failed!!!\n");
-    return(child_pid);
-}
-
-
 API_EXPORT(piped_log *) ap_open_piped_log(ap_context_t *p, const char *program)
 {
     piped_log *pl;
-    FILE *dummy;
-    int dummyno;
-#ifdef TPF
-    TPF_FORK_CHILD cld;
-    cld.filename = (char *)program;
-    cld.subprocess_env = NULL;
-    cld.prog_type = FORK_NAME;
+    ap_file_t *dummy;
+    int rc;
 
-    if (!ap_spawn_child (p, NULL, &cld,
-      kill_after_timeout, &dummy, NULL, NULL)){
-#else
-    if (!ap_spawn_child(p, piped_log_child, (void *)program,
-                       kill_after_timeout, &dummy, NULL, NULL)) {
-#endif /* TPF */
+    rc = log_child(p, program, NULL, &dummy, NULL);
+    if (rc != APR_SUCCESS) {
        perror("ap_spawn_child");
        fprintf(stderr, "Couldn't fork child for piped log process\n");
        exit (1);
     }
+
     pl = ap_palloc(p, sizeof (*pl));
     pl->p = p;
-    dummyno = fileno(dummy);
-    ap_put_os_file(&pl->write_f, &dummyno, p);
+    pl->write_f = dummy;
 
     return pl;
 }