예제 #1
0
/**
 * 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();
}
예제 #2
0
/**
 * 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);
}