#include "hostenv.h" #include "mailer.h" #include "libz.h" #include "libc.h" #include "zmsignal.h" #include #include #ifdef HAVE_SETRLIMIT #include #endif /* HAVE_SETRLIMIT */ #ifdef __linux__ #include #endif #ifdef USE_NOFILE #include #endif /* USE_NOFILE */ /* * Detach a daemon process from whoever/whatever started it. * Mostly lifted from an article in the July/August 1987 ;login:, * by Dave Lennert (hplabs!hpda!davel). Blame bugs on me. - rayan */ extern void cleanenv __((void)); void detach() { /* * If launched by init (process 1), there's no need to detach. * * Note: this test is unreliable due to an unavoidable race * condition if the process is orphaned. */ if (getppid() == 1) goto out; /* Ignore terminal stop signals */ #ifdef SIGTTOU SIGNAL_IGNORE(SIGTTOU); #endif /* SIGTTOU */ #ifdef SIGTTIN SIGNAL_IGNORE(SIGTTIN); #endif /* SIGTTIN */ #ifdef SIGTSTP SIGNAL_IGNORE(SIGTSTP); #endif /* SIGTSTP */ /* * Allow parent shell to continue. * Ensure the process is not a process group leader. */ if (fork() != 0) exit(0); /* parent */ /* child */ /* * Disassociate from controlling terminal and process group. * * Ensure the process can't reacquire a new controlling terminal. * This is done differently on BSD vs. AT&T: * * BSD won't assign a new controlling terminal * because process group is non-zero. * * AT&T won't assign a new controlling terminal * because process is not a process group leader. * (Must not do a subsequent setpgrp()!) */ #ifdef HAVE_SETSID if (fork() != 0) exit(0); /* setsid() can be called only once per proc. */ setsid(); #else /* !HAVE_SETSID */ #ifdef HAVE_GETPGRP #ifdef GETPGRP_VOID /* POSIX.1 style */ /* lose controlling terminal and change process group */ setpgrp(); SIGNAL_IGNORE(SIGHUP); /* immune from pgrp leader death */ if (fork() != 0) /* become non-pgrp-leader */ exit(0); /* first child */ /* second child */ #else /* BSD style */ { int fd = open("/dev/tty", O_RDWR, 0); if (fd >= 0) { ioctl(fd, TIOCNOTTY, 0); /* lose controlling terminal */ close(fd); } } setpgrp(0, getpid()); /* change process group */ #endif /* SETPGRP_VOID */ #endif /* HAVE_GETPGRP */ #endif /* !HAVE_SETSID */ out: #if 0 close(0); { int fd; for (fd = 3; fd < getdtablesize(); ++fd) close(fd); /* close almost all file descriptors */ } #endif /* notdef */ umask(022); /* clear any inherited file mode creation mask */ /* Clean out our environment from personal contamination */ cleanenv(); #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CPU) /* In case this place runs with cpu limits, remove them */ { struct rlimit rl; rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CPU, &rl); } #endif /* HAVE_SETRLIMIT */ return; } /* Debugging stuff.. */ extern int countfds __((void)); int countfds() { int fds = getdtablesize(); int i; int cnt = 0; for (i=0; i= 0) ++cnt; return cnt; }