diff -ru distcc-2.18.3.orig/man/distcc.1 distcc-2.18.3/man/distcc.1
--- distcc-2.18.3.orig/man/distcc.1	2007-08-03 09:58:50.000000000 +0200
+++ distcc-2.18.3/man/distcc.1	2007-08-03 10:31:49.000000000 +0200
@@ -354,7 +354,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.
@@ -440,6 +478,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 -ru distcc-2.18.3.orig/src/distcc.h distcc-2.18.3/src/distcc.h
--- distcc-2.18.3.orig/src/distcc.h	2007-08-03 09:58:50.000000000 +0200
+++ distcc-2.18.3/src/distcc.h	2007-08-03 10:24:55.000000000 +0200
@@ -271,6 +271,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 -ru distcc-2.18.3.orig/src/io.c distcc-2.18.3/src/io.c
--- distcc-2.18.3.orig/src/io.c	2007-08-03 09:58:50.000000000 +0200
+++ distcc-2.18.3/src/io.c	2007-08-03 10:32:11.000000000 +0200
@@ -63,7 +63,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;
+}
 
 
 /**
@@ -151,12 +180,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;
@@ -188,12 +218,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 -ru distcc-2.18.3.orig/src/pump.c distcc-2.18.3/src/pump.c
--- distcc-2.18.3.orig/src/pump.c	2007-08-03 09:58:50.000000000 +0200
+++ distcc-2.18.3/src/pump.c	2007-08-03 10:26:06.000000000 +0200
@@ -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 -ru distcc-2.18.3.orig/src/sendfile.c distcc-2.18.3/src/sendfile.c
--- distcc-2.18.3.orig/src/sendfile.c	2007-08-03 09:58:50.000000000 +0200
+++ distcc-2.18.3/src/sendfile.c	2007-08-03 10:26:06.000000000 +0200
@@ -163,6 +163,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
@@ -184,7 +185,7 @@
                 return dcc_pump_readwrite(ofd, ifd, size);
             } else 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) {
