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

📄 rpc.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 */			/* 15 Every one that is found shall be thrust			 * through; and every one that is joined unto			 * them shall fall by the sword.			 *		-- Isaiah 13 */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <ctype.h>#include <sys/stat.h>#include "distcc.h"#include "trace.h"#include "exitcode.h"#include "rpc.h"#include "snprintf.h"/** * @file * * Very simple RPC-like layer.  Requests and responses are build of * little packets each containing a 4-byte ascii token, an 8-byte hex * value or length, and optionally data corresponding to the length. * * 'x' means transmit, and 'r' means receive.  * * This builds on top of io.c and is called by the various routines * that handle communication. **//** * Transmit token name (4 characters) and value (32-bit int, as 8 hex * characters). **/int dcc_x_token_int(int ofd, const char *token, unsigned param){    char buf[13];    int shift;    char *p;    const char *hex = "0123456789abcdef";    if (strlen(token) != 4) {        rs_log_crit("token \"%s\" seems wrong", token);        return EXIT_PROTOCOL_ERROR;    }    memcpy(buf, token, 4);    /* Quick and dirty int->hex.  The only standard way is to call snprintf     * (?), which is undesirably slow for such a frequently-called     * function. */    for (shift=28, p = &buf[4];         shift >= 0;         shift -= 4, p++) {        *p = hex[(param >> shift) & 0xf];    }    buf[12] = '\0';    rs_trace("send %s", buf);    return dcc_writex(ofd, buf, 12);}/** * Send start of a result: DONE <version> **/int dcc_x_result_header(int ofd,                        enum dcc_protover protover){    return dcc_x_token_int(ofd, "DONE", protover);}int dcc_x_cc_status(int ofd, int status){    return dcc_x_token_int(ofd, "STAT", (unsigned) status);}int dcc_r_token(int ifd, char *buf){    return dcc_readx(ifd, buf, 4);}/** * We got a mismatch on a token, which indicates either a bug in distcc, or * that somebody (inetd?) is interfering with our network stream, or perhaps * some other network problem.  Whatever's happened, a bit more debugging * information would be handy. **/static int dcc_explain_mismatch(const char *buf,                                size_t buflen,                                int ifd){    ssize_t ret;    char extrabuf[200];    char *p;    size_t l;    memcpy(extrabuf, buf, buflen);        /* Read a bit more context, and find the printable prefix. */    ret = read(ifd, extrabuf + buflen, sizeof extrabuf - 1 - buflen);    if (ret == -1) {        ret = 0;                /* pah, use what we've got */    }    l = buflen + ret;    extrabuf[l] = '\0';    for (p = extrabuf; *p; p++)        if (!(isprint(*p) || *p == ' ' || *p == '\t')) {            *p = '\0';            break;        }        rs_log_error("error context: \"%s\"", extrabuf);    return 0;                   /* i just feel really sad... */}/** * Read a token and value.  The receiver always knows what token name * is expected next -- indeed the names are really only there as a * sanity check and to aid debugging. * * @param ifd      fd to read from * @param expected 4-char token that is expected to come in next * @param val      receives the parameter value **/int dcc_r_token_int(int ifd, const char *expected, unsigned *val){    char buf[13], *bum;    int ret;        if (strlen(expected) != 4) {        rs_log_error("expected token \"%s\" seems wrong", expected);        return EXIT_PROTOCOL_ERROR;    }    if ((ret = dcc_readx(ifd, buf, 12))) {        rs_log_error("read failed while waiting for token \"%s\"",                    expected);        return ret;    }        if (memcmp(buf, expected, 4)) {        rs_log_error("protocol derailment: expected token \"%s\"", expected);        dcc_explain_mismatch(buf, 12, ifd);        return EXIT_PROTOCOL_ERROR;    }    buf[12] = '\0';             /* terminate */    *val = strtoul(&buf[4], &bum, 16);    if (bum != &buf[12]) {        rs_log_error("failed to parse parameter of token \"%s\"",                      expected);        dcc_explain_mismatch(buf, 12, ifd);        return EXIT_PROTOCOL_ERROR;    }    rs_trace("got %s", buf);    return 0;}/** * Read a byte string of length @p l into a newly allocated buffer, returned in @p buf. **/int dcc_r_str_alloc(int fd, unsigned l, char **buf){     char *s;#if 0     /* never true  */     if (l < 0) {         rs_log_crit("oops, l < 0");         return EXIT_PROTOCOL_ERROR;     }#endif/*      rs_trace("read %d byte string", l); */     s = *buf = malloc((size_t) l + 1);     if (!s)          rs_log_error("malloc failed");     if (dcc_readx(fd, s, (size_t) l))          return EXIT_OUT_OF_MEMORY;     s[l] = 0;     return 0;}/** * Write a token, and then the string @p buf. * * The length of buf is determined by its nul delimiter, but the \0 is not sent. **/int dcc_x_token_string(int fd,                       const char *token,                       const char *buf){    int ret;    size_t len;    len = strlen(buf);    if ((ret = dcc_x_token_int(fd, token, (unsigned) len)))        return ret;    if ((ret = dcc_writex(fd, buf, len)))        return ret;    return 0;}int dcc_r_token_string(int ifd, const char *expect_token,                       char **p_str){    unsigned a_len;    int ret;            if ((ret = dcc_r_token_int(ifd, expect_token, &a_len)))        return ret;    if ((ret = dcc_r_str_alloc(ifd, a_len, p_str)))        return ret;        return 0;}

⌨️ 快捷键说明

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