/** * Become a daemon, discarding the controlling terminal. * * Borrowed from rsync. * * This function returns in the child, but not in the parent. **/ static void dcc_detach(void) { int i; pid_t pid; pid_t sid; dcc_ignore_sighup(); if ((pid = fork()) == -1) { rs_log_error("fork failed: %s", strerror(errno)); exit(EXIT_DISTCC_FAILED); } else if (pid != 0) { /* In the parent. This guy is about to go away so as to * detach from the controlling process, but first save the * child's pid. */ dcc_save_pid(pid); _exit(0); } /* This is called in the detached child */ /* detach from the terminal */ #ifdef HAVE_SETSID if ((sid = setsid()) == -1) { rs_log_error("setsid failed: %s", strerror(errno)); } else { rs_trace("setsid to session %d", (int) sid); } #else /* no HAVE_SETSID */ #ifdef TIOCNOTTY i = open("/dev/tty", O_RDWR); if (i >= 0) { ioctl(i, (int) TIOCNOTTY, (char *)0); close(i); } #endif /* TIOCNOTTY */ #endif /* not HAVE_SETSID */ /* make sure that stdin, stdout an stderr don't stuff things up (library functions, for example) */ for (i=0;i<3;i++) { close(i); open("/dev/null", O_RDWR); } /* If there's a lifetime limit on this server (for testing) then it needs * to apply after detaching as well. */ dcc_set_lifetime(); }
/** * distcc daemon. May run from inetd, or standalone. Accepts * requests from clients to compile files. **/ int main(int argc, char *argv[]) { int ret; const char *tmp; dcc_setup_startup_log(); if (distccd_parse_options(argc, (const char **) argv)) dcc_exit(EXIT_DISTCC_FAILED); /* check this before redirecting the logs, so that it's really obvious */ if (!dcc_should_be_inetd()) if (opt_allowed == NULL) { rs_log_error("--allow option is now mandatory; " "you must specify which clients are allowed to connect"); ret = EXIT_BAD_ARGUMENTS; goto out; } if ((ret = dcc_set_lifetime()) != 0) dcc_exit(ret); /* do this before giving away root */ if (nice(opt_niceness) == -1) { rs_log_warning("nice %d failed: %s", opt_niceness, strerror(errno)); /* continue anyhow */ } if ((ret = dcc_discard_root()) != 0) dcc_exit(ret); /* Discard privileges before opening log so that if it's created, it has * the right ownership. */ dcc_setup_real_log(); /* Do everything from root directory. Allows start directory to be * unmounted, should make accidental writing of local files cause a * failure... */ if ((ret = dcc_get_tmp_top(&tmp))) goto out; if (chdir(tmp) == -1) { rs_log_error("failed to chdir to %s: %s", tmp, strerror(errno)); ret = EXIT_IO_ERROR; goto out; } else { rs_trace("chdir to %s", tmp); } if ((ret = dcc_setup_daemon_path())) goto out; if (dcc_should_be_inetd()) ret = dcc_inetd_server(); else ret = dcc_standalone_server(); out: dcc_exit(ret); }