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 * close (and thus clear down) a slot, it is assumed that you have done whatever
86 * you need to do to close the actual device already
89 void sel_close(sel_t *sp)
92 chain_flush(sp->msgbase);
95 memset(sp, 0, sizeof(sel_t));
96 if (sel_top == (sp - sel) + 1)
103 * this actually runs the (de)multiplexor, it simply listens to the various cnums
104 * presents the events to the handler which has to deal with them
116 /* first set up the parameters for the select according to the slots registered */
122 for (i = 0; i < sel_top; ++i) {
124 if (sp->sort && !sp->err) {
125 if (sp->flags & SEL_INPUT)
126 FD_SET(sp->cnum, &infd);
127 if (sp->flags & SEL_OUTPUT)
128 FD_SET(sp->cnum, &outfd);
129 if (sp->flags & SEL_ERROR)
130 FD_SET(sp->cnum, &errfd);
136 /* now do the select */
137 r = select(max + 1, &infd, &outfd, &errfd, &tv);
141 die("Error during select (%d)", errno);
145 /* if there is anything to do, pass it on to the appropriate handler */
150 for (i = 0; i < sel_top; ++i) {
153 in = FD_ISSET(sp->cnum, &infd);
154 out = FD_ISSET(sp->cnum, &outfd);
155 err = FD_ISSET(sp->cnum, &errfd);
156 if (in || out || err) {
157 hr = (sp->handler)(sp, in, out, err);
159 /* if this is positive, close this selector */
163 FD_CLR(sp->cnum, &infd);
164 FD_CLR(sp->cnum, &outfd);
165 FD_CLR(sp->cnum, &errfd);
172 time(&sel_systime); /* note the time, for general purpuse use */
176 * get/set error flag - -1 simply gets the flag, 0 or 1 sets the flag
178 * in all cases the old setting of the flag is returned
181 int sel_error(sel_t *sp, int err)
191 * Revision 1.3 2000-03-30 22:51:14 djk
192 * fixed connect code in client.pl so it doesn't falsely recognise /spider
193 * /src/client as a 'client' directive.
194 * Tidied up the C client a bit
196 * Revision 1.2 2000/03/26 14:22:59 djk
197 * removed some irrelevant log info
199 * Revision 1.1 2000/03/26 00:03:30 djk
200 * first cut of client
202 * Revision 1.1 1997/01/03 23:44:31 djk