From 30e8b23e52a9ee5b5735d0179dd572656feeaa6b Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 19 Oct 2003 16:47:06 +0000 Subject: [PATCH] Added fastbuf backend for reading from file descriptors with a given limit. (Very useful for communication over sockets.) --- lib/fastbuf.h | 4 +++ lib/fb-limfd.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 lib/fb-limfd.c diff --git a/lib/fastbuf.h b/lib/fastbuf.h index e08e16a1..8699fe40 100644 --- a/lib/fastbuf.h +++ b/lib/fastbuf.h @@ -82,6 +82,10 @@ struct fastbuf *fbmem_clone_read(struct fastbuf *); /* Create reading fastbuf */ struct fastbuf *bopen_mm(byte *name, uns mode); +/* FastI on file descriptors with limit */ + +struct fastbuf *bopen_limited_fd(int fd, uns bufsize, uns limit); + /* Configuring stream parameters */ int bconfig(struct fastbuf *f, uns type, int data); diff --git a/lib/fb-limfd.c b/lib/fb-limfd.c new file mode 100644 index 00000000..c1b6cb2c --- /dev/null +++ b/lib/fb-limfd.c @@ -0,0 +1,74 @@ +/* + * Sherlock Library -- Fast Buffered Input on Limited File Descriptors + * + * (c) 2003 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" +#include "lib/fastbuf.h" + +#include +#include + +struct fb_limfd { + struct fastbuf fb; + int fd; /* File descriptor */ + int limit; +}; +#define FB_LIMFD(f) ((struct fb_limfd *)(f)->is_fastbuf) + +static int +bfl_refill(struct fastbuf *f) +{ + int max = MIN(FB_LIMFD(f)->limit - f->pos, f->bufend - f->buffer); + int l = read(FB_LIMFD(f)->fd, f->buffer, max); + if (l < 0) + die("Error reading %s: %m", f->name); + f->bptr = f->buffer; + f->bstop = f->buffer + l; + f->pos += l; + return l; +} + +static void +bfl_close(struct fastbuf *f) +{ + xfree(f); +} + +struct fastbuf * +bopen_limited_fd(int fd, uns buflen, uns limit) +{ + struct fb_limfd *F = xmalloc(sizeof(struct fb_limfd) + buflen); + struct fastbuf *f = &F->fb; + + bzero(F, sizeof(*F)); + f->buffer = (char *)(F+1); + f->bptr = f->bstop = f->buffer; + f->bufend = f->buffer + buflen; + f->name = "limited-fd"; + F->fd = fd; + F->limit = limit; + f->refill = bfl_refill; + f->close = bfl_close; + return f; +} + +#ifdef TEST + +int main(int argc, char **argv) +{ + struct fastbuf *f = bopen_limited_fd(0, 3, 13); + struct fastbuf *o = bfdopen_shared(1, 16); + int c; + while ((c = bgetc(f)) >= 0) + bputc(o, c); + bclose(o); + bclose(f); + return 0; +} + +#endif -- 2.39.2