diff options
Diffstat (limited to 'contrib/cvs/src/buffer.c')
-rw-r--r-- | contrib/cvs/src/buffer.c | 114 |
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; |