cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] ccvs/src ChangeLog buffer.c buffer.h client.c l...


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/src ChangeLog buffer.c buffer.h client.c l...
Date: Tue, 28 Mar 2006 15:30:24 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         
Changes by:     Derek Robert Price <address@hidden>     06/03/28 15:30:23

Modified files:
        src            : ChangeLog buffer.c buffer.h client.c 
                         log-buffer.c main.c sanity.sh server.c 
Added files:
        src            : command_line_opt.h 

Log message:
        [patch #4992]
        * buffer.c (fd_buffer): Store new connection timeout parameter.
        (fd_buffer_initialize): Handle and set new connection timeout
        parameter.
        (fd_buffer_input, fd_buffer_output): Time out connections when
        requested.
        * buffer.h (fd_buffer_initialize): Update proto.
        * client.c, log-buffer.c, server.c: Update all callers.
        * server.c (server): Handle time out return from input/output.
        * command_line_opt.h: New header file.
        * main.c (main): Handle --timeout global option.
        * sanity.sh (server-23): New test.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/ChangeLog.diff?tr1=1.3360&tr2=1.3361&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/buffer.c.diff?tr1=1.66&tr2=1.67&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/buffer.h.diff?tr1=1.26&tr2=1.27&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/client.c.diff?tr1=1.440&tr2=1.441&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/command_line_opt.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/log-buffer.c.diff?tr1=1.16&tr2=1.17&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/main.c.diff?tr1=1.263&tr2=1.264&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/sanity.sh.diff?tr1=1.1121&tr2=1.1122&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/server.c.diff?tr1=1.455&tr2=1.456&r1=text&r2=text

Patches:
Index: ccvs/src/ChangeLog
diff -u ccvs/src/ChangeLog:1.3360 ccvs/src/ChangeLog:1.3361
--- ccvs/src/ChangeLog:1.3360   Fri Mar 24 16:02:56 2006
+++ ccvs/src/ChangeLog  Tue Mar 28 15:30:22 2006
@@ -1,3 +1,18 @@
+2006-03-28  Derek Price  <address@hidden>
+
+       [patch #4992]
+       * buffer.c (fd_buffer): Store new connection timeout parameter.
+       (fd_buffer_initialize): Handle and set new connection timeout
+       parameter.
+       (fd_buffer_input, fd_buffer_output): Time out connections when
+       requested.
+       * buffer.h (fd_buffer_initialize): Update proto.
+       * client.c, log-buffer.c, server.c: Update all callers.
+       * server.c (server): Handle time out return from input/output.
+       * command_line_opt.h: New header file.
+       * main.c (main): Handle --timeout global option.
+       * sanity.sh (server-23): New test.
+
 2006-03-24  Derek Price  <address@hidden>
 
        * sanity.sh (recase): Correct spelling typo in comment.
Index: ccvs/src/buffer.c
diff -u ccvs/src/buffer.c:1.66 ccvs/src/buffer.c:1.67
--- ccvs/src/buffer.c:1.66      Fri Jan 27 17:15:33 2006
+++ ccvs/src/buffer.c   Tue Mar 28 15:30:23 2006
@@ -1728,6 +1728,8 @@
     int fd;
     /* Nonzero if the file descriptor is in blocking mode.  */
     int blocking;
+    /* Time to wait for reads and writes to succeed.  */
+    long timeout;
     /* The child process id when fd is a pipe.  */
     pid_t child_pid;
     /* The connection info, when fd is a pipe to a server.  */
@@ -1742,18 +1744,19 @@
 static int fd_buffer_shutdown (struct buffer *);
 
 /* Initialize a buffer built on a file descriptor.  FD is the file
-   descriptor.  INPUT is nonzero if this is for input, zero if this is
+   descriptor.  INPUT is true if this is for input, false if this is
    for output.  MEMORY is the function to call when a memory error
    occurs.  */
 
 struct buffer *
 fd_buffer_initialize (int fd, pid_t child_pid, cvsroot_t *root, bool input,
-                      void (*memory) (struct buffer *))
+                      long timeout, void (*memory) (struct buffer *))
 {
     struct fd_buffer *n;
 
     n = xmalloc (sizeof *n);
     n->fd = fd;
+    n->timeout = timeout;
     n->child_pid = child_pid;
     n->root = root;
     fd_buffer_block (n, true);
@@ -1797,6 +1800,7 @@
  *
  * RETURNS
  *   errno     On error.
+ *   -3                On timeout.
  *   -1                On EOF.
  *   0         Otherwise.
  *
@@ -1809,7 +1813,7 @@
                 size_t *got)
 {
     struct fd_buffer *fb = closure;
-    int nbytes;
+    ssize_t nbytes;
 
     assert (need <= size);
 
@@ -1819,10 +1823,14 @@
     {
        int status;
        fd_set readfds;
+       struct timeval timeout;
+       struct timeval *timeout_p;
 
        /* Set non-block.  */
         status = fd_buffer_block (fb, false);
        if (status != 0) return status;
+       if (fb->timeout) timeout_p = &timeout;
+       else timeout_p = NULL;
 
        FD_ZERO (&readfds);
        FD_SET (fb->fd, &readfds);
@@ -1830,16 +1838,29 @@
        {
            int numfds;
 
-           do {
+           do
+           {
+               if (timeout_p)
+               {
+                   timeout.tv_sec = fb->timeout;
+                   timeout.tv_usec = 0;
+               }
+
                /* This used to select on exceptions too, but as far
                   as I know there was never any reason to do that and
                   SCO doesn't let you select on exceptions on pipes.  */
-               numfds = fd_select (fb->fd + 1, &readfds, NULL, NULL, NULL);
+               numfds = fd_select (fb->fd + 1, &readfds, NULL, NULL,
+                                   timeout_p);
                if (numfds < 0 && errno != EINTR)
                {
                    status = errno;
                    goto block_done;
                }
+               else if (numfds == 0)
+               {
+                   status = -3;
+                   goto block_done;
+               }
            } while (numfds < 0);
 
            nbytes = read (fb->fd, data + *got, size - *got);
@@ -1917,44 +1938,100 @@
 
 
 /* The buffer output function for a buffer built on a file descriptor.  */
-
 static int
 fd_buffer_output (void *closure, const char *data, size_t have, size_t *wrote)
 {
-    struct fd_buffer *fd = closure;
+    struct fd_buffer *fb = closure;
+    ssize_t nbytes;
 
     *wrote = 0;
 
-    while (have > 0)
+    if (fb->blocking)
     {
-       int nbytes;
+       int status;
+       fd_set writefds;
+       struct timeval timeout;
+       struct timeval *timeout_p;
 
-       nbytes = write (fd->fd, data, have);
+       /* Set non-block.  */
+        status = fd_buffer_block (fb, false);
+       if (status != 0) return status;
+       if (fb->timeout) timeout_p = &timeout;
+       else timeout_p = NULL;
 
-       if (nbytes <= 0)
+       FD_ZERO (&writefds);
+       FD_SET (fb->fd, &writefds);
+       do
        {
-           if (! fd->blocking
-               && (nbytes == 0 || blocking_error (errno)))
+           int numfds;
+
+           do
+           {
+               if (timeout_p)
+               {
+                   timeout.tv_sec = fb->timeout;
+                   timeout.tv_usec = 0;
+               }
+
+               /* This used to select on exceptions too, but as far
+                  as I know there was never any reason to do that and
+                  SCO doesn't let you select on exceptions on pipes.  */
+               numfds = fd_select (fb->fd + 1, NULL, &writefds, NULL,
+                                   timeout_p);
+               if (numfds < 0 && errno != EINTR)
+               {
+                   status = errno;
+                   goto block_done;
+               }
+               else if (numfds == 0)
+               {
+                   status = -3;
+                   goto block_done;
+               }
+           } while (numfds < 0);
+
+           nbytes = write (fb->fd, data + *wrote, have - *wrote);
+
+           if (nbytes < 0)
            {
-               /* A nonblocking write failed to write any data.  Just
-                  return.  */
-               return 0;
+               /* Some error occurred.  */
+               if (!blocking_error (errno))
+               {
+                   status = errno;
+                   break;
+               }
+               /* else Everything's fine, we just didn't get any data.  */
            }
 
-           /* Some sort of error occurred.  */
+           *wrote += nbytes;
+       } while (*wrote < have);
 
-           if (nbytes == 0)
-               return EIO;
+block_done:
+       if (status == 0)
+       {
+           int newstatus;
 
-           return errno;
+           /* OK - Reset block.  */
+           newstatus = fd_buffer_block (fb, true);
+           if (newstatus) status = newstatus;
        }
+       return status;
+    }
+
+    /* The above will always return.  Handle non-blocking read.  */
+    nbytes = write (fb->fd, data, have);
 
-       *wrote += nbytes;
-       data += nbytes;
-       have -= nbytes;
+    if (nbytes >= 0)
+    {
+       *wrote = nbytes;
+       return 0;
     }
 
-    return 0;
+    if (blocking_error (errno))
+       /* Everything's fine, we just didn't get any data.  */
+       return 0;
+
+    return errno;
 }
 
 
Index: ccvs/src/buffer.h
diff -u ccvs/src/buffer.h:1.26 ccvs/src/buffer.h:1.27
--- ccvs/src/buffer.h:1.26      Wed Jul 13 17:06:35 2005
+++ ccvs/src/buffer.h   Tue Mar 28 15:30:23 2006
@@ -184,7 +184,7 @@
 
 struct buffer *
 fd_buffer_initialize (int fd, pid_t child_pid, cvsroot_t *root, bool input,
-                      void (*memory) (struct buffer *));
+                      long timeout, void (*memory) (struct buffer *));
 
 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
    return it, rather than EAGAIN, for nonblocking writes.  */
Index: ccvs/src/client.c
diff -u ccvs/src/client.c:1.440 ccvs/src/client.c:1.441
--- ccvs/src/client.c:1.440     Sun Feb 26 21:30:10 2006
+++ ccvs/src/client.c   Tue Mar 28 15:30:23 2006
@@ -15,11 +15,16 @@
 #endif /* HAVE_CONFIG_H */
 
 #include "cvs.h"
+
+/* GNULIB Headers.  */
 #include "getline.h"
-#include "edit.h"
-#include "buffer.h"
 #include "save-cwd.h"
 
+/* CVS Headers.  */
+#include "buffer.h"
+#include "command_line_opt.h"
+#include "edit.h"
+
 #ifdef CLIENT_SUPPORT
 
 # include "log-buffer.h"
@@ -3431,9 +3436,10 @@
         * child_pid in there.  In theory, it should be stored in both
         * buffers with a ref count...
         */
-       *to_server_p = fd_buffer_initialize (tofd, 0, root, false, NULL);
+       *to_server_p = fd_buffer_initialize (tofd, 0, root, false,
+                                            connection_timeout, NULL);
        *from_server_p = fd_buffer_initialize (fromfd, child_pid, root,
-                                               true, NULL);
+                                               true, connection_timeout, NULL);
     }
 }
 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined (SERVER_SUPPORT) || defined 
(HAVE_KERBEROS) || defined(HAVE_GSSAPI) */
Index: ccvs/src/log-buffer.c
diff -u ccvs/src/log-buffer.c:1.16 ccvs/src/log-buffer.c:1.17
--- ccvs/src/log-buffer.c:1.16  Wed Mar 16 15:43:19 2005
+++ ccvs/src/log-buffer.c       Tue Mar 28 15:30:23 2006
@@ -384,7 +384,7 @@
     }
 
     /* Create a new fd buffer around the log.  */
