Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include_server/test_data/distcc/src/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
int dcc_compile_remote(char **argv,
char *input_fname,
char *cpp_fname,
char *header_list_fname,
char **file_names,
char *output_fname,
char *deps_fname,
char *server_stderr_fname,
pid_t cpp_pid,
pid_t header_list_pid,
int local_cpu_lock_fd,
struct dcc_hostdef *host,
int *status);
Expand Down
5 changes: 3 additions & 2 deletions include_server/test_data/distcc/src/distcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ int dcc_get_tempdir(const char **);
int dcc_make_tmpnam(const char *, const char *suffix, char **);
int dcc_get_new_tmpdir(char **tmpdir);
int dcc_mk_tmpdir(const char *path);
int dcc_mkdir_recursively(const char *path);
int dcc_mkdir(const char *path);

int dcc_get_lock_dir(char **path_ret) WARN_UNUSED;
Expand All @@ -269,8 +270,8 @@ int dcc_strip_local_args(char **from, char ***out_argv);
int dcc_strip_dasho(char **from, char ***out_argv);

/* cpp.c */
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
pid_t *cpp_pid);
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname, pid_t *cpp_pid);
int dcc_depends_header_list(char **argv, char *input_fname, char **header_list_fname, pid_t *header_list_pid);

/* filename.c */
int dcc_is_source(const char *sfile);
Expand Down
1 change: 1 addition & 0 deletions include_server/test_data/distcc/src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ int dcc_getenv_bool(const char *name, int def_value);
int set_cloexec_flag (int desc, int value);
int dcc_ignore_sigpipe(int val);
int dcc_remove_if_exists(const char *fname);
int dcc_rename(const char *old_filename, const char *new_filename);
int dcc_trim_path(const char *compiler_name);
int dcc_set_path(const char *newpath);
char *dcc_abspath(const char *path, int path_len);
Expand Down
8 changes: 7 additions & 1 deletion src/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,13 +653,15 @@ dcc_build_somewhere(char *argv[],
int *status)
{
char *input_fname = NULL, *output_fname, *cpp_fname, *deps_fname = NULL;
char *header_list_fname = NULL;
char **files;
char **server_side_argv = NULL;
int server_side_argv_deep_copied = 0;
char *server_stderr_fname = NULL;
int needs_dotd = 0;
int sets_dotd_target = 0;
pid_t cpp_pid = 0;
pid_t header_list_pid = 0;
int cpu_lock_fd = -1, local_cpu_lock_fd = -1;
int ret;
int remote_ret = 0;
Expand Down Expand Up @@ -781,6 +783,9 @@ dcc_build_somewhere(char *argv[],
if ((ret = dcc_cpp_maybe(argv, input_fname, &cpp_fname, &cpp_pid) != 0))
goto fallback;

if ((ret = dcc_depends_header_list(argv, input_fname, &header_list_fname, &header_list_pid)))
goto fallback;

if ((ret = dcc_strip_local_args(argv, &server_side_argv)))
goto fallback;

Expand All @@ -804,11 +809,12 @@ dcc_build_somewhere(char *argv[],
if ((ret = dcc_compile_remote(server_side_argv,
input_fname,
cpp_fname,
header_list_fname,
files,
output_fname,
needs_dotd ? deps_fname : NULL,
server_stderr_fname,
cpp_pid, local_cpu_lock_fd,
cpp_pid, header_list_pid, local_cpu_lock_fd,
host, status)) != 0) {
/* Returns zero if we successfully ran the compiler, even if
* the compiler itself bombed out. */
Expand Down
2 changes: 2 additions & 0 deletions src/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
int dcc_compile_remote(char **argv,
char *input_fname,
char *cpp_fname,
char *header_list_fname,
char **file_names,
char *output_fname,
char *deps_fname,
char *server_stderr_fname,
pid_t cpp_pid,
pid_t header_list_pid,
int local_cpu_lock_fd,
struct dcc_hostdef *host,
int *status);
Expand Down
27 changes: 25 additions & 2 deletions src/cpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@
* allows us to overlap opening the TCP socket, which probably doesn't
* use many cycles, with running the preprocessor.
**/
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
pid_t *cpp_pid)
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname, pid_t *cpp_pid)
{
char **cpp_argv;
int ret;
Expand Down Expand Up @@ -99,3 +98,27 @@ int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
return dcc_spawn_child(cpp_argv, cpp_pid,
"/dev/null", *cpp_fname, NULL);
}

int dcc_depends_header_list(char **argv, char *input_fname, char **header_list_fname, pid_t *header_list_pid)
{
char **header_list_argv;
int ret;

*header_list_pid = 0;

if (dcc_is_preprocessed(input_fname)) {
rs_log_error("failed to get depends header list, file already preprocessed");
return EXIT_DISTCC_FAILED;
}

if ((ret = dcc_make_tmpnam("distcc", ".list", header_list_fname)))
return ret;

if ((ret = dcc_strip_dasho(argv, &header_list_argv))
|| (ret = dcc_set_action_opt(header_list_argv, "-MM")))
return ret;

/* FIXME: header_list_argv is leaked */
return dcc_spawn_child(header_list_argv, header_list_pid,
"/dev/null", *header_list_fname, NULL);
}
5 changes: 3 additions & 2 deletions src/distcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ int dcc_get_tempdir(const char **);
int dcc_make_tmpnam(const char *, const char *suffix, char **);
int dcc_get_new_tmpdir(char **tmpdir);
int dcc_mk_tmpdir(const char *path);
int dcc_mkdir_recursively(const char *path);
int dcc_mkdir(const char *path);
int dcc_get_subdir(const char *name, char **path_ret) WARN_UNUSED;

Expand All @@ -292,8 +293,8 @@ int dcc_strip_local_args(char **from, char ***out_argv);
int dcc_strip_dasho(char **from, char ***out_argv);

/* cpp.c */
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname,
pid_t *cpp_pid);
int dcc_cpp_maybe(char **argv, char *input_fname, char **cpp_fname, pid_t *cpp_pid);
int dcc_depends_header_list(char **argv, char *input_fname, char **header_list_fname, pid_t *header_list_pid);

/* filename.c */
int dcc_is_source(const char *sfile);
Expand Down
4 changes: 2 additions & 2 deletions src/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ int dcc_make_lock_filename(const char *lockname,
* @retval 0 if we got the lock
* @retval -1 with errno set if the file is already locked.
**/
static int sys_lock(int fd, int block)
int dcc_lock(int fd, int block)
{
#if defined(F_SETLK)
struct flock lockparam;
Expand Down Expand Up @@ -291,7 +291,7 @@ int dcc_lock_host(const char *lockname,
return ret;
}

if (sys_lock(*lock_fd, block) == 0) {
if (dcc_lock(*lock_fd, block) == 0) {
rs_trace("got %s lock on %s slot %d as fd%d", lockname,
host->hostdef_string, slot, *lock_fd);
free(fname);
Expand Down
2 changes: 2 additions & 0 deletions src/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ int dcc_lock_host(const char *lockname,
const struct dcc_hostdef *host, int slot, int block,
int *lock_fd);

int dcc_lock(int fd, int block);

int dcc_unlock(int lock_fd);

int dcc_make_lock_filename(const char *lockname,
Expand Down
115 changes: 113 additions & 2 deletions src/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/time.h>
Expand Down Expand Up @@ -149,7 +150,98 @@ dcc_send_header(int net_fd,
return 0;
}

static int
dcc_get_precompiled_header_path(const char *header_list_fname, char precompiled_header_path[PATH_MAX]) {
int ret;
int fd;
off_t file_size;

precompiled_header_path[0] = 0;
if (header_list_fname == NULL) {
return 0;
}

if ((ret = dcc_open_read(header_list_fname, &fd, &file_size))) {
return ret;
}

char *data = (char *)malloc(file_size + 1);
if (data == NULL) {
dcc_close(fd);
return EXIT_OUT_OF_MEMORY;
}

if ((ret = dcc_readx(fd, data, file_size))) {
free(data);
dcc_close(fd);
return ret;
}
data[file_size] = 0;

const char precompiled_preprocess[] = "#pragma GCC pch_preprocess \"";
const char *begin = strstr(data, precompiled_preprocess);
if (begin) {
begin += strlen(precompiled_preprocess);
const char *end = strchr(begin, '"');
if (!end || end - begin >= PATH_MAX) {
free(data);
dcc_close(fd);
return EXIT_DISTCC_FAILED;
}
strncpy(precompiled_header_path, begin, end - begin);
precompiled_header_path[end - begin] = 0;
}

free(data);
dcc_close(fd);
return 0;
}

/**
* Sends precompiled header path and sends precompiled header itself if need.
*
* PCHP: precompiled header path on disk; it should be present on distccd agent
* PCHR:
* 0 - if precompiled header is present on distccd agent or we do not need it at all
* 1 - if precompiled header is absent on distccd agent and we should send it
* PCHF: precompiled header file itself
**/
static int
try_exchange_precompiled_header(int to_net_fd, int from_net_fd, char *input_fname, int *status,
const char *header_list_fname, pid_t header_list_pid) {
int ret;
if ((ret = dcc_wait_for_cpp(header_list_pid, status, input_fname))) {
return ret;
}

char precompiled_header_path[PATH_MAX] = {0};
if ((ret = dcc_get_precompiled_header_path(header_list_fname, precompiled_header_path))) {
return ret;
}

/* expect that precompiled header is placed on tmp dir */
/* TODO: may be such limitation too strict? */
if (precompiled_header_path[0] && strncmp(precompiled_header_path, "/tmp/", 5)) {
rs_log_warning("expect precompiled header in /tmp dir, got %s", precompiled_header_path);
precompiled_header_path[0] = 0;
}

if ((ret = dcc_x_token_string(to_net_fd, "PCHP", precompiled_header_path))) {
return ret;
}

unsigned precompiled_header_required;
if ((ret = dcc_r_token_int(from_net_fd, "PCHR", &precompiled_header_required))) {
return ret;
}

if (precompiled_header_required) {
if ((ret = dcc_x_file(to_net_fd, precompiled_header_path, "PCHF", DCC_COMPRESS_LZO1X, NULL))) {
return ret;
}
}
return 0;
}
/**
* Pass a compilation across the network.
*
Expand All @@ -164,17 +256,23 @@ dcc_send_header(int net_fd,
*
* @param argv Compiler command to run.
*
* @param cpp_fname Filename of preprocessed source. May not be complete yet,
* @param cpp_fname Filename of preprocessed source. May not be complete yet,
* depending on @p cpp_pid.
*
* @param header_list_fname Filename of list with used headers.
* May not be complete yet, depending on @p header_list_pid.
*
* @param files If we are doing preprocessing on the server, the names of
* all the files needed; otherwise, NULL.
*
* @param output_fname File that the object code should be delivered to.
*
* @param cpp_pid If nonzero, the pid of the preprocessor. Must be
* @param cpp_pid If nonzero, the pid of the preprocessor. Must be
* allowed to complete before we send the input file.
*
* @param header_list_pid If nonzero, the pid of the preprocessor for getting used headers.
* Must be allowed to complete before we send the input file.
*
* @param local_cpu_lock_fd If != -1, file descriptor for the lock file.
* Should be != -1 iff (host->cpp_where != DCC_CPP_ON_SERVER).
* If != -1, the lock must be held on entry to this function,
Expand All @@ -195,11 +293,13 @@ dcc_send_header(int net_fd,
int dcc_compile_remote(char **argv,
char *input_fname,
char *cpp_fname,
char *header_list_fname,
char **files,
char *output_fname,
char *deps_fname,
char *server_stderr_fname,
pid_t cpp_pid,
pid_t header_list_pid,
int local_cpu_lock_fd,
struct dcc_hostdef *host,
int *status)
Expand Down Expand Up @@ -251,6 +351,12 @@ int dcc_compile_remote(char **argv,
goto out;
}

/* Here will sent just an empty string */
if ((ret = try_exchange_precompiled_header(to_net_fd, from_net_fd, input_fname, status,
header_list_fname, header_list_pid))) {
goto out;
}

n_files = dcc_argv_len(files);
if ((ret = dcc_x_many_files(to_net_fd, n_files, files))) {
goto out;
Expand All @@ -263,6 +369,11 @@ int dcc_compile_remote(char **argv,
if ((ret = dcc_send_header(to_net_fd, argv, host)))
goto out;

if ((ret = try_exchange_precompiled_header(to_net_fd, from_net_fd, input_fname, status,
header_list_fname, header_list_pid))) {
goto out;
}

if ((ret = dcc_wait_for_cpp(cpp_pid, status, input_fname)))
goto out;

Expand Down
Loading