/* -*- c-file-style: "java"; indent-tabs-mode: nil; tab-width: 4; fill-column: 78 -*- * * distcc -- A simple distributed compiler system * * Copyright (C) 2002, 2003, 2004 by Martin Pool * Copyright 2007 Google Inc. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ /* distcc.h -- common internal-use header file */ #include #include /* for struct timeval */ #ifdef NORETURN /* nothing */ #elif defined(__GNUC__) # define NORETURN __attribute__((noreturn)) #elif defined(__LCLINT__) # define NORETURN /*@noreturn@*/ x #else /* !__GNUC__ && !__LCLINT__ */ # define NORETURN #endif /* !__GNUC__ && !__LCLINT__ */ #ifdef UNUSED /* nothing */ #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else /* !__GNUC__ && !__LCLINT__ */ # define UNUSED(x) x #endif /* !__GNUC__ && !__LCLINT__ */ /* According to the gcc info page, __attribute__((unused)) means "this * variable is *possibly* unused" (emphasis added). So we can use it for * POSSIBLY_UNUSED. This macro is used when a variable is used in one #ifdef * case but not another, say. */ #ifdef POSSIBLY_UNUSED /* nothing */ #elif defined(__GNUC__) # define POSSIBLY_UNUSED(x) x __attribute__((unused)) #elif defined(__LCLINT__) # define POSSIBLY_UNUSED(x) /*@unused@*/ x #else /* !__GNUC__ && !__LCLINT__ */ # define POSSIBLY_UNUSED(x) x #endif /* !__GNUC__ && !__LCLINT__ */ #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) /* This works on Gentoo's (patched?) gcc 3.3.3 but not 3.2.3, and not Debian's * 3.3.4. It should be standard on 3.4. */ # define WARN_UNUSED __attribute__((warn_unused_result)) #else # define WARN_UNUSED #endif #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif struct dcc_hostdef; #include "state.h" enum dcc_compress { /* weird values to catch errors */ DCC_COMPRESS_NONE = 69, DCC_COMPRESS_LZO1X }; enum dcc_cpp_where { /* weird values to catch errors */ DCC_CPP_ON_CLIENT = 42, DCC_CPP_ON_SERVER }; enum dcc_protover { DCC_VER_1 = 1, /**< vanilla */ DCC_VER_2 = 2, /**< LZO sprinkles */ DCC_VER_3 = 3 /**< server-side cpp */ }; int str_endswith(const char *tail, const char *tiger); /* A macro so that we get the right __FUNCTION__ in the trace message. * * We condition on rs_trace_enabled so that we don't do the to-string * conversion unless the user will actually see the result, because it's a * little expensive. */ #define dcc_trace_argv(_message, _argv) \ if (rs_trace_enabled()) { \ char *_astr; \ _astr = dcc_argv_tostr(_argv); \ rs_trace("%s: %s", _message, _astr); \ free(_astr); \ } else {} /* help.c */ int dcc_trace_version(void); int dcc_show_version(const char *prog); /* hosts.c */ int dcc_parse_hosts_env(struct dcc_hostdef **ret_list, int *ret_nhosts); int dcc_parse_hosts(const char *where, const char *source_name, struct dcc_hostdef **ret_list, int *ret_nhosts, struct dcc_hostdef **ret_prev); /* ncpu.c */ int dcc_ncpus(int *); /* ssh.c */ int dcc_ssh_connect(char *ssh_cmd, char *user, char *machine, char *path, int *f_in, int *f_out, pid_t *ssh_pid); /* safeguard.c */ int dcc_increment_safeguard(void); int dcc_recursion_safeguard(void); /* clirpc.c */ int dcc_x_req_header(int fd, enum dcc_protover protover); int dcc_x_argv(int fd, const char *argc_token, const char *argv_token, char **argv); int dcc_x_cwd(int fd); int dcc_is_link(const char *fname, int *is_link); int dcc_read_link(const char* fname, char *points_to); /* srvrpc.c */ int dcc_r_cwd(int ifd, char **cwd); /* remote.c */ int dcc_send_job_corked(int net_fd, char **argv, pid_t cpp_pid, int *status, const char *, const char *cpp_fname, struct dcc_hostdef *); int dcc_retrieve_results(int net_fd, int *status, const char *output_fname, const char *deps_fname, const char *server_stderr_fname, struct dcc_hostdef *); /* climasq.c */ int dcc_support_masquerade(char *argv[], char *progname, int *); /* backoff.c */ int dcc_enjoyed_host(const struct dcc_hostdef *host); int dcc_disliked_host(const struct dcc_hostdef *host); int dcc_remove_disliked(struct dcc_hostdef **hostlist); int dcc_backoff_is_enabled(void); #define DISTCC_DEFAULT_PORT 3632 #define DISTCC_DEFAULT_STATS_ENABLED 0 #define DISTCC_DEFAULT_STATS_PORT 3633 #ifndef WAIT_ANY # define WAIT_ANY (-1) #endif /* If --enable-rfc2553 was given, then we will try to enable compile-time IPv6 * support. This means we must have a sockaddr_storage large enough to hold * IPv6 addresses. If not, we'll just use a plain sockaddr, which is more * likely to compile correctly. */ #ifdef ENABLE_RFC2553 # ifndef HAVE_SOCKADDR_STORAGE # error You can't use RFC2553 because you don't have a sockaddr_storage type # endif /* HAVE_SOCKADDR_STORAGE */ # define dcc_sockaddr_storage sockaddr_storage #else /* !ENABLE_RFC2553 */ # define dcc_sockaddr_storage sockaddr #endif /* !ENABLE_RFC2553 */ #ifndef O_BINARY # define O_BINARY 0 #endif void dcc_set_trace_from_env(void); /* compress.c */ int dcc_r_bulk_lzo1x(int outf_fd, int in_fd, unsigned in_len); int dcc_compress_file_lzo1x(int in_fd, size_t in_len, char **out_buf, size_t *out_len); int dcc_compress_lzo1x_alloc(const char *in_buf, size_t in_len, char **out_buf_ret, size_t *out_len_ret); /* bulk.c */ void dcc_calc_rate(off_t size_out, struct timeval *before, struct timeval *after, double *secs, double *rate); /* arg.c */ int dcc_set_action_opt(char **, const char *); int dcc_set_output(char **, char *); int dcc_set_input(char **, char *); int dcc_scan_args(char *argv[], /*@out@*/ /*@relnull@*/ char **orig_o, char **orig_i, char ***ret_newargv); int dcc_expand_preprocessor_options(char ***argv_ptr); /* argutil.c */ unsigned int dcc_argv_len(char **a); int dcc_argv_search(char **a, const char *); int dcc_argv_startswith(char **a, const char *); int dcc_copy_argv(char **argv, char ***out_argv, int extra_args); int dcc_argv_append(char **argv, char *toadd); char *dcc_argv_tostr(char **a); void dcc_free_argv(char **argv); /* tempfile.c */ 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(const char *path); int dcc_get_subdir(const char *name, char **path_ret) WARN_UNUSED; int dcc_get_lock_dir(char **path_ret) WARN_UNUSED; int dcc_get_state_dir(char **path_ret) WARN_UNUSED; int dcc_get_top_dir(char **path_ret) WARN_UNUSED; int dcc_get_tmp_top(const char **p_ret) WARN_UNUSED; int dcc_mk_tmp_ancestor_dirs(const char* file); /* cleanup.c */ void dcc_cleanup_tempfiles(void); void dcc_cleanup_tempfiles_from_signal_handler(void); int dcc_add_cleanup(const char *filename) WARN_UNUSED; /* strip.c */ 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); /* filename.c */ int dcc_is_source(const char *sfile); int dcc_is_preprocessed(const char *sfile); int dcc_is_object(const char *filename); int dcc_source_needs_local(const char *); char * dcc_find_extension(char *sfile); const char * dcc_find_extension_const(const char *sfile); int dcc_output_from_source(const char *sfile, const char *out_extn, char **ofile); const char * dcc_preproc_exten(const char *e); const char * dcc_find_basename(const char *sfile); void dcc_truncate_to_dirname(char *file); /* io.c */ int dcc_writex(int fd, const void *buf, size_t len); int dcc_r_token(int ifd, char *token); int dcc_readx(int fd, void *buf, size_t len); int dcc_pump_sendfile(int ofd, int ifd, size_t n); int dcc_r_str_alloc(int fd, unsigned len, char **buf); int tcp_cork_sock(int fd, int corked); int dcc_close(int fd); int dcc_get_io_timeout(void); int dcc_want_mmap(void); int dcc_select_for_write(int fd, int timeout); int dcc_select_for_read(int fd, int timeout); /* loadfile.c */ int dcc_load_file_string(const char *filename, char **retbuf); extern const int dcc_connect_timeout; /* pump.c */ int dcc_r_bulk(int ofd, int ifd, unsigned f_size, enum dcc_compress compression); int dcc_pump_readwrite(int ofd, int ifd, size_t n); /* mapfile.c */ int dcc_map_input_file(int in_fd, off_t in_size, char **buf_ret); /* XXX: Kind of kludgy, we should do dynamic allocation. But this will do for * now. */ #ifndef MAXPATHLEN #define MAXPATHLEN 4096 #endif #ifndef WCOREDUMP # define WCOREDUMP(status) 0 #endif