-    retbuf = fd_buffer_initialize (fd, 0, NULL, true, buf->memory_error);
+    retbuf = fd_buffer_initialize (fd, 0, NULL, true, 0, buf->memory_error);
 
     {
        struct buffer *tmp;
Index: ccvs/src/main.c
diff -u ccvs/src/main.c:1.263 ccvs/src/main.c:1.264
--- ccvs/src/main.c:1.263       Sat Feb 25 07:41:50 2006
+++ ccvs/src/main.c     Tue Mar 28 15:30:23 2006
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
  *
- * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * Portions Copyright (C) 1998-2006 Derek Price, Ximbiot <http://ximbiot.com>,
  *                                  and others.
  *
  * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
@@ -19,11 +19,17 @@
 
 #include "cvs.h"
 
+/* GNULIB Headers.  */
 #include "closeout.h"
 #include "setenv.h"
 #include "strftime.h"
 #include "xgethostname.h"
 
+/* CVS Headers.  */
+#include "command_line_opt.h"
+
+
+
 const char *program_name;
 const char *program_path;
 const char *cvs_cmd_name;
@@ -43,6 +49,7 @@
 int noexec = 0;
 int readonlyfs = 0;
 int logoff = 0;
+long connection_timeout = 0;
 
 /*
  * Zero if compression isn't supported or requested; non-zero to indicate
@@ -291,6 +298,8 @@
     "    -n           Do not execute anything that will change the disk.\n",
     "    -t           Show trace of program execution (repeat for more\n",
     "                 verbosity) -- try with -n.\n",
+    "    --timeout SECONDS\n",
+    "                 Time out network connections in SECONDS seconds.\n",
     "    -R           Assume repository is read-only, such as CDROM\n",
     "    -v           CVS version and copyright.\n",
     "    -T tmpdir    Use 'tmpdir' for temporary files.\n",
@@ -526,6 +535,7 @@
        {"help-options", 0, NULL, 4},
 #ifdef SERVER_SUPPORT
        {"allow-root", required_argument, NULL, 3},
+       {"timeout", required_argument, NULL, 5},
 #endif /* SERVER_SUPPORT */
         {0, 0, 0, 0}
     };
