#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "distcc.h"
#include "trace.h"
#include "io.h"
#include "exec.h"
#include "rpc.h"
#include "exitcode.h"
#include "util.h"
#include "clinet.h"
#include "bulk.h"
#include "clirpc.h"
#include "cpp_dialect.h"
static int dcc_x_req_header(int fd)
{
return dcc_x_token_int(fd, "DIST", PROTO_VER);
}
static void fix_opt_x(char **argv)
{
int i;
for(i = 0; NULL != argv[i]; i++)
{
if(!strcmp(argv[i], "-x"))
{
char *dialect;
if(dialect = dialect_lookup(argv[i + 1]))
{
argv[i + 1] = dialect;
}
}
}
return;
}
static int dcc_x_argv(int fd, char **argv)
{
int i;
int ret;
int argc;
fix_opt_x(argv);
argc = dcc_argv_len(argv);
if (dcc_x_token_int(fd, "ARGC", argc))
return -1;
for (i = 0; i < argc; i++) {
size_t len;
len = strlen(argv[i]);
if ((ret = dcc_x_token_int(fd, "ARGV", (unsigned) len)))
return ret;
if ((ret = dcc_writex(fd, argv[i], len)))
return ret;
}
return 0;
}
static int dcc_send_job(int net_fd,
char **argv,
pid_t cpp_pid,
int *status,
const char *cpp_fname)
{
long stime_usec, utime_usec;
int ret;
if ((ret = dcc_x_req_header(net_fd))
|| (ret = dcc_x_argv(net_fd, argv)))
return ret;
if (cpp_pid) {
if ((ret = dcc_collect_child(cpp_pid, status, &utime_usec, &stime_usec))
|| (ret = dcc_report_rusage("cpp", utime_usec, stime_usec)))
return ret;
if (dcc_critique_status(*status, "cpp", dcc_gethostname()))
return 0;
}
if (access(cpp_fname, R_OK) != 0) {
rs_log_error("can't read cpp output \"%s\": %s",
cpp_fname, strerror(errno));
return EXIT_IO_ERROR;
}
if ((ret = dcc_x_file_timed(net_fd, cpp_fname, "DOTI", NULL)))
return ret;
rs_trace("client finished sending request to server");
return 0;
}
int dcc_send_job_corked(int net_fd,
char **argv,
pid_t cpp_pid,
int *status,
const char *cpp_fname)
{
int ret;
tcp_cork_sock(net_fd, 1);
ret = dcc_send_job(net_fd, argv, cpp_pid, status, cpp_fname);
tcp_cork_sock(net_fd, 0);
return ret;
}
int dcc_retrieve_results(int net_fd, int *status, const char *output_fname)
{
int len;
int ret;
int o_len;
if ((ret = dcc_r_result_header(net_fd))
|| (ret = dcc_r_cc_status(net_fd, status))
|| (ret = dcc_r_token_int(net_fd, "SERR", &len))
|| (ret = dcc_r_file_body(STDERR_FILENO, net_fd, len))
|| (ret = dcc_r_token_int(net_fd, "SOUT", &len))
|| (ret = dcc_r_file_body(STDOUT_FILENO, net_fd, len))
|| (ret = dcc_r_token_int(net_fd, "DOTO", &o_len)))
return ret;
if (o_len)
return dcc_r_file_timed(net_fd, output_fname, o_len);
else {
rs_log_notice("skipping retrieval of 0 byte object file %s",
output_fname);
return 0;
}
}