summaryrefslogtreecommitdiff
path: root/src/distcc.h
blob: 4b94aec5659653ce1c63cfdb6e1c66f089c1b92a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/* -*- 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 <sys/types.h>
#include <sys/time.h>     /* 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);



#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