Browse code

socklib: implement sselect functions using select as backend

Dario Rodriguez authored on 10/06/2014 10:36:24
Showing 1 changed files
... ...
@@ -7,6 +7,7 @@
7 7
  *      28/01/2014 Creation
8 8
  *      27/05/2014 New API.
9 9
  *      28/05/2014 Implement the ipv4_* functions.
10
+ *      10/06/2014 Implement the sselect functions using select as backend.
10 11
  *
11 12
  * Author: Dario Rodriguez dario@softhome.net
12 13
  * This file is licensed under the terms of the GNU LGPL v2+
... ...
@@ -28,12 +29,20 @@
28 29
 #include "socklib.h"
29 30
 
30 31
 typedef struct _sselect {
31
-        int dummy;
32
+        int fd_set readset;
33
+        int fd_set writeset;
34
+        int maxfd;
35
+        int numfd;
36
+        int fd_set readresult;
37
+        int fd_set writeresult;
38
+        int sizeresult;
39
+        int readresultreturned;
40
+        int writeresultreturned;
32 41
 } _sselect;
33 42
 
34 43
 
35 44
 #ifndef FILLTV
36
-#define FILLTV(tv,sec,usec) tv.tv_sec=sec,tv.tv_usec=usec
45
+#define FILLTV(tv,sec,usec) (tv).tv_sec=(sec),(tv).tv_usec=(usec)
37 46
 #endif
38 47
 
39 48
 #ifndef FILLIPV4ADDR
... ...
@@ -217,16 +226,140 @@ sock_setblocking(int fd, int block)
217 226
         return(fcntl(fd,F_SETFL,fl));
218 227
 }
219 228
 
220
-sselect *sselect_init(void);
221
-int sselect_reset(sselect *ssel);
222
-int sselect_addread(sselect *ssel, int fd);
223
-int sselect_addwrite(sselect *ssel, int fd);
224
-int sselect_delread(sselect *ssel, int fd);
225
-int sselect_delwrite(sselect *ssel, int fd);
226
-int sselect_wait(sselect *ssel, int ms);
227
-int sselect_getread(sselect *ssel, int *fds, int sizefds);
228
-int sselect_getwrite(sselect *ssel, int *fds, int sizefds);
229
+sselect *
230
+sselect_init(void)
231
+{
232
+        _sselect *ssel;
233
+        if((ssel=malloc(sizeof(_sselect)))==NULL)
234
+                return(NULL);
235
+        memset(ssel,0,sizeof(_sselect));
236
+        sselect_reset((sselect *)ssel);
237
+        return((sselect *)ssel);
238
+}
239
+
240
+int
241
+sselect_reset(sselect *paramssel)
242
+{
243
+        int i;
244
+        _sselect *ssel=(_sselect *)paramssel;
245
+        if(ssel==NULL)
246
+                return(-1);
247
+        FD_ZERO(&(ssel->readset));
248
+        FD_ZERO(&(ssel->writeset));
249
+        ssel->maxfd=0;
250
+        ssel->numfd=0;
251
+        FD_ZERO(&(ssel->readresult));
252
+        FD_ZERO(&(ssel->writeresult));
253
+        return(0);
254
+}
255
+
256
+int
257
+sselect_addread(sselect *paramssel, int fd)
258
+{
259
+        int i;
260
+        _sselect *ssel=(_sselect *)paramssel;
261
+        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->readset))
262
+                return(-1);
263
+        FD_SET(fd,&(ssel->readset));
264
+        if(fd>ssel->maxfd)
265
+                ssel->maxfd=fd;
266
+        ssel->numfd++;
267
+        return(0);
268
+}
269
+
270
+
271
+int
272
+sselect_addwrite(sselect *paramssel, int fd)
273
+{
274
+        int i;
275
+        _sselect *ssel=(_sselect *)paramssel;
276
+        if(ssel==NULL || fd<0 ||  FD_ISSET(fd,&(ssel->writeset))
277
+                return(-1);
278
+        FD_SET(fd,&(ssel->writeset));
279
+        if(fd>ssel->maxfd)
280
+                ssel->maxfd=fd;
281
+        ssel->numfd++;
282
+        return(0);
283
+}
284
+
285
+int
286
+sselect_delread(sselect *paramssel, int fd)
287
+{
288
+        int i;
289
+        _sselect *ssel=(_sselect *)paramssel;
290
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->readset))
291
+                return(-1);
292
+        FD_CLR(fd,&(ssel->readset));
293
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->writeset))
294
+                ssel->maxfd=fd-1;
295
+        ssel->numfd--;
296
+        return(0);
297
+}
298
+
299
+
300
+int
301
+sselect_delwrite(sselect *paramssel, int fd)
302
+{
303
+        int i;
304
+        _sselect *ssel=(_sselect *)paramssel;
305
+        if(ssel==NULL || fd<0 || !FD_ISSET(fd,&(ssel->writeset))
306
+                return(-1);
307
+        FD_CLR(fd,&(ssel->writeset));
308
+        if(fd>0 && fd==ssel->maxfd && !FD_ISSET(fd,&(ssel->readset))
309
+                ssel->maxfd=fd-1;
310
+        ssel->numfd--;
311
+        return(0);
312
+}
313
+
314
+int
315
+sselect_wait(sselect *paramssel, int ms)
316
+{
317
+        fd_set readset,writefd;
318
+        timeval tv;
319
+        _sselect *ssel=(_sselect *)paramssel;
320
+        if(ssel==NULL || ms<0)
321
+                return(-1);
322
+        memcpy(&(ssel->readresult),&(ssel->readset),sizeof(fd_set));
323
+        memcpy(&(ssel->writeresult),&(ssel->writeset),sizeof(fd_set));
324
+        ssel->readresultreturned=0;
325
+        ssel->writeresultreturned=0;
326
+        FILLTV(tv,(ms/1000),(ms%1000)*1000);
327
+        if((ssel->sizeresult=select(
328
+          ssel->maxfd+1,&(ssel->readresult),
329
+          &(ssel->writeresult),NULL,&tv))<0)
330
+                return(-1);
331
+        return(ssel->sizeresult);
332
+}
229 333
 
334
+int
335
+sselect_getread(sselect *paramssel, int *fds, int sizefds)
336
+{
337
+        int i,n;
338
+        _sselect *ssel=(_sselect *)paramssel;
339
+        if(ssel==NULL || fds==NULL || sizefds<1)
340
+                return(-1);
341
+        for(n=0,i=ssel->readresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
342
+                if(FD_ISSET(i,&(ssel->readresult)))
343
+                        fds[n++]=i;
344
+        }
345
+        ssel->readresultreturned=i;
346
+        return(n);
347
+}
348
+
349
+int
350
+sselect_getwrite(sselect *paramssel, int *fds, int sizefds)
351
+{
352
+        int i,n;
353
+        _sselect *ssel=(_sselect *)paramssel;
354
+        if(ssel==NULL || fds==NULL || sizefds<1)
355
+                return(-1);
356
+        for(n=0,i=ssel->writeresultreturned;i<ssel->maxfd && n<sizeofds;i++) {
357
+                if(FD_ISSET(i,&(ssel->writeresult)))
358
+                        fds[n++]=i;
359
+        }
360
+        ssel->writeresultreturned=i;
361
+        return(n);
362
+}
230 363
 
231 364
 /* aux functions */
232 365
 void