00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <signal.h>
00025 #include <sys/stat.h>
00026 #include <sys/param.h>
00027 #if defined(__sun) || defined(__sgi)
00028 # include <fcntl.h>
00029 #endif
00030
00031 #ifdef SIGTSTP
00032 #include <sys/file.h>
00033 #include <sys/ioctl.h>
00034 #include <sys/wait.h>
00035 #endif
00036
00037 #ifndef NOFILE
00038 # define NOFILE 0
00039 #endif
00040
00041 #if defined(__hpux)
00042 #define USE_SIGCHLD
00043 #endif
00044
00045 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
00046 #define USE_SIGCHLD
00047 #define SIGCLD SIGCHLD
00048 #endif
00049
00050 #if defined(linux) || defined(__hpux) || defined(__sun) || defined(__sgi) || \
00051 defined(_AIX) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
00052 defined(__APPLE__) || defined(__MACH__) || \
00053 (defined(__CYGWIN__) && defined(__GNUC__))
00054 #define USE_SETSID
00055 #endif
00056
00057
00058 #include "rpdp.h"
00059
00060 extern int gDebug;
00061
00062 namespace ROOT {
00063
00064 extern ErrorHandler_t gErrSys;
00065
00066 #if defined(USE_SIGCHLD)
00067
00068 static void SigChild(int)
00069 {
00070 int pid;
00071 #if defined(__hpux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
00072 defined(__APPLE__)
00073 int status;
00074 #else
00075 union wait status;
00076 #endif
00077
00078 while ((pid = wait3(&status, WNOHANG, 0)) > 0)
00079 ;
00080 }
00081 #endif
00082
00083
00084 void DaemonStart(int ignsigcld, int fdkeep, EService service)
00085 {
00086
00087
00088
00089
00090
00091
00092
00093
00094 int fd;
00095
00096 #if !(defined(__CYGWIN__) && defined(__GNUC__))
00097 if (getppid() == 1) {
00098 if (service == kROOTD) printf ("ROOTD_PID=%ld\n", (long) getpid());
00099 goto out;
00100 }
00101 #endif
00102
00103
00104
00105 #ifdef SIGTTOU
00106 signal(SIGTTOU, SIG_IGN);
00107 #endif
00108 #ifdef SIGTTIN
00109 signal(SIGTTIN, SIG_IGN);
00110 #endif
00111 #ifdef SIGTSTP
00112 signal(SIGTSTP, SIG_IGN);
00113 #endif
00114
00115
00116
00117
00118
00119 int childpid;
00120 if ((childpid = fork()) < 0) {
00121 if (service == kROOTD) fprintf(stderr, "DaemonStart: can't fork first child\n");
00122 Error(gErrSys,kErrFatal, "DaemonStart: can't fork first child");
00123 } else if (childpid > 0) {
00124 #ifdef SIGTSTP
00125 if (service == kROOTD) printf("ROOTD_PID=%d\n", childpid);
00126 #endif
00127 exit(0);
00128 } else {
00129 if (gDebug > 2)
00130 ErrorInfo("DaemonStart: this is the child thread ... socket is: %d",fdkeep);
00131 }
00132
00133
00134
00135
00136
00137
00138 #ifdef SIGTSTP
00139
00140 #ifdef USE_SETSID
00141 if (setsid() == -1) {
00142 #else
00143 if (setpgrp(0, getpid()) == -1) {
00144 #endif
00145 if (service == kROOTD)
00146 fprintf(stderr, "DaemonStart: can't change process group\n");
00147 Error(gErrSys,kErrFatal, "DaemonStart: can't change process group");
00148 }
00149
00150 if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
00151 #if !defined(__hpux) && !defined(__sun) && \
00152 !(defined(__CYGWIN__) && defined(__GNUC__))
00153 ioctl(fd, TIOCNOTTY, 0);
00154 #endif
00155 close(fd);
00156 }
00157
00158 #else
00159
00160 if (setpgrp() == -1) {
00161 if (service == kROOTD)
00162 fprintf(stderr,"DaemonStart: can't change process group\n");
00163 Error(gErrSys,kErrFatal, "DaemonStart: can't change process group");
00164 }
00165
00166 signal(SIGHUP, SIG_IGN);
00167
00168 if ((childpid = fork()) < 0) {
00169 if (service == kROOTD)
00170 fprintf(stderr, "DaemonStart: can't fork second child\n");
00171 Error(gErrSys,kErrFatal, "DaemonStart: can't fork second child");
00172 } else if (childpid > 0) {
00173 if (service == kROOTD) printf("ROOTD_PID=%d (2nd fork)\n", childpid);
00174 exit(0);
00175 }
00176
00177 #endif
00178 out:
00179
00180 for (fd = 0; fd < NOFILE; fd++) {
00181 if ((fd != fdkeep) || (service == kPROOFD)) close(fd);
00182 }
00183
00184 ResetErrno();
00185
00186
00187
00188
00189 if (chdir("/") == -1)
00190 fprintf(stderr, "DaemonStart: cannot chdir to /\n");
00191
00192
00193
00194 umask(0);
00195
00196
00197
00198
00199
00200
00201
00202
00203 if (ignsigcld) {
00204 #ifdef USE_SIGCHLD
00205 signal(SIGCLD, SigChild);
00206 #else
00207 #if defined(__alpha) && !defined(linux)
00208 struct sigaction oldsigact, sigact;
00209 sigact.sa_handler = SIG_IGN;
00210 sigemptyset(&sigact.sa_mask);
00211 sigact.sa_flags = SA_NOCLDWAIT;
00212 sigaction(SIGCHLD, &sigact, &oldsigact);
00213 #elif defined(__sun)
00214 sigignore(SIGCHLD);
00215 #else
00216 signal(SIGCLD, SIG_IGN);
00217 #endif
00218 #endif
00219 }
00220 }
00221
00222 }
00223