@@ -650,6 +660,13 @@
                /* --allow-root */
                root_allow_add (optarg, gConfigPath);
                break;
+           case 5:
+               /* --timeout */
+               connection_timeout = strtol (optarg, &end, 10);
+               if (*end != '\0' || connection_timeout < 0)
+                 error (1, 0,
+"argument to --timeout must be greater than or equal to 0");
+               break;
 #endif /* SERVER_SUPPORT */
            case 'Q':
                really_quiet = 1;
Index: ccvs/src/sanity.sh
diff -u ccvs/src/sanity.sh:1.1121 ccvs/src/sanity.sh:1.1122
--- ccvs/src/sanity.sh:1.1121   Fri Mar 24 16:02:56 2006
+++ ccvs/src/sanity.sh  Tue Mar 28 15:30:23 2006
@@ -31441,6 +31441,12 @@
 noop
 EOF
 
+           # Test the server timeout feature.  If this fails, this test may
+           # block indefinitely.
+           dotest server-23 "$testcvs --timeout 5 server" \
+"E Fatal server error, aborting\.
+error ETIMEOUT Connection timed out\."
+
            dokeep
            rm -rf $TESTDIR/crerepos
            rm gzipped.dat session.dat
Index: ccvs/src/server.c
diff -u ccvs/src/server.c:1.455 ccvs/src/server.c:1.456
--- ccvs/src/server.c:1.455     Thu Feb  2 13:16:03 2006
+++ ccvs/src/server.c   Tue Mar 28 15:30:23 2006
@@ -11,6 +11,7 @@
 #include "cvs.h"
 
 /* CVS */
