chiark / gitweb /
b572f4b937d39b8e798c66888e54d4049a115735
[mLib] / selbuf.c
1 /* -*-c-*-
2  *
3  * Line-buffering select handler
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the mLib utilities library.
11  *
12  * mLib is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * mLib is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with mLib; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include <sys/types.h>
36 #include <sys/time.h>
37 #include <unistd.h>
38
39 #include "lbuf.h"
40 #include "sel.h"
41 #include "selbuf.h"
42
43 /*----- Main code ---------------------------------------------------------*/
44
45 /* --- @selbuf_enable@ --- *
46  *
47  * Arguments:   @selbuf *b@ = pointer to buffer block
48  *
49  * Returns:     ---
50  *
51  * Use:         Enables a buffer for reading, and emits any queued lines
52  *              to the buffer's owner.
53  */
54
55 void selbuf_enable(selbuf *b)
56 {
57   if (!(b->b.f & LBUF_ENABLE)) {
58     b->b.f |= LBUF_ENABLE;
59     sel_addfile(&b->reader);
60     lbuf_flush(&b->b, 0, 0);
61   }
62 }
63
64 /* --- @selbuf_disable@ --- *
65  *
66  * Arguments:   @selbuf *b@ = pointer to a buffer block
67  *
68  * Returns:     ---
69  *
70  * Use:         Disables a buffer.  It won't be read from until it's
71  *              enabled again.
72  */
73
74 void selbuf_disable(selbuf *b)
75 {
76   if (b->b.f & LBUF_ENABLE) {
77     b->b.f &= ~LBUF_ENABLE;
78     sel_rmfile(&b->reader);
79   }
80 }
81
82 /* --- @selbuf_read@ --- *
83  *
84  * Arguments:   @int fd@ = file descriptor to read from
85  *              @int mode@ = what we can do to the file
86  *              @void *vp@ = pointer to buffer context
87  *
88  * Returns:     ---
89  *
90  * Use:         Acts on the result of a @select@ call.
91  */
92
93 static void selbuf_read(int fd, unsigned mode, void *vp)
94 {
95   selbuf *b = vp;
96   char *p;
97   size_t sz;
98   int n;
99
100   sz = lbuf_free(&b->b, &p);
101   n = read(fd, p, sz);
102   if (n == 0)
103     lbuf_close(&b->b);
104   else if (n > 0)
105     lbuf_flush(&b->b, p, n);
106   else switch (errno) {
107     case EINTR:
108     case EAGAIN:
109 #if EAGAIN != EWOULDBLOCK
110     case EWOULDBLOCK:
111 #endif
112       return;
113     default:
114       lbuf_close(&b->b);
115   }
116 }
117
118 /* --- @selbuf_setsize@ --- *
119  *
120  * Arguments:   @selbuf *b@ = pointer to buffer block
121  *              @size_t sz@ = size of buffer
122  *
123  * Returns:     ---
124  *
125  * Use:         Sets the size of the buffer used for reading lines.
126  */
127
128 void selbuf_setsize(selbuf *b, size_t sz)
129 {
130   lbuf_setsize(&b->b, sz);
131 }
132
133 /* --- @selbuf_init@ --- *
134  *
135  * Arguments:   @selbuf *b@ = pointer to buffer block
136  *              @sel_state *s@ = pointer to select state to attach to
137  *              @int fd@ = file descriptor to listen to
138  *              @lbuf_func *func@ = function to call
139  *              @void *p@ = argument for function
140  *
141  * Returns:     ---
142  *
143  * Use:         Initializes a buffer block.
144  */
145
146 void selbuf_init(selbuf *b, sel_state *s, int fd, lbuf_func *func, void *p)
147 {
148   lbuf_init(&b->b, func, p);
149   b->b.f &= ~LBUF_ENABLE;
150   sel_initfile(s, &b->reader, fd, SEL_READ, selbuf_read, b);
151   selbuf_enable(b);
152 }
153
154 /* --- @selbuf_destroy@ --- *
155  *
156  * Arguments:   @selbuf *b@ = pointer to buffer block
157  *
158  * Returns:     ---
159  *
160  * Use:         Deallocates a line buffer and frees any resources it owned.
161  */
162
163 void selbuf_destroy(selbuf *b)
164 {
165   selbuf_disable(b);
166   lbuf_destroy(&b->b);
167 }
168
169 /*----- That's all, folks -------------------------------------------------*/