2 * UCW Library -- Fast Buffered I/O on Sockets with Timeouts
4 * (c) 2008 Martin Mares <mj@ucw.cz>
5 * (c) 2017 Pavel Charvat <pchar@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
12 #include <ucw/fastbuf.h>
13 #include <ucw/fb-socket.h>
22 struct fbsock_params par;
26 #define FB_SOCK(f) ((struct fb_sock *)(f))
29 fbs_refill(struct fastbuf *f)
31 struct fbsock_params *p = &FB_SOCK(f)->par;
39 int e = poll(&pf, 1, p->timeout_ms);
42 p->err(p->data, FBSOCK_READ, "read error");
47 p->err(p->data, FBSOCK_READ | FBSOCK_TIMEOUT, "read timeout");
52 int l = read(p->fd, f->buffer, f->bufend-f->buffer);
55 if (errno == EINTR || errno == EAGAIN)
57 p->err(p->data, FBSOCK_READ, "read error");
60 f->bstop = f->buffer + l;
67 fbs_spout(struct fastbuf *f)
69 struct fbsock_params *p = &FB_SOCK(f)->par;
75 int l = f->bptr - f->bstop;
82 int e = poll(&pf, 1, p->timeout_ms);
85 p->err(p->data, FBSOCK_WRITE, "write error");
90 p->err(p->data, FBSOCK_WRITE | FBSOCK_TIMEOUT, "write timeout");
94 e = write(p->fd, buf, l);
97 if (errno == EINTR || errno == EAGAIN)
99 p->err(p->data, FBSOCK_WRITE, "write error");
108 fbs_close(struct fastbuf *f)
110 if (!FB_SOCK(f)->par.fd_is_shared)
111 close(FB_SOCK(f)->par.fd);
116 fbsock_create(struct fbsock_params *p)
118 struct fb_sock *F = xmalloc(sizeof(*F) + p->bufsize);
119 struct fastbuf *f = &F->fb;
121 bzero(F, sizeof(*F));
124 f->bptr = f->bstop = f->buffer;
125 f->bufend = f->buffer + p->bufsize;
126 f->name = "<socket>";
127 f->refill = fbs_refill;
128 f->spout = fbs_spout;
129 f->close = fbs_close;
130 f->can_overwrite_buffer = 1;
138 static void test_err(void *x UNUSED, uint flags, char *msg UNUSED)
140 if (flags & FBSOCK_READ)
142 else if (flags & FBSOCK_WRITE)
144 if (flags & FBSOCK_TIMEOUT)
145 printf(" TIMEOUT\n");
157 struct fbsock_params p = {
163 struct fastbuf *f = fbsock_create(&p);
165 bputsn(f, "Oook!"); // This fits in PIPE_BUF
169 if (!bgets(f, buf, sizeof(buf)))
171 if (strcmp(buf, "Oook!"))
172 die("Misread input");
174 bgets(f, buf, sizeof(buf));