source: rtems/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_sockets.c @ 14876018

4.115
Last change on this file since 14876018 was 14876018, checked in by Daniel Ramirez <javamonn@…>, on 11/21/13 at 00:24:48

select.h, rtems_select.c, nds select: Add restrict keyword

  • Property mode set to 100644
File size: 18.1 KB
RevLine 
[311dfa6]1// DSWifi Project - sgIP Internet Protocol Stack Implementation
2// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
[32b8506]3/******************************************************************************
[311dfa6]4DSWifi Lib and test materials are licenced under the MIT open source licence:
5Copyright (c) 2005-2006 Stephen Stair
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software and associated documentation files (the "Software"), to deal in
9the Software without restriction, including without limitation the rights to
10use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11of the Software, and to permit persons to whom the Software is furnished to do
12so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24******************************************************************************/
25
26#include "sgIP_sockets.h"
27#include "sgIP_TCP.h"
28#include "sgIP_UDP.h"
29#include "sgIP_ICMP.h"
30#include "sgIP_DNS.h"
31
32
33sgIP_socket_data socketlist[SGIP_SOCKET_MAXSOCKETS];
34extern unsigned long sgIP_timems;
35
36
37void sgIP_sockets_Init() {
38        int i;
39        for(i=0;i<SGIP_SOCKET_MAXSOCKETS;i++) {
40                socketlist[i].conn_ptr=0;
41                socketlist[i].flags = 0;
42        }
43}
44
45 // spawn/kill socket for internal use ONLY.
46int spawn_socket(int flags) {
47   int s;
48   SGIP_INTR_PROTECT();
49   for(s=0;s<SGIP_SOCKET_MAXSOCKETS;s++) if(!(socketlist[s].flags&SGIP_SOCKET_FLAG_ACTIVE)) break;
50   if(s==SGIP_SOCKET_MAXSOCKETS) {
51      SGIP_INTR_UNPROTECT();
52      return SGIP_ERROR(ENOMEM);
53   }
54   socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | flags;
55   socketlist[s].conn_ptr=0;
56   SGIP_INTR_UNPROTECT();
57   return s+1;
58}
59int kill_socket(int s) {
60   if(s<1 || s>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
61   SGIP_INTR_PROTECT();
62   s--;
63   socketlist[s].conn_ptr=0;
64   socketlist[s].flags=0;
65   SGIP_INTR_UNPROTECT();
66   return 0;
67}
68
69int socket(int domain, int type, int protocol) {
70        int s;
71        if(domain!=AF_INET) return SGIP_ERROR(EINVAL);
72        if(protocol!=0) return SGIP_ERROR(EINVAL);
73        if(type!=SOCK_DGRAM && type!=SOCK_STREAM) return SGIP_ERROR(EINVAL);
74        SGIP_INTR_PROTECT();
75        for(s=0;s<SGIP_SOCKET_MAXSOCKETS;s++) if(!(socketlist[s].flags&SGIP_SOCKET_FLAG_ACTIVE)) break;
76   if(s==SGIP_SOCKET_MAXSOCKETS) {
77      SGIP_INTR_UNPROTECT();
78      return SGIP_ERROR(ENOMEM);
79   }
80        if(type==SOCK_STREAM) {
81                socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_TCP;
82                socketlist[s].conn_ptr=sgIP_TCP_AllocRecord();
83        } else if(type==SOCK_DGRAM) {
84                socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_UDP;
[32b8506]85                socketlist[s].conn_ptr=sgIP_UDP_AllocRecord();
[311dfa6]86        } else {
87                SGIP_INTR_UNPROTECT();
88                return SGIP_ERROR(EINVAL);
89        }
90#ifdef SGIP_SOCKET_DEFAULT_NONBLOCK
91        socketlist[s].flags|=SGIP_SOCKET_FLAG_NONBLOCKING;
92#endif
93        SGIP_INTR_UNPROTECT();
94        return s+1;
95}
96
97
98int closesocket(int socket) {
99        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
100        SGIP_INTR_PROTECT();
101        socket--;
102        if(!(socketlist[socket].flags&SGIP_SOCKET_FLAG_ACTIVE)) { SGIP_INTR_UNPROTECT(); return 0; }
103        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
104                sgIP_TCP_FreeRecord((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
105        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
106                sgIP_UDP_FreeRecord((sgIP_Record_UDP *)socketlist[socket].conn_ptr);
107        }
108        socketlist[socket].conn_ptr=0;
109        socketlist[socket].flags=0;
110        SGIP_INTR_UNPROTECT();
111        return 0;
112}
113
114int bind(int socket, const struct sockaddr * addr, int addr_len) {
115        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
116   if(addr_len!=sizeof(struct sockaddr_in)) return SGIP_ERROR(EINVAL);
117        SGIP_INTR_PROTECT();
118        int retval=SGIP_ERROR(EINVAL);
119        socket--;
120        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
121      retval=sgIP_TCP_Bind((sgIP_Record_TCP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_port,((struct sockaddr_in *)addr)->sin_addr.s_addr);
122        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
123                retval=sgIP_UDP_Bind((sgIP_Record_UDP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_port,((struct sockaddr_in *)addr)->sin_addr.s_addr);
124        }
125        SGIP_INTR_UNPROTECT();
126        return retval;
127}
128int connect(int socket, const struct sockaddr * addr, int addr_len) {
129   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
130   if(addr_len!=sizeof(struct sockaddr_in)) return SGIP_ERROR(EINVAL);
131   SGIP_INTR_PROTECT();
132   int i;
133   int retval=SGIP_ERROR(EINVAL);
134   socket--;
135   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
136      retval=sgIP_TCP_Connect((sgIP_Record_TCP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_addr.s_addr,((struct sockaddr_in *)addr)->sin_port);
137          if(retval==0) {
138                do {
139                        i=((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->tcpstate;
140                        if(i==SGIP_TCP_STATE_ESTABLISHED || i==SGIP_TCP_STATE_CLOSE_WAIT) {retval=0; break;}
[32b8506]141                        if(i==SGIP_TCP_STATE_CLOSED || i==SGIP_TCP_STATE_UNUSED || i==SGIP_TCP_STATE_LISTEN || i==SGIP_TCP_STATE_NODATA)
[311dfa6]142                        {       retval=SGIP_ERROR(((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->errorcode); break; }
143                        if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
144                        SGIP_INTR_UNPROTECT();
145                        SGIP_WAITEVENT();
146                        SGIP_INTR_REPROTECT();
147                } while(1);
148          }
149   }
150   SGIP_INTR_UNPROTECT();
151   return retval;
152}
153int send(int socket, const void * data, int sendlength, int flags) {
154   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
155   SGIP_INTR_PROTECT();
156   int retval=SGIP_ERROR(EINVAL);
157   socket--;
158   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
159       do {
160           retval=sgIP_TCP_Send((sgIP_Record_TCP *)socketlist[socket].conn_ptr,data,sendlength,flags);
161           if(retval!=-1) break;
162           if(errno!=EWOULDBLOCK) break;
163           if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
164           SGIP_INTR_UNPROTECT();
165           SGIP_WAITEVENT();
166           SGIP_INTR_REPROTECT();
167       } while(1);
168   }
169   SGIP_INTR_UNPROTECT();
170   return retval;
171}
172int recv(int socket, void * data, int recvlength, int flags) {
173   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
174   SGIP_INTR_PROTECT();
175   int retval=SGIP_ERROR(EINVAL);
176   socket--;
177   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
178      do {
179         retval=sgIP_TCP_Recv((sgIP_Record_TCP *)socketlist[socket].conn_ptr,data,recvlength,flags);
180         if(retval!=-1) break;
181         if(errno!=EWOULDBLOCK) break;
182         if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
183         SGIP_INTR_UNPROTECT();
184         SGIP_WAITEVENT();
185         SGIP_INTR_REPROTECT();
186      } while(1);
187   }
188   SGIP_INTR_UNPROTECT();
189   return retval;
190}
191int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len) {
192        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
193        if(!addr) return -1;
194        SGIP_INTR_PROTECT();
195        int retval=SGIP_ERROR(EINVAL);
196        socket--;
197        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
198        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
199                retval=sgIP_UDP_SendTo((sgIP_Record_UDP *)socketlist[socket].conn_ptr,data,sendlength,flags,((struct sockaddr_in *)addr)->sin_addr.s_addr,((struct sockaddr_in *)addr)->sin_port);
200        }
201        SGIP_INTR_UNPROTECT();
202        return retval;
203}
204int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len) {
205        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
206        if(!addr) return -1;
207        SGIP_INTR_PROTECT();
208        int retval=SGIP_ERROR(EINVAL);
209        socket--;
210        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
211        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
212      do {
213         retval=sgIP_UDP_RecvFrom((sgIP_Record_UDP *)socketlist[socket].conn_ptr,data,recvlength,flags,&(((struct sockaddr_in *)addr)->sin_addr.s_addr),&(((struct sockaddr_in *)addr)->sin_port));
214         if(retval!=-1) break;
215         if(errno!=EWOULDBLOCK) break;
216         if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
217         SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
218         SGIP_WAITEVENT(); // don't just try again immediately
219         SGIP_INTR_REPROTECT();
220      } while(1);
221                *addr_len = sizeof(struct sockaddr_in);
222        }
223        SGIP_INTR_UNPROTECT();
224        return retval;
225}
226int listen(int socket, int max_connections) {
227   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
228   SGIP_INTR_PROTECT();
229   int retval=SGIP_ERROR(EINVAL);
230   socket--;
231   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
232      retval=sgIP_TCP_Listen((sgIP_Record_TCP *)socketlist[socket].conn_ptr,max_connections);
233   }
234   SGIP_INTR_UNPROTECT();
235   return retval;
236}
237int accept(int socket, struct sockaddr * addr, int * addr_len) {
238   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS || !addr || !addr_len) return SGIP_ERROR(EINVAL);
239   SGIP_INTR_PROTECT();
240   sgIP_Record_TCP * ret;
241   int retval,s;
242   retval=SGIP_ERROR0(EINVAL);
243   ret=0;
244   socket--;
245   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
246      s=spawn_socket((socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) | SGIP_SOCKET_FLAG_TYPE_TCP);
247      if(s>0) {
248         do {
249            ret=sgIP_TCP_Accept((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
250            if(ret!=0) break;
251            if(errno!=EWOULDBLOCK) break;
252            if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
253            SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
254            SGIP_WAITEVENT(); // don't just try again immediately
255            SGIP_INTR_REPROTECT();
256         } while(1);
257      }
258      if(ret==0) {
259         kill_socket(s);
260         retval=-1;
261      } else {
262                 *addr_len=sizeof(struct sockaddr_in);
263                 ((struct sockaddr_in *)addr)->sin_family=AF_INET;
264                 ((struct sockaddr_in *)addr)->sin_port=ret->destport;
265                 ((struct sockaddr_in *)addr)->sin_addr.s_addr=ret->destip;
266         socketlist[s-1].conn_ptr=ret;
267         retval=s;
268      }
269   }
270   SGIP_INTR_UNPROTECT();
271   return retval;
272}
273int shutdown(int socket, int shutdown_type) {
274   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
275   SGIP_INTR_PROTECT();
276   int retval=SGIP_ERROR(EINVAL);
277   socket--;
278   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
279           retval=sgIP_TCP_Close((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
280   }
281   SGIP_INTR_UNPROTECT();
282   return retval;
283}
284
285int ioctl(int socket, long cmd, void * arg) {
286        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
287        socket--;
288        int retval,i;
289        retval=0;
290        SGIP_INTR_PROTECT();
291        switch(cmd) {
292        case FIONBIO:
293                if(!arg){
294                        retval=SGIP_ERROR(EINVAL);
295                } else {
296                        socketlist[socket].flags &= ~SGIP_SOCKET_FLAG_NONBLOCKING;
297                        if(*((unsigned long *)arg)) socketlist[socket].flags |= SGIP_SOCKET_FLAG_NONBLOCKING;
298                }
299                break;
300        case FIONREAD:
301                if(!arg) {
302                        retval=SGIP_ERROR(EINVAL);
303                } else {
304                        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
305                                i=((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->buf_rx_out-((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->buf_rx_in;
306                                if(i<0) i+=SGIP_TCP_RECEIVEBUFFERLENGTH;
307                                *((int *)arg)=i;
308                        } else {
309                                retval=SGIP_ERROR(EINVAL);
310                        }
311                }
312        }
313        SGIP_INTR_UNPROTECT();
314        return retval;
315}
316
317int setsockopt(int socket, int level, int option_name, const void * data, int data_len) {
318   return 0;
[32b8506]319}
[311dfa6]320int getsockopt(int socket, int level, int option_name, void * data, int * data_len) {
321   return 0;
322}
323
324int getpeername(int socket, struct sockaddr *addr, int * addr_len) {
325        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
326        if(!addr || !addr_len) return SGIP_ERROR(EFAULT);
327        if(*addr_len<sizeof(struct sockaddr_in)) return SGIP_ERROR(EFAULT);
328        socket--;
329        SGIP_INTR_PROTECT();
330        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
331                {
332                        struct sockaddr_in * sain = (struct sockaddr_in *)addr;
333                        sgIP_Record_TCP * rec = (sgIP_Record_TCP *)socketlist[socket].conn_ptr;
334                        if(rec->tcpstate!=SGIP_TCP_STATE_ESTABLISHED) {
335                                SGIP_INTR_UNPROTECT();
336                                return SGIP_ERROR(ENOTCONN);
337                        } else {
338                                sain->sin_addr.s_addr=rec->destip;
339                                sain->sin_family=AF_INET;
340                                sain->sin_port=rec->destport;
341                                *addr_len=sizeof(struct sockaddr_in);
342                        }
343                }
344        } else {
345                SGIP_INTR_UNPROTECT();
346                return SGIP_ERROR(EOPNOTSUPP);
347        }
348        SGIP_INTR_UNPROTECT();
349        return 0;
350}
351int getsockname(int socket, struct sockaddr *addr, int * addr_len) {
352        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
353        if(!addr || !addr_len) return SGIP_ERROR(EFAULT);
354        if(*addr_len<sizeof(struct sockaddr_in)) return SGIP_ERROR(EFAULT);
355        socket--;
356        SGIP_INTR_PROTECT();
357        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
358                {
359                        struct sockaddr_in * sain = (struct sockaddr_in *)addr;
360                        sgIP_Record_TCP * rec = (sgIP_Record_TCP *)socketlist[socket].conn_ptr;
361                        if(rec->tcpstate==SGIP_TCP_STATE_UNUSED || rec->tcpstate==SGIP_TCP_STATE_CLOSED) {
362                                SGIP_INTR_UNPROTECT();
363                                return SGIP_ERROR(EINVAL);
364                        } else {
365                                sain->sin_addr.s_addr=rec->srcip;
366                                sain->sin_family=AF_INET;
367                                sain->sin_port=rec->srcport;
368                                *addr_len=sizeof(struct sockaddr_in);
369                        }
370                }
371        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
372        {
373            struct sockaddr_in * sain = (struct sockaddr_in *)addr;
374            sgIP_Record_UDP * rec = (sgIP_Record_UDP *)socketlist[socket].conn_ptr;
375            if(rec->state==SGIP_UDP_STATE_UNUSED) {
376                SGIP_INTR_UNPROTECT();
377                return SGIP_ERROR(EINVAL);
378            } else {
379                sain->sin_addr.s_addr=rec->srcip;
380                sain->sin_family=AF_INET;
381                sain->sin_port=rec->srcport;
382                *addr_len=sizeof(struct sockaddr_in);
383            }
384        }
385        } else {
386                SGIP_INTR_UNPROTECT();
387                return SGIP_ERROR(EOPNOTSUPP);
388        }
389        SGIP_INTR_UNPROTECT();
390        return 0;
391}
392
393
394struct hostent * gethostbyname(const char * name) {
395   return (struct hostent *)sgIP_DNS_gethostbyname(name);
396};
397
398
[14876018]399extern int select(int nfds, fd_set *__restrict readfds, fd_set *__restrict writefds,
400                  fd_set *__restrict errorfds, struct timeval *__restrict timeout) {
[311dfa6]401        // 31 days = 2678400 seconds
402        unsigned long timeout_ms, lasttime, temp;
403        sgIP_Record_TCP * rec;
404        sgIP_Record_UDP * urec;
405        lasttime=sgIP_timems;
406        if(!timeout) timeout_ms=2678400000UL;
407        else {
408                if(timeout->tv_sec>=2678400) {
409                        timeout_ms=2678400000UL;
410                } else {
411                        timeout_ms=timeout->tv_sec*1000 + (timeout->tv_usec/1000);
412                }
413        }
414        SGIP_INTR_PROTECT();
415        nfds=SGIP_SOCKET_MAXSOCKETS;
416
417        int i,j,retval;
418        while(timeout_ms>0) { // check all fd sets
419                // readfds
420                if(readfds) {
421                        for(i=0;i<nfds;i++) {
422                                if(FD_ISSET(i+1,readfds)) {
423                                        if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
424                                                rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
425                                                if(rec->buf_rx_in!=rec->buf_rx_out) { timeout_ms=0; break; }
426                                        } else if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
427                                                urec = (sgIP_Record_UDP *)socketlist[i].conn_ptr;
428                                                if(urec->incoming_queue) { timeout_ms=0; break; }
429                                        }
430                                }
431                        }
432                        if(timeout_ms==0) break;
433                }
434                if(writefds) {
435                        // writefds
436                        for(i=0;i<nfds;i++) {
437                                if(FD_ISSET(i+1,writefds)) {
438                                        if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
439                                                rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
440                                                j=rec->buf_tx_in-1;
441                                                if(j<0) j=SGIP_TCP_TRANSMITBUFFERLENGTH-1;
442                                                if(rec->buf_tx_in!=j) { timeout_ms=0; break; }
443                                        }
444                                }
445                        }
446                        if(timeout_ms==0) break;
447                }
448                // errorfds
449                // ignore errorfds for now.
450
451                temp=sgIP_timems-lasttime;
452                if(timeout_ms<temp) timeout_ms=0; else timeout_ms -= temp;
453                lasttime+=temp;
454                SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
455                SGIP_WAITEVENT(); // don't just try again immediately
456                SGIP_INTR_REPROTECT();
457        }
458        // markup fd sets and return
459        // readfds
460        retval=0;
461        if(readfds) {
462                for(i=0;i<nfds;i++) {
463                        if(FD_ISSET(i+1,readfds)) {
464                                if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
465                                        rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
466                                        if(rec->buf_rx_in==rec->buf_rx_out) { FD_CLR(i+1,readfds);} else retval++;
467                                } else if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
468                                        urec = (sgIP_Record_UDP *)socketlist[i].conn_ptr;
469                                        if(!urec->incoming_queue) { FD_CLR(i+1,readfds);} else retval++;
470                                }
471                        }
472                }
473        }
474
475        // writefds
476        if(writefds) {
477                for(i=0;i<nfds;i++) {
478                        if(FD_ISSET(i+1,writefds)) {
479                                if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
480                                        rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
481                                        j=rec->buf_tx_in-1;
482                                        if(j<0) j=SGIP_TCP_TRANSMITBUFFERLENGTH-1;
483                                        if(rec->buf_tx_in==j) { FD_CLR(i+1,writefds); } else retval++;
484                                }
485                        }
486                }
487        }
488
489        if(errorfds) { FD_ZERO(errorfds); }
490
491        SGIP_INTR_UNPROTECT();
492        return retval;
493}
494
495
496/*
497extern void FD_CLR(int fd, fd_set * fdset) {
498        if(fd<1 || fd>FD_SETSIZE || !fdset) return;
499        fd--;
500        fdset->fdbits[fd>>5] &= ~(1<<(fd&31));
501}
502extern int FD_ISSET(int fd, fd_set * fdset) {
503        if(fd<1 || fd>FD_SETSIZE || !fdset) return 0;
504        fd--;
505        return (fdset->fdbits[fd>>5] & 1<<(fd&31))?1:0;
506}
507extern void FD_SET(int fd, fd_set * fdset) {
508        if(fd<1 || fd>FD_SETSIZE || !fdset) return;
509        fd--;
510        fdset->fdbits[fd>>5] |= 1<<(fd&31);
511}
512extern void FD_ZERO(fd_set * fdset) {
513        int i;
514        if(!fdset) return;
515        for(i=0;i<(FD_SETSIZE+31)/32;i++) {
516                fdset->fdbits[i]=0;
517        }
518}
519*/
520
521
Note: See TracBrowser for help on using the repository browser.