1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251875Speter * contributor license agreements.  See the NOTICE file distributed with
3251875Speter * this work for additional information regarding copyright ownership.
4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251875Speter * (the "License"); you may not use this file except in compliance with
6251875Speter * the License.  You may obtain a copy of the License at
7251875Speter *
8251875Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251875Speter *
10251875Speter * Unless required by applicable law or agreed to in writing, software
11251875Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251875Speter * See the License for the specific language governing permissions and
14251875Speter * limitations under the License.
15251875Speter */
16251875Speter
17251875Speter#include "apr_arch_threadproc.h"
18251875Speter
19251875SpeterAPR_DECLARE(apr_status_t) apr_proc_detach(int daemonize)
20251875Speter{
21251875Speter    if (chdir("/") == -1) {
22251875Speter        return errno;
23251875Speter    }
24251875Speter
25251875Speter#if !defined(MPE) && !defined(OS2) && !defined(TPF) && !defined(BEOS)
26251875Speter    /* Don't detach for MPE because child processes can't survive the death of
27251875Speter     * the parent. */
28251875Speter    if (daemonize) {
29251875Speter        int x;
30251875Speter
31251875Speter        if ((x = fork()) > 0) {
32251875Speter            exit(0);
33251875Speter        }
34251875Speter        else if (x == -1) {
35251875Speter            perror("fork");
36251875Speter            fprintf(stderr, "unable to fork new process\n");
37251875Speter            exit(1);  /* we can't do anything here, so just exit. */
38251875Speter        }
39251875Speter        /* RAISE_SIGSTOP(DETACH); */
40251875Speter    }
41251875Speter#endif
42251875Speter
43251875Speter#ifdef HAVE_SETSID
44251875Speter    /* A setsid() failure is not fatal if we didn't just fork().
45251875Speter     * The calling process may be the process group leader, in
46251875Speter     * which case setsid() will fail with EPERM.
47251875Speter     */
48251875Speter    if (setsid() == -1 && daemonize) {
49251875Speter        return errno;
50251875Speter    }
51251875Speter#elif defined(NEXT) || defined(NEWSOS)
52251875Speter    if (setpgrp(0, getpid()) == -1) {
53251875Speter        return errno;
54251875Speter    }
55251875Speter#elif defined(OS2) || defined(TPF) || defined(MPE)
56251875Speter    /* do nothing */
57251875Speter#else
58251875Speter    if (setpgid(0, 0) == -1) {
59251875Speter        return errno;
60251875Speter    }
61251875Speter#endif
62251875Speter
63251875Speter    /* close out the standard file descriptors */
64251875Speter    if (freopen("/dev/null", "r", stdin) == NULL) {
65251875Speter        return errno;
66251875Speter        /* continue anyhow -- note we can't close out descriptor 0 because we
67251875Speter         * have nothing to replace it with, and if we didn't have a descriptor
68251875Speter         * 0 the next file would be created with that value ... leading to
69251875Speter         * havoc.
70251875Speter         */
71251875Speter    }
72251875Speter    if (freopen("/dev/null", "w", stdout) == NULL) {
73251875Speter        return errno;
74251875Speter    }
75251875Speter     /* We are going to reopen this again in a little while to the error
76251875Speter      * log file, but better to do it twice and suffer a small performance
77251875Speter      * hit for consistancy than not reopen it here.
78251875Speter      */
79251875Speter    if (freopen("/dev/null", "w", stderr) == NULL) {
80251875Speter        return errno;
81251875Speter    }
82251875Speter    return APR_SUCCESS;
83251875Speter}
84251875Speter
85251875Speter#if (!HAVE_WAITPID)
86251875Speter/* From ikluft@amdahl.com
87251875Speter * this is not ideal but it works for SVR3 variants
88251875Speter * Modified by dwd@bell-labs.com to call wait3 instead of wait because
89251875Speter *   apache started to use the WNOHANG option.
90251875Speter */
91251875Speterint waitpid(pid_t pid, int *statusp, int options)
92251875Speter{
93251875Speter    int tmp_pid;
94251875Speter    if (kill(pid, 0) == -1) {
95251875Speter        errno = ECHILD;
96251875Speter        return -1;
97251875Speter    }
98251875Speter    while (((tmp_pid = wait3(statusp, options, 0)) != pid) &&
99251875Speter                (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
100251875Speter        ;
101251875Speter    return tmp_pid;
102251875Speter}
103251875Speter#endif
104251875Speter
105