⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daemon.c

📁 distcc编译器的源代码.好像是readhat公司开发的.
💻 C
字号:
/* -*- c-file-style: "java"; indent-tabs-mode: nil; fill-column: 78; -*- *  * distcc -- A simple distributed compiler system * * Copyright (C) 2002, 2003 by Martin Pool <mbp@samba.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */                /* "Just like distributed.net, only useful!" *//** * @file * * distcc volunteer server.  Accepts and serves requests to compile * files. * * May be run from inetd (default if stdin is a socket), or as a * daemon by itself.   * * distcc has an adequate but perhaps not optimal system for deciding * where to send files.  The general principle is that the server * should say how many jobs it is willing to accept, rather than the * client having to know.  This is probably good in two ways: it * allows for people in the future to impose limits on how much work * their contributed machine will do, and secondly it seems better to * put this information in one place rather than on every client. **/#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <syslog.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/param.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#ifdef HAVE_ARPA_NAMESER_H#  include <arpa/nameser.h>#endif#include <arpa/inet.h>#include "exitcode.h"#include "distcc.h"#include "trace.h"#include "util.h"#include "dopt.h"#include "srvnet.h"#include "daemon.h"#include "types.h"/* for trace.c */char const *rs_program_name = "distccd";static int dcc_inetd_server(void);static void dcc_setup_real_log(void);/** * Errors during startup (e.g. bad options) need to be reported somewhere, * although we have not yet parsed the options to work out where the user * wants them. * * In inetd mode, we can't write to stderr because that will corrupt the * stream, so if it looks like stderr is a socket we go to syslog instead. **/static int dcc_setup_startup_log(void){    rs_trace_set_level(RS_LOG_INFO);    if (!is_a_socket(STDERR_FILENO)) {        rs_add_logger(rs_logger_file, RS_LOG_DEBUG, 0, STDERR_FILENO);    } else {        openlog("distccd", LOG_PID, LOG_DAEMON);        rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0);    }    return 0;}static int dcc_should_be_inetd(void){    /* Work out if we ought to serve stdin or be a standalone daemon */    if (opt_inetd_mode)        return 1;    else if (opt_daemon_mode)        return 0;    else if (is_a_socket(STDIN_FILENO)) {        rs_log_info("stdin is socket; assuming --inetd mode");        return 1;    } else if (isatty(STDIN_FILENO)) {        rs_log_info("stdin is a tty; assuming --daemon mode");        return 0;    } else {        rs_log_info("stdin is neither a tty nor a socket; assuming --daemon mode");        return 0;    }}static int dcc_setup_daemon_path(void){    int ret;    const char *path;    if ((path = getenv("DISTCCD_PATH")) != NULL) {        if ((ret = dcc_set_path(path)))            return ret;        return 0;    } else {        path = getenv("PATH");        rs_log_info("daemon's PATH is %s", path ? path : "(NULL)");        return 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);}/** * If a --lifetime options was specified, set up a timer that will kill the * daemon when it expires. **/int dcc_set_lifetime(void){    if (opt_lifetime) {        alarm(opt_lifetime);/*         rs_trace("set alarm for %+d seconds", opt_lifetime); */    }    return 0;}/** * Set log to the final destination after options have been read. **/static void dcc_setup_real_log(void){    int fd;    /* Even in inetd mode, we might want to log to stderr, because that will     * work OK for ssh connections. */        if (opt_log_stderr) {        rs_remove_all_loggers();        rs_add_logger(rs_logger_file, RS_LOG_DEBUG, 0, STDERR_FILENO);        return;    }        if (arg_log_file) {        /* Don't remove loggers yet, in case this fails and needs to go to the         * default. */        if ((fd = open(arg_log_file, O_CREAT|O_APPEND|O_WRONLY, 0666)) == -1) {            rs_log_error("failed to open %s: %s", arg_log_file,                         strerror(errno));            /* continue and use syslog */        } else {            rs_remove_all_loggers();            rs_add_logger(rs_logger_file, RS_LOG_DEBUG, NULL, fd);            return;        }    }        rs_remove_all_loggers();    openlog("distccd", LOG_PID, LOG_DAEMON);    rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0);}int dcc_log_daemon_started(const char *role){    rs_log_info("%s started (%s %s, built %s %s)",                role,                PACKAGE_VERSION,                GNU_HOST,                 __DATE__, __TIME__);    return 0;}/** * Serve a single file on stdin, and then exit. **/static int dcc_inetd_server(void){    int ret, close_ret;    struct dcc_sockaddr_storage ss;    struct sockaddr *psa = (struct sockaddr *) &ss;    socklen_t len = sizeof ss;        dcc_log_daemon_started("inetd server");    if ((getpeername(STDIN_FILENO, psa, &len) == -1)) {        /* This can fail with ENOTSOCK if e.g. sshd has started us on a pipe,         * not on a socket.  I think it's harmless. */        rs_log_notice("failed to get peer name: %s", strerror(errno));        psa = NULL;             /* make sure we don't refer to uninitialized mem */        len = 0;    }    ret = dcc_service_job(STDIN_FILENO, STDOUT_FILENO, psa, len);    close_ret = dcc_close(STDIN_FILENO);    if (ret)        return ret;    else        return close_ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -