4 * util routines for do the various select activities
6 * Copyright 1996 (c) D-J Koopman
12 static char rcsid[] = "$Id$";
15 #include <sys/types.h>
25 sel_t *sel; /* the array of selectors */
26 int sel_max; /* the maximum no of selectors */
27 int sel_top; /* the last selector in use */
28 int sel_inuse; /* the no of selectors in use */
29 time_t sel_systime; /* the unix time now */
30 struct timeval sel_tv; /* the current timeout for select */
33 * initialise the selector system, no is the no of slots to reserve
36 void sel_init(int no, long sec, long usec)
38 sel = malloc(sizeof(sel_t) * no);
40 die("no room in sel_init");
41 memset(sel, 0, sizeof(sel_t) * no);
43 sel_inuse = sel_top = 0;
44 if (sec == 0 && usec == 0)
47 sel_tv.tv_usec = usec;
51 * open and initialise a selector slot, you are expected to deal with the
52 * actual opening and setting up of the device itself
55 sel_t *sel_open(int cnum, void *fcb, char *name, int (*handler)(), int sort, int flags)
61 for (i = 0; i < sel_max; ++i) {
67 die("there are no more sel slots available (max %d)", sel_max);
69 /* fill in the blanks */
72 sp->name = strdup(name);
73 sp->handler = handler;
76 sp->msgbase = chain_new();
79 if (sel_top < (sp - sel) + 1)
80 sel_top = (sp - sel) + 1;
85 * post a close handler for this connection, to do special things
86 * in the event of this cnum closing, the default is just to close
89 void sel_closehandler(sel_t *sp, void (*handler)())
91 sp->closehandler = handler;
95 * close (and thus clear down) a slot, it is assumed that you have done whatever
96 * you need to do to close the actual device already
99 void sel_close(sel_t *sp)
102 if (sp->closehandler) {
103 (sp->closehandler)(sp);
107 chain_flush(sp->msgbase);
110 memset(sp, 0, sizeof(sel_t));
111 if (sel_top == (sp - sel) + 1)
118 * this actually runs the (de)multiplexor, it simply listens to the various cnums
119 * presents the events to the handler which has to deal with them
131 /* first set up the parameters for the select according to the slots registered */
137 for (i = 0; i < sel_top; ++i) {
139 if (sp->sort && !sp->err) {
140 if (sp->flags & SEL_INPUT)
141 FD_SET(sp->cnum, &infd);
142 if (sp->flags & SEL_OUTPUT)
143 FD_SET(sp->cnum, &outfd);
144 if (sp->flags & SEL_ERROR)
145 FD_SET(sp->cnum, &errfd);
151 /* now do the select */
152 r = select(max + 1, &infd, &outfd, &errfd, &tv);
156 die("Error during select (%d)", errno);
160 /* if there is anything to do, pass it on to the appropriate handler */
165 for (i = 0; i < sel_top; ++i) {
168 in = FD_ISSET(sp->cnum, &infd);
169 out = FD_ISSET(sp->cnum, &outfd);
170 err = FD_ISSET(sp->cnum, &errfd);
171 if (in || out || err) {
172 hr = (sp->handler)(sp, in, out, err);
174 /* if this is positive, close this selector */
178 FD_CLR(sp->cnum, &infd);
179 FD_CLR(sp->cnum, &outfd);
180 FD_CLR(sp->cnum, &errfd);
187 time(&sel_systime); /* note the time, for general purpuse use */
191 * get/set error flag - -1 simply gets the flag, 0 or 1 sets the flag
193 * in all cases the old setting of the flag is returned
196 int sel_error(sel_t *sp, int err)
206 * Revision 1.5 2002-01-27 15:35:33 minima
207 * try to fix EOF on standard input problems
209 * Revision 1.4 2000/07/20 14:16:00 minima
210 * can use Sourceforge now!
211 * added user->qra cleaning
212 * added 4 digit qra to user broadcast dxspots if available
214 * Revision 1.3 2000/03/30 22:51:14 djk
215 * fixed connect code in client.pl so it doesn't falsely recognise /spider
216 * /src/client as a 'client' directive.
217 * Tidied up the C client a bit
219 * Revision 1.2 2000/03/26 14:22:59 djk
220 * removed some irrelevant log info
222 * Revision 1.1 2000/03/26 00:03:30 djk
223 * first cut of client
225 * Revision 1.1 1997/01/03 23:44:31 djk