]> mj.ucw.cz Git - libucw.git/blob - lib/fb-limfd.c
7e07e328f94a0d6de2bac582d9641fb412d86511
[libucw.git] / lib / fb-limfd.c
1 /*
2  *      Sherlock Library -- Fast Buffered Input on Limited File Descriptors
3  *
4  *      (c) 2003 Martin Mares <mj@ucw.cz>
5  *      (c) 2004 Robert Spalek <robert@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "lib/lib.h"
12 #include "lib/fastbuf.h"
13
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 struct fb_limfd {
18   struct fastbuf fb;
19   int fd;                               /* File descriptor */
20   int limit;
21   int can_overwrite;
22 };
23 #define FB_LIMFD(f) ((struct fb_limfd *)(f)->is_fastbuf)
24
25 static int
26 bfl_refill(struct fastbuf *f)
27 {
28   int max = MIN(FB_LIMFD(f)->limit - f->pos, f->bufend - f->buffer);
29   int l = read(FB_LIMFD(f)->fd, f->buffer, max);
30   if (l < 0)
31     die("Error reading %s: %m", f->name);
32   f->bptr = f->buffer;
33   f->bstop = f->buffer + l;
34   f->pos += l;
35   return l;
36 }
37
38 static void
39 bfl_close(struct fastbuf *f)
40 {
41   xfree(f);
42 }
43
44 static int
45 bfl_config(struct fastbuf *f, uns item, int value)
46 {
47   switch (item)
48     {
49     case BCONFIG_CAN_OVERWRITE: ;
50       int old_value = FB_LIMFD(f)->can_overwrite;
51       if (value >= 0 && value <= 2)
52         FB_LIMFD(f)->can_overwrite = value;
53       return old_value;
54     default:
55       return -1;
56     }
57 }
58
59 struct fastbuf *
60 bopen_limited_fd(int fd, uns buflen, uns limit)
61 {
62   struct fb_limfd *F = xmalloc(sizeof(struct fb_limfd) + buflen);
63   struct fastbuf *f = &F->fb;
64
65   bzero(F, sizeof(*F));
66   f->buffer = (char *)(F+1);
67   f->bptr = f->bstop = f->buffer;
68   f->bufend = f->buffer + buflen;
69   f->name = "limited-fd";
70   F->fd = fd;
71   F->limit = limit;
72   f->refill = bfl_refill;
73   f->close = bfl_close;
74   f->config = bfl_config;
75   F->can_overwrite = 2;
76   return f;
77 }
78
79 #ifdef TEST
80
81 int main(int argc, char **argv)
82 {
83   struct fastbuf *f = bopen_limited_fd(0, 3, 13);
84   struct fastbuf *o = bfdopen_shared(1, 16);
85   int c;
86   while ((c = bgetc(f)) >= 0)
87     bputc(o, c);
88   bclose(o);
89   bclose(f);
90   return 0;
91 }
92
93 #endif