+#include "command_line_opt.h"
 #include "edit.h"
 #include "fileattr.h"
 #include "watch.h"
@@ -3707,7 +3708,7 @@
        error_use_protocol = 0;
 
        protocol = fd_buffer_initialize (protocol_pipe[1], 0, NULL, false,
-                                        protocol_memory_error);
+                                        0, protocol_memory_error);
 
        /* At this point we should no longer be using buf_to_net and
           buf_from_net.  Instead, everything should go through
@@ -3844,13 +3845,13 @@
        }
 
        stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 0, NULL, true,
-                                         input_memory_error);
+                                         0, input_memory_error);
 
        stderrbuf = fd_buffer_initialize (stderr_pipe[0], 0, NULL, true,
-                                         input_memory_error);
+                                         0, input_memory_error);
 
        protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 0, NULL, true,
-                                              input_memory_error);
+                                              0, input_memory_error);
 
        set_nonblock (buf_to_net);
        set_nonblock (stdoutbuf);
@@ -6371,8 +6372,10 @@
     if (!buf_to_net)
     {
        buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, NULL, false,
+                                          connection_timeout,
                                           outbuf_memory_error);
        buf_from_net = fd_buffer_initialize (STDIN_FILENO, 0, NULL, true,
+                                            connection_timeout,
                                             outbuf_memory_error);
     }
 
@@ -6445,6 +6448,12 @@
 error ENOMEM Virtual memory exhausted.\n");
            break;
        }
+       if (status == -3)
+       {
+           buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
+error ETIMEOUT Connection timed out.\n");
+           break;
+       }
        if (status != 0)
            break;
 
@@ -7218,8 +7227,10 @@
 
     /* Initialize buffers.  */
     buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, NULL, false,
+                                      connection_timeout,
                                       outbuf_memory_error);
     buf_from_net = fd_buffer_initialize (STDIN_FILENO, 0, NULL, true,
+                                        connection_timeout,
                                         outbuf_memory_error);
 
 #ifdef SO_KEEPALIVE




reply via email to

[Prev in Thread] Current Thread [Next in Thread]