kernel: Remove the FFS_ROOT option. It was a no-op since 4.9.
[dragonfly.git] / contrib / cvs-1.12 / src / ms-buffer.c
blob5bf49f5c2e75003d9c10f2050af041478902516e
1 /* CVS client logging buffer.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details. */
13 #include <config.h>
15 #include <stdio.h>
17 #include "cvs.h"
18 #include "buffer.h"
19 #include "ms-buffer.h"
21 #if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
22 #ifdef PROXY_SUPPORT
24 /* This structure is the closure field of a multi-source buffer. */
25 struct ms_buffer
27 /* Our buffer struct. */
28 struct buffer *buf;
30 /* The underlying buffers. */
31 struct buffer *cur;
32 List *bufs;
34 /* Whether we are in blocking mode or not. */
35 bool block;
40 /* The block function for a multi-source buffer. */
41 static int
42 ms_buffer_block (void *closure, bool block)
44 struct ms_buffer *mb = closure;
46 mb->block = block;
47 if (block)
48 return set_block (mb->cur);
49 else
50 return set_nonblock (mb->cur);
55 /* The input function for a log buffer. */
56 static int
57 ms_buffer_input (void *closure, char *data, size_t need, size_t size,
58 size_t *got)
60 struct ms_buffer *mb = closure;
61 int status;
63 assert (mb->cur->input);
64 status = (*mb->cur->input) (mb->cur->closure, data, need, size, got);
65 if (status == -1)
67 Node *p;
68 /* EOF. Set up the next buffer in line but return success and no
69 * data since our caller may have selected on the target to find
70 * ready data before calling us.
72 * If there are no more buffers, return EOF.
74 if (list_isempty (mb->bufs)) return -1;
75 buf_shutdown (mb->cur);
76 buf_free (mb->cur);
77 p = mb->bufs->list->next;
78 mb->cur = p->data;
79 p->delproc = NULL;
80 p->data = NULL;
81 delnode (p);
82 if (!buf_empty_p (mb->cur)) buf_append_buffer (mb->buf, mb->cur);
83 ms_buffer_block (closure, mb->block);
84 *got = 0;
85 status = 0;
88 return status;
93 /* Return the file descriptor underlying any child buffers. */
94 static int
95 ms_buffer_get_fd (void *closure)
97 struct ms_buffer *mb = closure;
98 return buf_get_fd (mb->cur);
103 /* The shutdown function for a multi-source buffer. */
104 static int
105 ms_buffer_shutdown (struct buffer *buf)
107 struct ms_buffer *mb = buf->closure;
108 Node *p;
109 int err = 0;
111 assert (mb->cur);
112 err += buf_shutdown (mb->cur);
113 buf_free (mb->cur);
114 for (p = mb->bufs->list->next; p != mb->bufs->list; p = p->next)
116 assert (p);
117 err += buf_shutdown (p->data);
120 dellist (&mb->bufs);
121 return err;
126 static void
127 delbuflist (Node *p)
129 if (p->data)
130 buf_free (p->data);
135 /* Create a multi-source buffer. This could easily be generalized to support
136 * any number of source buffers, but for now only two are necessary.
138 struct buffer *
139 ms_buffer_initialize (void (*memory) (struct buffer *),
140 struct buffer *buf, struct buffer *buf2/*, ...*/)
142 struct ms_buffer *mb = xmalloc (sizeof *mb);
143 struct buffer *retbuf;
144 Node *p;
146 mb->block = false;
147 mb->cur = buf;
148 set_nonblock (buf);
149 mb->bufs = getlist ();
150 p = getnode ();
151 p->data = buf2;
152 p->delproc = delbuflist;
153 addnode (mb->bufs, p);
154 retbuf = buf_initialize (ms_buffer_input, NULL, NULL,
155 ms_buffer_block, ms_buffer_get_fd,
156 ms_buffer_shutdown, memory, mb);
157 if (!buf_empty_p (buf)) buf_append_buffer (retbuf, buf);
158 mb->buf = retbuf;
160 return retbuf;
162 #endif /* PROXY_SUPPORT */
163 #endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */