procsup.c revision 251875
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