diff -urN a/man/distcc.1 b/man/distcc.1 --- a/man/distcc.1 2008-12-02 14:50:31.000000000 -0700 +++ b/man/distcc.1 2011-12-04 19:02:53.000000000 -0700 @@ -606,7 +606,8 @@ server is disconnected while in use. If a client-side timeout expires, the job will be re-run locally. .PP -The timeouts are not configurable at present. +The client side IO timeout can be configured through the DISTCC_IO_TIMEOUT +environment variable. All other timeouts are not configurable at present. .SH "DIAGNOSTICS" Error messages or warnings from local or remote compilers are passed through to diagnostic output on the client. @@ -729,6 +730,12 @@ this system. Using corks normally helps pack requests into fewer packets and aids performance. This should normally be left enabled. .TP +.B "DISTCC_IO_TIMEOUT" +If set to a positive integer, specifies the client side IO timeout in +seconds (applicable to all IO except for opening connections). Zero +or negative values set an infinite timeout. An empty string selects +the default timeout. +.TP .B DISTCC_SSH Specifies the command used for opening SSH connections. Defaults to "ssh" but may be set to a different connection command such as "lsh" diff -urN a/src/distcc.h b/src/distcc.h --- a/src/distcc.h 2008-12-02 14:50:25.000000000 -0700 +++ b/src/distcc.h 2011-12-04 19:02:53.000000000 -0700 @@ -322,6 +322,7 @@ int dcc_close(int fd); int dcc_want_mmap(void); +int dcc_get_io_timout(void); int dcc_select_for_write(int fd, int timeout); int dcc_select_for_read(int fd, int timeout); diff -urN a/src/io.c b/src/io.c --- a/src/io.c 2008-12-02 14:50:25.000000000 -0700 +++ b/src/io.c 2011-12-04 19:14:20.000000000 -0700 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,36 @@ /** Timeout for all IO other than opening connections. Much longer, because * compiling files can take a long time. **/ -const int dcc_io_timeout = 300; /* seconds */ +const int dcc_default_io_timeout = 300; /* seconds */ + +/** Minimum IO timeout. **/ +const int dcc_min_io_timeout = 10; /* seconds */ + + +/** + * Get the configured IO timeout. Return dcc_default_io_timeout if not + * specified. + **/ +int dcc_get_io_timout(void) +{ + static int io_timeout = 0; + static int initialized = 0; + + if (!initialized) { + const char *e = getenv("DISTCC_IO_TIMEOUT"); + + if (e && *e) { + io_timeout = atoi(e); + if (io_timeout <= 0) + io_timeout = INT_MAX; + else if (io_timeout < dcc_min_io_timeout) + io_timeout = dcc_min_io_timeout; + } else + io_timeout = dcc_default_io_timeout; + initialized = 1; + } + return io_timeout; +} /** @@ -173,12 +203,13 @@ { ssize_t r; int ret; + int io_timeout = dcc_get_io_timout(); while (len > 0) { r = read(fd, buf, len); if (r == -1 && errno == EAGAIN) { - if ((ret = dcc_select_for_read(fd, dcc_io_timeout))) + if ((ret = dcc_select_for_read(fd, io_timeout))) return ret; else continue; @@ -210,12 +241,13 @@ { ssize_t r; int ret; + int io_timeout = dcc_get_io_timout(); while (len > 0) { r = write(fd, buf, len); if (r == -1 && errno == EAGAIN) { - if ((ret = dcc_select_for_write(fd, dcc_io_timeout))) + if ((ret = dcc_select_for_write(fd, io_timeout))) return ret; else continue; diff -urN a/src/pump.c b/src/pump.c --- a/src/pump.c 2008-12-02 14:50:25.000000000 -0700 +++ b/src/pump.c 2011-12-04 19:02:53.000000000 -0700 @@ -101,13 +101,14 @@ char *p; ssize_t r_in, r_out, wanted; int ret; + int io_timeout = dcc_get_io_timout(); while (n > 0) { wanted = (n > sizeof buf) ? (sizeof buf) : n; r_in = read(ifd, buf, (size_t) wanted); if (r_in == -1 && errno == EAGAIN) { - if ((ret = dcc_select_for_read(ifd, dcc_io_timeout)) != 0) + if ((ret = dcc_select_for_read(ifd, io_timeout)) != 0) return ret; else continue; @@ -132,7 +133,7 @@ r_out = write(ofd, p, (size_t) r_in); if (r_out == -1 && errno == EAGAIN) { - if ((ret = dcc_select_for_write(ofd, dcc_io_timeout)) != 0) + if ((ret = dcc_select_for_write(ofd, io_timeout)) != 0) return ret; else continue; diff -urN a/src/sendfile.c b/src/sendfile.c --- a/src/sendfile.c 2008-12-02 14:50:24.000000000 -0700 +++ b/src/sendfile.c 2011-12-04 19:02:53.000000000 -0700 @@ -196,6 +196,7 @@ ssize_t sent; off_t offset = 0; int ret; + int io_timeout = dcc_get_io_timout(); while (size) { /* Handle possibility of partial transmission, e.g. if @@ -206,7 +207,7 @@ if (sent == -1) { if (errno == EAGAIN) { /* Sleep until we're able to write out more data. */ - if ((ret = dcc_select_for_write(ofd, dcc_io_timeout)) != 0) + if ((ret = dcc_select_for_write(ofd, io_timeout)) != 0) return ret; rs_trace("select() returned, continuing to write"); } else if (errno == EINTR) {