示例#1
0
文件: serve.c 项目: aosm/distcc
/**
 * Read a request, run the compiler, and send a response.
 **/
static int dcc_run_job(int in_fd,
                       int out_fd)
{
    char **argv;
    int status;
    char *temp_i, *temp_o, *err_fname, *out_fname;
    int ret, compile_ret;
    char *orig_input, *orig_output;
    pid_t cc_pid;
    enum dcc_protover protover;
    enum dcc_compress compr;
    dcc_indirection indirect;
    
    if ((ret = dcc_make_tmpnam("distcc", ".stderr", &err_fname)))
        goto out_cleanup;
    if ((ret = dcc_make_tmpnam("distcc", ".stdout", &out_fname)))
        goto out_cleanup;
    
    dcc_remove_if_exists(err_fname);
    dcc_remove_if_exists(out_fname);

    /* Capture any messages relating to this compilation to the same file as
     * compiler errors so that they can all be sent back to the client. */
    dcc_add_log_to_file(err_fname);

    /* Ignore SIGPIPE; we consistently check error codes and will see the
     * EPIPE.  Note that it is set back to the default behaviour when spawning
     * a child, to handle cases like the assembler dying while its being fed
     * from the compiler */
    dcc_ignore_sigpipe(1);

    /* Allow output to accumulate into big packets. */
    tcp_cork_sock(out_fd, 1);

    if ((ret = dcc_r_request_header(in_fd, &protover))
        || (ret = dcc_r_argv(in_fd, &argv))
        || (ret = dcc_scan_args(argv, &orig_input, &orig_output, &argv)))
        goto out_cleanup;
    
    if (strcmp(argv[0],"--host-info") == 0) {
        if ((ret = dcc_x_result_header(out_fd, protover)) ||
            (ret = dcc_send_host_info(out_fd)))
            dcc_x_token_int(out_fd, "DOTO", 0);
    } else {
        
        rs_trace("output file %s", orig_output);
        
        if ((ret = dcc_input_tmpnam(orig_input, &temp_i)))
            goto out_cleanup;
        if ((ret = dcc_make_tmpnam("distccd", ".o", &temp_o)))
            goto out_cleanup;
        
        compr = (protover == 2) ? DCC_COMPRESS_LZO1X : DCC_COMPRESS_NONE;
        
        if ((ret = dcc_r_token_file(in_fd, "DOTI", temp_i, compr))
            || (ret = dcc_set_input(argv, temp_i))
            || (ret = dcc_set_output(argv, temp_o)))
            goto out_cleanup;
        
        if ((ret = dcc_check_compiler_masq(argv[0])))
            goto out_cleanup;
        
        indirect.in_fd = in_fd;
        indirect.out_fd = out_fd;
        if ((compile_ret = dcc_spawn_child(argv, &cc_pid,
                                           "/dev/null", out_fname, err_fname, &indirect))
            || (compile_ret = dcc_collect_child("cc", cc_pid, &status))) {
            /* We didn't get around to finding a wait status from the actual compiler */
            status = W_EXITCODE(compile_ret, 0);
        }
        
        if ((ret = dcc_x_result_header(out_fd, protover))
            || (ret = dcc_send_system_info(out_fd))
            || (ret = dcc_send_compiler_version(out_fd, argv[0]))
            || (ret = dcc_x_cc_status(out_fd, status))
            || (ret = dcc_x_file(out_fd, err_fname, "SERR", compr, NULL))
            || (ret = dcc_x_file(out_fd, out_fname, "SOUT", compr, NULL))
            || WIFSIGNALED(status)
            || WEXITSTATUS(status)) {
            /* Something went wrong, so send DOTO 0 */
            dcc_x_token_int(out_fd, "DOTO", 0);
        } else {
            ret = dcc_x_file(out_fd, temp_o, "DOTO", compr, NULL);
        }
        
        dcc_critique_status(status, argv[0], orig_input, dcc_hostdef_local, 0);
    }
    tcp_cork_sock(out_fd, 0);

    rs_log(RS_LOG_INFO|RS_LOG_NONAME, "job complete");

    out_cleanup:
    dcc_remove_log_to_file();
    dcc_cleanup_tempfiles();

    return ret;
}
示例#2
0
/* TODO: This code is highly specific to DCC_VER_3; it assumes
   lzo compression is on, and that the include server has
   actually compressed the files. */
int dcc_x_many_files(int ofd,
                     unsigned int n_files,
                     char **fnames)
{
    int ret = 0;
    char link_points_to[MAXPATHLEN + 1];
    int is_link;
    const char *fname;
    char *original_fname = NULL;
#ifdef XCODE_INTEGRATION
    /* NOTE: If this function is ever used for something besides pump
     * mode support for sending things to be compiled, then it should
     * take another argument to include/exclude this fixup. */
    char *xci_original_fname, *xci_link_points_to;
#endif

    dcc_x_token_int(ofd, "NFIL", n_files);

    for (; *fnames != NULL; ++fnames) {
        fname = *fnames;
        ret = dcc_get_original_fname(fname, &original_fname);
        if (ret) return ret;

        if ((ret = dcc_is_link(fname, &is_link))) {
            return ret;
        }

#ifdef XCODE_INTEGRATION
        xci_original_fname = dcc_xci_mask_developer_dir(original_fname);
        if (xci_original_fname) {
            free(original_fname);
            original_fname = xci_original_fname;
            xci_original_fname = NULL;
        } else {
            ret = EXIT_OUT_OF_MEMORY;
            return ret;
        }
#endif

        if (is_link) {
            if ((ret = dcc_read_link(fname, link_points_to))) {
				return ret;
            }
#ifdef XCODE_INTEGRATION
            xci_link_points_to = dcc_xci_mask_developer_dir(link_points_to);
            if (xci_link_points_to) {
                strlcpy(link_points_to, xci_link_points_to,
                        sizeof(link_points_to));
                free(xci_link_points_to);
                xci_link_points_to = NULL;
            } else {
                ret = EXIT_OUT_OF_MEMORY;
				return ret;
            }
#endif
            if ((ret = dcc_x_token_string(ofd, "NAME", original_fname)) ||
                (ret = dcc_x_token_string(ofd, "LINK", link_points_to))) {
                    return ret;
            }
        } else {
            ret = dcc_x_token_string(ofd, "NAME", original_fname);
            if (ret) return ret;
            /* File should be compressed already.
               If we ever support non-compressed server-side-cpp,
               we should have some checks here and then uncompress
               the file if it is compressed. */
            ret = dcc_x_file(ofd, fname, "FILE", DCC_COMPRESS_NONE,
                             NULL);
            if (ret) return ret;
        }
    }
    return 0;
}