[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Cvs-cvs] ccvs/src ChangeLog buffer.c buffer.h client.c l...,
Derek Robert Price <=