summaryrefslogtreecommitdiff
path: root/contrib/cvs/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/buffer.c')
-rw-r--r--contrib/cvs/src/buffer.c114
1 files changed, 72 insertions, 42 deletions
diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c
index fd98d82508e08..fb98e11d23be5 100644
--- a/contrib/cvs/src/buffer.c
+++ b/contrib/cvs/src/buffer.c
@@ -60,6 +60,11 @@ void
buf_free (buf)
struct buffer *buf;
{
+ if (buf->closure != NULL)
+ {
+ free (buf->closure);
+ buf->closure = NULL;
+ }
if (buf->data != NULL)
{
buf->last->next = free_buffer_data;
@@ -137,8 +142,23 @@ get_buffer_data ()
return ret;
}
-/* See whether a buffer is empty. */
+
+/* See whether a buffer and its file descriptor is empty. */
+int
+buf_empty (buf)
+ struct buffer *buf;
+{
+ /* Try and read any data on the file descriptor first.
+ * We already know the descriptor is non-blocking.
+ */
+ buf_input_data (buf, NULL);
+ return buf_empty_p (buf);
+}
+
+
+
+/* See whether a buffer is empty. */
int
buf_empty_p (buf)
struct buffer *buf;
@@ -151,6 +171,8 @@ buf_empty_p (buf)
return 1;
}
+
+
#ifdef SERVER_FLOWCONTROL
/*
* Count how much data is stored in the buffer..
@@ -1208,6 +1230,8 @@ buf_shutdown (buf)
return 0;
}
+
+
/* The simplest type of buffer is one built on top of a stdio FILE.
For simplicity, and because it is all that is required, we do not
implement setting this type of buffer into nonblocking mode. The
@@ -1218,14 +1242,17 @@ static int stdio_buffer_output PROTO((void *, const char *, int, int *));
static int stdio_buffer_flush PROTO((void *));
static int stdio_buffer_shutdown PROTO((struct buffer *buf));
-/* Initialize a buffer built on a stdio FILE. */
+
+/* Initialize a buffer built on a stdio FILE. */
struct stdio_buffer_closure
{
FILE *fp;
int child_pid;
};
+
+
struct buffer *
stdio_buffer_initialize (fp, child_pid, input, memory)
FILE *fp;
@@ -1351,8 +1378,9 @@ stdio_buffer_output (closure, data, have, wrote)
return 0;
}
-/* The buffer flush function for a buffer built on a stdio FILE. */
+
+/* The buffer flush function for a buffer built on a stdio FILE. */
static int
stdio_buffer_flush (closure)
void *closure;
@@ -1376,12 +1404,12 @@ static int
stdio_buffer_shutdown (buf)
struct buffer *buf;
{
- struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) buf->closure;
+ struct stdio_buffer_closure *bc = buf->closure;
struct stat s;
int closefp = 1;
/* Must be a pipe or a socket. What could go wrong? */
- assert (fstat ( fileno (bc->fp), &s ) != -1);
+ assert (fstat (fileno (bc->fp), &s) != -1);
/* Flush the buffer if we can */
if (buf->flush)
@@ -1392,30 +1420,11 @@ stdio_buffer_shutdown (buf)
if (buf->input)
{
- if ( !buf_empty_p (buf) )
- {
-# ifdef SERVER_SUPPORT
- if (server_active)
- /* FIXME: This should probably be sysloged since it doesn't
- * have anywhere else to go at this point.
- */
- error (0, 0, "dying gasps from client unexpected");
- else
-#endif
- error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
- }
- else if (ferror (bc->fp))
- {
-# ifdef SERVER_SUPPORT
- if (server_active)
- /* FIXME: This should probably be sysloged since it doesn't
- * have anywhere else to go at this point.
- */
- error (0, errno, "reading from client");
- else
-#endif
- error (0, errno, "reading from %s", current_parsed_root->hostname);
- }
+ /* There used to be a check here for unread data in the buffer of on
+ * the pipe, but it was deemed unnecessary and possibly dangerous. In
+ * some sense it could be second-guessing the caller who requested it
+ * closed, as well.
+ */
# ifdef SHUTDOWN_SERVER
if (current_parsed_root->method != server_method)
@@ -1423,8 +1432,8 @@ stdio_buffer_shutdown (buf)
# ifndef NO_SOCKET_TO_FD
{
/* shutdown() sockets */
- if (S_ISSOCK(s.st_mode))
- shutdown ( fileno (bc->fp), 0);
+ if (S_ISSOCK (s.st_mode))
+ shutdown (fileno (bc->fp), 0);
}
# endif /* NO_SOCKET_TO_FD */
# ifdef START_RSH_WITH_POPEN_RW
@@ -1446,13 +1455,13 @@ stdio_buffer_shutdown (buf)
* SHUTDOWN_SERVER_OUTPUT
*/
if (current_parsed_root->method == server_method)
- SHUTDOWN_SERVER ( fileno (bc->fp) );
+ SHUTDOWN_SERVER (fileno (bc->fp));
else
# endif
# ifndef NO_SOCKET_TO_FD
/* shutdown() sockets */
- if (S_ISSOCK(s.st_mode))
- shutdown ( fileno (bc->fp), 1);
+ if (S_ISSOCK (s.st_mode))
+ shutdown (fileno (bc->fp), 1);
# else
{
/* I'm not sure I like this empty block, but the alternative
@@ -1465,15 +1474,34 @@ stdio_buffer_shutdown (buf)
}
if (closefp && fclose (bc->fp) == EOF)
- error (1, errno,
- "closing down connection to %s",
- current_parsed_root->hostname);
+ {
+ if (0
+# ifdef SERVER_SUPPORT
+ || server_active
+# endif /* SERVER_SUPPORT */
+ )
+ {
+ /* Syslog this? */
+ }
+# ifdef CLIENT_SUPPORT
+ else
+ error (1, errno,
+ "closing down connection to %s",
+ current_parsed_root->hostname);
+# endif /* CLIENT_SUPPORT */
+ }
/* If we were talking to a process, make sure it exited */
- if (bc->child_pid
- && waitpid (bc->child_pid, (int *) 0, 0) == -1)
- error (1, errno, "waiting for process %d", bc->child_pid);
+ if (bc->child_pid)
+ {
+ int w;
+ do
+ w = waitpid (bc->child_pid, (int *) 0, 0);
+ while (w == -1 && errno == EINTR);
+ if (w == -1)
+ error (1, errno, "waiting for process %d", bc->child_pid);
+ }
return 0;
}
@@ -1872,8 +1900,9 @@ packetizing_buffer_output (closure, data, have, wrote)
return buf_send_output (pb->buf);
}
-/* Flush data to a packetizing buffer. */
+
+/* Flush data to a packetizing buffer. */
static int
packetizing_buffer_flush (closure)
void *closure;
@@ -1887,8 +1916,9 @@ packetizing_buffer_flush (closure)
return buf_flush (pb->buf, 0);
}
-/* The block routine for a packetizing buffer. */
+
+/* The block routine for a packetizing buffer. */
static int
packetizing_buffer_block (closure, block)
void *closure;