librnr  1.14.5
RoadNarrows Robotics Common Library 1
sockset.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Common Library 1
4 //
5 // Library: librnr
6 //
7 // File: sockset.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2010-05-03 13:38:47 -0600 (Mon, 03 May 2010) $
12  * $Rev: 362 $
13  *
14  * \brief Socket Sets services definitions.
15  *
16  * A socket set is composed of three open socket read/write subsets:
17  * <table class="rnr-def">
18  * <tr>
19  * <td>Active</td>
20  * <td>SD's (socked descriptors) active for read/write I/O.</td>
21  * </tr>
22  * <tr>
23  * <td>OnHold</td>
24  * <td>SD's managed but are on hold (not select()'ed).</td>
25  * </tr>
26  * <tr>
27  * <td>Select</td>
28  * <td>The select() working subset. The Active subset is copied into
29  * the Select set and passed into select(). On select()'s return,
30  * the Select set is the subset SD's with I/O events.</td>
31  * </tr>
32  * </table>
33  *
34  * \note
35  * These socket functions were inspired by the <em>camserv</em> socket.c
36  * functions written by Jon Travis (jtravis@p00p.org)
37  *
38  * \author Robin Knight (robin.knight@roadnarrows.com)
39  *
40  * \pkgcopyright{2005-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
41  */
42 //
43 // Permission is hereby granted, without written agreement and without
44 // license or royalty fees, to use, copy, modify, and distribute this
45 // software and its documentation for any purpose, provided that
46 // (1) The above copyright notice and the following two paragraphs
47 // appear in all copies of the source code and (2) redistributions
48 // including binaries reproduces these notices in the supporting
49 // documentation. Substantial modifications to this software may be
50 // copyrighted by their authors and need not follow the licensing terms
51 // described here, provided that the new terms are clearly indicated in
52 // all files where they apply.
53 //
54 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
55 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
56 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
57 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
58 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
59 // THE POSSIBILITY OF SUCH DAMAGE.
60 //
61 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
62 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
63 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
64 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
65 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
66 //
67 ////////////////////////////////////////////////////////////////////////////////
68 
69 #include <sys/types.h>
70 #include <sys/socket.h>
71 #include <netinet/in.h>
72 #include <netdb.h>
73 #include <arpa/inet.h>
74 #include <sys/time.h>
75 #include <unistd.h>
76 #include <errno.h>
77 #include <string.h>
78 
79 #include "rnr/rnrconfig.h"
80 #include "rnr/sock.h"
81 #include "rnr/sockset.h"
82 #include "rnr/log.h"
83 #include "rnr/new.h"
84 
85 
86 // ---------------------------------------------------------------------------
87 // Private Interface
88 // ---------------------------------------------------------------------------
89 
90 
91 PRAGMA_IGNORED(sign-conversion)
92 /*!
93  * \brief FD_SET() wrapper with no annoying warnings.
94  * \param fd File descriptor to add to set.
95  * \param pset Pointer to fd set.
96  */
97 static inline void fdset_nowarn(int fd, fd_set *pset)
98 {
99  FD_SET(fd, pset);
100 }
101 
102 /*!
103  * \brief FD_CLR() wrapper with no annoying warnings.
104  * \param fd File descriptor to add to set.
105  * \param pset Pointer to fd set.
106  */
107 static inline void fdclr_nowarn(int fd, fd_set *pset)
108 {
109  FD_CLR(fd, pset);
110 }
111 
112 /*!
113  * \brief FD_ISSET() wrapper with no annoying warnings.
114  * \param fd File descriptor to add to set.
115  * \param pset Pointer to fd set.
116  * \return Returusn non-zero if set, else zero.
117  */
118 static inline int fdisset_nowarn(int fd, fd_set *pset)
119 {
120  return FD_ISSET(fd, pset);
121 }
122 PRAGMA_WARNING(sign-conversion)
123 
124 PRAGMA_IGNORED(conversion)
125 /*!
126  * \brief ntohs() wrapper with no annoying warnings.
127  * \param huShort Unsigned short integer.
128  * \return Host byte order.
129  */
130 static inline ushort_t ntohs_nowarn(ushort_t huShort)
131 {
132  return ntohs(huShort);
133 }
134 
135 /*!
136  * \brief htons() wrapper with no annoying warnings.
137  * \param huShort Unsigned short integer.
138  * \return Network byte order.
139  */
140 static inline ushort_t htons_nowarn(ushort_t huShort)
141 {
142  return htons(huShort);
143 }
144 PRAGMA_WARNING(conversion)
145 
146 /*!
147  * \brief Socket Set Structure
148  */
149 struct sockset_t
150 {
151  int m_sdHighest; ///< highest socket descriptor value
152  fd_set m_sdSetSelect[SOCK_IO_NUMOF]; ///< select socket descriptor set
153  fd_set m_sdSetActive[SOCK_IO_NUMOF]; ///< active socket descriptor set
154  fd_set m_sdSetOnHold[SOCK_IO_NUMOF]; ///< on-hold socket descriptor set
155  Socket_T *m_pSocket[FD_SETSIZE]; ///< associated sockets
156 };
157 
158 /*!
159  * \brief Find the highest socket descriptor number in the Active subset.
160  *
161  * \param pSockSet Pointer to socket set.
162  *
163  * \return Highest socket descriptor. -1 if none found.
164  */
165 static int SockSetFindHighestSd(SockSet_T *pSockSet)
166 {
167  int sd;
168  int sdHighest;
169 
170  for(sd=0, sdHighest=-1; sd <= pSockSet->m_sdHighest; ++sd)
171  {
172  if( fdisset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_READ]))
173  || fdisset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_WRITE])) )
174  {
175  if( sd > sdHighest )
176  {
177  sdHighest = sd;
178  }
179  }
180  }
181 
182  return sdHighest;
183 }
184 
185 /*!
186  * \brief Check if socket is open and within valid range.
187  *
188  * \param pSocket Pointer to socket.
189  *
190  * \return
191  * Returns socket descriptor if valid.\n
192  * Otherwise the appropriate socket return code < 0 is returned.
193  */
194 static int SockSetChkSd(Socket_T *pSocket)
195 {
196  int sd; // socket descriptor
197 
198  CHKPTR(pSocket, SOCK_RC_EBADSOCK);
199 
200  // this socket isn't open
201  if( !SocketStateIsOpen(pSocket) )
202  {
203  LOGERROR("Socket not open");
204  return SOCK_RC_EBADSD;
205  }
206 
207  sd = SocketAttrGetSd(pSocket);
208 
209  if( sd >= FD_SETSIZE )
210  {
211  LOGERROR("Socket '%s' descriptor %d > %d: too big",
212  SocketAttrGetLocalName(pSocket), sd, FD_SETSIZE);
213  return SOCK_RC_EBADSD;
214  }
215 
216  return sd;
217 }
218 
219 
220 // ---------------------------------------------------------------------------
221 // Public Interface
222 // ---------------------------------------------------------------------------
223 
224 /*!
225  * \brief Allocate a new SockSet.
226  *
227  * \return Pointer to allocated SockSet.
228  */
230 {
231  SockSet_T *pSockSet = NEW(SockSet_T);
232 
233  pSockSet->m_sdHighest = -1;
234 
235  FD_ZERO(&(pSockSet->m_sdSetSelect[SOCK_IO_READ]));
236  FD_ZERO(&(pSockSet->m_sdSetSelect[SOCK_IO_WRITE]));
237  FD_ZERO(&(pSockSet->m_sdSetActive[SOCK_IO_READ]));
238  FD_ZERO(&(pSockSet->m_sdSetActive[SOCK_IO_WRITE]));
239  FD_ZERO(&(pSockSet->m_sdSetOnHold[SOCK_IO_READ]));
240  FD_ZERO(&(pSockSet->m_sdSetOnHold[SOCK_IO_WRITE]));
241 
242  return pSockSet;
243 }
244 
245 /*!
246  * \brief Delete an allocated SockSet.
247  *
248  * \param pSockSet Pointer to SockSet.
249  */
250 void SockSetDelete(SockSet_T *pSockSet)
251 {
252  if( pSockSet == NULL )
253  {
254  return;
255  }
256  delete(pSockSet);
257 }
258 
259 /*!
260  * \brief Add a Socket to a SockSet.
261  *
262  * Socket is added to either the on-hold or active socket set, depending on the
263  * given boolean value.
264  *
265  * \param pSockSet Pointer to SockSet.
266  * \param pSocket Pointer to Socket.
267  * \param bActivateRead Do [not] add to active read set.
268  * \param bActivateWrite Do [not] add to active write set.
269  *
270  * \return Returns OK(0) on success, \h_le 0 on error.
271  */
272 int SockSetAdd(SockSet_T *pSockSet,
273  Socket_T *pSocket,
274  bool_t bActivateRead,
275  bool_t bActivateWrite)
276 {
277  int sd; // socket descriptor
278 
279  CHKPTR(pSockSet, SOCK_RC_EBADSOCK);
280 
281  // Check data and return socket descriptor
282  if( (sd = SockSetChkSd(pSocket)) < 0 )
283  {
284  return sd;
285  }
286 
287  LOGDIAG4CALL(_TPTR(pSockSet), _TSTR(SocketAttrGetLocalName(pSocket)),
288  _TBOOL(bActivateRead), _TBOOL(bActivateWrite));
289 
290  //
291  // Add sd to appropriate read socket descriptor set
292  //
293  if( bActivateRead ) // place read in the active set
294  {
295  fdset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_READ]));
296  if( pSockSet->m_sdHighest < sd )
297  {
298  pSockSet->m_sdHighest = sd;
299  }
300  }
301  else // place read in the on-hold set
302  {
303  fdset_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_READ]));
304  }
305 
306  //
307  // Add sd to appropriate write socket descriptor set
308  //
309  if( bActivateWrite ) // place write in the active set
310  {
311  fdset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_WRITE]));
312  if( pSockSet->m_sdHighest < sd )
313  {
314  pSockSet->m_sdHighest = sd;
315  }
316  }
317  else // place write in the on-hold set
318  {
319  fdset_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_WRITE]));
320  }
321 
322  // add socket
323  pSockSet->m_pSocket[sd] = pSocket;
324 
325  return OK;
326 }
327 
328 /*!
329  * \brief Remove Socket from SockSet.
330  *
331  * \param pSockSet Pointer to SockSet.
332  * \param pSocket Pointer to Socket.
333  *
334  * \return Returns OK(0) on success, \h_le 0 on error.
335  */
336 int SockSetRemove(SockSet_T *pSockSet, Socket_T *pSocket)
337 {
338  int sd; // socket descriptor
339 
340  CHKPTR(pSockSet, SOCK_RC_EBADSOCK);
341 
342  // Check data and return socket descriptor
343  if( (sd = SockSetChkSd(pSocket)) < 0 )
344  {
345  return sd;
346  }
347 
348  LOGDIAG4CALL(_TPTR(pSockSet), _TSTR(SocketAttrGetLocalName(pSocket)));
349 
350  // remove socket descriptor from all sets
351  fdclr_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_READ]));
352  fdclr_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_READ]));
353  fdclr_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_WRITE]));
354  fdclr_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_WRITE]));
355 
356  // remove socket
357  pSockSet->m_pSocket[sd] = NULL;
358 
359  // find new highest socket descriptor
360  pSockSet->m_sdHighest = SockSetFindHighestSd(pSockSet);
361 
362  return OK;
363 }
364 
365 /*!
366  * \brief Activate Socket read/write operations in SockSet.
367  *
368  * Socket is already part of the SockSet.
369  *
370  * \param pSockSet Pointer to SockSet.
371  * \param pSocket Pointer to Socket.
372  * \param bActivateRead Do [not] add to active read set.
373  * \param bActivateWrite Do [not] add to active write set.
374  *
375  * \return Returns OK(0) on success, \h_le 0 on error.
376  */
378  Socket_T *pSocket,
379  bool_t bActivateRead,
380  bool_t bActivateWrite)
381 {
382  int sd; // socket descriptor
383 
384  CHKPTR(pSockSet, SOCK_RC_EBADSOCK);
385 
386  // Check data and return socket descriptor
387  if( (sd = SockSetChkSd(pSocket)) < 0 )
388  {
389  return sd;
390  }
391 
392  if( bActivateRead )
393  {
394  fdclr_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_READ]));
395  fdset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_READ]));
396  if( sd > pSockSet->m_sdHighest )
397  {
398  pSockSet->m_sdHighest = sd;
399  }
400  }
401 
402  if( bActivateWrite )
403  {
404  fdclr_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_WRITE]));
405  fdset_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_WRITE]));
406  if( sd > pSockSet->m_sdHighest )
407  {
408  pSockSet->m_sdHighest = sd;
409  }
410  }
411 
412  pSockSet->m_sdHighest = SockSetFindHighestSd(pSockSet);
413 
414  return OK;
415 }
416 
417 /*!
418  * \brief Put Socket read/write operations in SockSet on hold.
419  *
420  * Socket is already part of the SockSet.
421  *
422  * \param pSockSet Pointer to SockSet.
423  * \param pSocket Pointer to Socket.
424  * \param bHoldRead Do [not] add to hold read set.
425  * \param bHoldWrite Do [not] add to hold write set.
426  *
427  * \return Returns OK(0) on success, \h_le 0 on error.
428  */
430  Socket_T *pSocket,
431  bool_t bHoldRead,
432  bool_t bHoldWrite)
433 {
434  int sd; // socket descriptor
435 
436  CHKPTR(pSockSet, SOCK_RC_EBADSOCK);
437 
438  // Check data and return socket descriptor
439  if( (sd = SockSetChkSd(pSocket)) < 0 )
440  {
441  return sd;
442  }
443 
444  if( bHoldRead )
445  {
446  fdclr_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_READ]));
447  fdset_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_READ]));
448  }
449 
450  if( bHoldWrite )
451  {
452  fdclr_nowarn(sd, &(pSockSet->m_sdSetActive[SOCK_IO_WRITE]));
453  fdset_nowarn(sd, &(pSockSet->m_sdSetOnHold[SOCK_IO_WRITE]));
454  }
455 
456  pSockSet->m_sdHighest = SockSetFindHighestSd(pSockSet);
457 
458  return OK;
459 }
460 
461 /*!
462  * \brief Perform select() on SockSet's Active sets.
463  *
464  * \param pSockSet Pointer to SockSet.
465  * \param pTimeOut Select time out.
466  *
467  * \return
468  * On success, returns number of socket descriptors found in the active state.\n
469  * On time out, returns 0.\n
470  * On error, returns \h_le 0.
471  */
472 int SockSetSelect(SockSet_T *pSockSet, struct timeval *pTimeOut)
473 {
474  struct timeval tvSave = {0, 0}; // saved timeout value
475  int nSd; // number of socket descriptors selected
476  int nTries = 0; // number of tries when interrupted
477 
478  CHKPTR(pSockSet, SOCK_RC_EBADSOCK);
479 
480  // save timeout value - can get munged by select()
481  if( pTimeOut != NULL )
482  {
483  tvSave = *pTimeOut;
484  }
485 
486  //
487  // Try at most three times to select.
488  //
489  while(nTries++ < 3)
490  {
491  // build select read/write sets
492  pSockSet->m_sdSetSelect[SOCK_IO_READ] =
493  pSockSet->m_sdSetActive[SOCK_IO_READ];
494  pSockSet->m_sdSetSelect[SOCK_IO_WRITE] =
495  pSockSet->m_sdSetActive[SOCK_IO_WRITE];
496 
497  //
498  // Wait with timeout (optional) for read/write availability
499  //
500  nSd = select(pSockSet->m_sdHighest+1,
501  &(pSockSet->m_sdSetSelect[SOCK_IO_READ]),
502  &(pSockSet->m_sdSetSelect[SOCK_IO_WRITE]),
503  NULL,
504  pTimeOut);
505 
506  // restore mangled time out
507  if( pTimeOut != NULL )
508  {
509  *pTimeOut = tvSave;
510  }
511 
512  // system error occurred
513  if( nSd < 0 )
514  {
515  switch(errno)
516  {
517  case EINTR: // interrupted - try again
518  break;
519  default:
520  LOGSYSERROR("select()");
521  return SOCK_RC_ESYSERR;
522  }
523  }
524 
525  // read/write sets available or timeout
526  else
527  {
528  return nSd;
529  }
530  }
531 
532  LOGERROR("Failed %d times to select()", nTries);
533 
534  return SOCK_RC_EFAIL;
535 }
536 
537 /*!
538  * \brief Start iteration of Sockets in the given set in SockSet.
539  *
540  * \param pSockSet Pointer to SockSet.
541  * \param eSet One of: \ref SOCK_SET_ONHOLD \ref SOCK_SET_ACTIVE
542  * \ref SOCK_SET_SELECTED.
543  * \param eIO One of: \ref SOCK_IO_READ \ref SOCK_IO_WRITE.
544  * \param pIter SockSet interator.
545  *
546  * \return Pointer to first Socket if found, else NULL.
547  */
549  int eSet,
550  int eIO,
551  SockSetIter_T *pIter)
552 {
553  CHKPTR(pSockSet, NULL);
554  SOCK_SET_CHK_SET(eSet, NULL);
555  SOCK_CHK_IO(eIO, NULL);
556  CHKPTR(pIter, NULL);
557 
558  pIter->m_pSockSet = pSockSet;
559  pIter->m_eSet = eSet;
560  pIter->m_eIO = eIO;
561  pIter->m_sdCur = -1;
562 
563  switch(eSet)
564  {
565  case SOCK_SET_ONHOLD:
566  pIter->m_sdSet = pSockSet->m_sdSetOnHold[eIO];
567  break;
568  case SOCK_SET_ACTIVE:
569  pIter->m_sdSet = pSockSet->m_sdSetActive[eIO];
570  break;
571  case SOCK_SET_SELECTED:
572  default:
573  pIter->m_sdSet = pSockSet->m_sdSetSelect[eIO];
574  break;
575  }
576 
577  return SockSetIterNext(pIter);
578 }
579 
580 /*!
581  * \brief Next Socket in iteration over the initialized socket set of SockSet.
582  *
583  * \param pIter SockSet interator.
584  *
585  * \return Pointer to next Socket if found, else NULL.
586  */
588 {
589  int sd;
590 
591  CHKPTR(pIter, NULL);
592  CHKPTR(pIter->m_pSockSet, NULL);
593 
594  for(sd = pIter->m_sdCur + 1; sd <= pIter->m_pSockSet->m_sdHighest; ++sd)
595  {
596  if( fdisset_nowarn(sd, &(pIter->m_sdSet)) )
597  {
598  pIter->m_sdCur = sd;
599  return pIter->m_pSockSet->m_pSocket[sd];
600  }
601  }
602 
603  // no more selected sockets found
604  pIter->m_sdCur = sd;
605 
606  return NULL;
607 }
#define SOCK_IO_READ
read index
Definition: sock.h:130
#define SOCK_RC_EFAIL
general, unspecified error
Definition: sock.h:119
int SocketAttrGetSd(Socket_T *pSocket)
Get Socket socket (file) descriptor.
Definition: sock.c:735
int m_sdCur
current iterator position
Definition: sockset.h:56
#define SOCK_SET_CHK_SET(set,...)
Check socket set enum.
Definition: sockset.h:72
fd_set m_sdSetActive[SOCK_IO_NUMOF]
active socket descriptor set
Definition: sockset.c:153
Socket Set Structure.
Definition: sockset.c:149
#define CHKPTR(p,...)
Checks validity of pointer.
Definition: log.h:651
#define SOCK_RC_EBADSD
bad/closed socket descriptor
Definition: sock.h:124
const char * SocketAttrGetLocalName(Socket_T *pSocket)
Get Socket local name.
Definition: sock.c:632
#define OK
Okay.
Definition: rnrconfig.h:301
int SockSetSelect(SockSet_T *pSockSet, struct timeval *pTimeOut)
Perform select() on SockSet&#39;s Active sets.
Definition: sockset.c:472
#define NULL
null pointer
Definition: rnrconfig.h:199
#define SOCK_SET_ACTIVE
active socket descriptor set
Definition: sockset.h:64
static int fdisset_nowarn(int fd, fd_set *pset)
FD_ISSET() wrapper with no annoying warnings.
Definition: sockset.c:118
Memory allocation and deallocation declarations.
Socket_T * SockSetIterNext(SockSetIter_T *pIter)
Next Socket in iteration over the initialized socket set of SockSet.
Definition: sockset.c:587
#define PRAGMA_IGNORED(filter)
Disable compiler warnings on the diagnostics filter.
Definition: rnrconfig.h:358
Socket Sets services definitions.
#define LOGSYSERROR(fmt,...)
Standard System Error logging.
Definition: log.h:509
Socket_T * m_pSocket[FD_SETSIZE]
associated sockets
Definition: sockset.c:155
static void fdclr_nowarn(int fd, fd_set *pset)
FD_CLR() wrapper with no annoying warnings.
Definition: sockset.c:107
static int SockSetChkSd(Socket_T *pSocket)
Check if socket is open and within valid range.
Definition: sockset.c:194
#define LOGERROR(fmt,...)
Standard Error logging.
Definition: log.h:488
int SockSetActivate(SockSet_T *pSockSet, Socket_T *pSocket, bool_t bActivateRead, bool_t bActivateWrite)
Activate Socket read/write operations in SockSet.
Definition: sockset.c:377
static ushort_t ntohs_nowarn(ushort_t huShort)
ntohs() wrapper with no annoying warnings.
Definition: sockset.c:130
fd_set m_sdSetOnHold[SOCK_IO_NUMOF]
on-hold socket descriptor set
Definition: sockset.c:154
#define SOCK_SET_SELECTED
post select() selected socket desc. set
Definition: sockset.h:65
#define SOCK_SET_ONHOLD
on-hold socket descriptor set
Definition: sockset.h:63
bool_t SocketStateIsOpen(Socket_T *pSocket)
Check if Socket is open.
Definition: sock.c:888
SockSet_T * m_pSockSet
socket set
Definition: sockset.h:53
int SockSetPutOnHold(SockSet_T *pSockSet, Socket_T *pSocket, bool_t bHoldRead, bool_t bHoldWrite)
Put Socket read/write operations in SockSet on hold.
Definition: sockset.c:429
#define NEW(T)
Allocate new type.
Definition: new.h:49
Socket services declarations.
SockSet_T * SockSetNew()
Allocate a new SockSet.
Definition: sockset.c:229
#define SOCK_RC_EBADSOCK
socket is bad
Definition: sock.h:122
#define SOCK_CHK_IO(io,...)
Check I/O index.
Definition: sock.h:138
int m_eIO
which read/write subset to iterate over
Definition: sockset.h:55
static ushort_t htons_nowarn(ushort_t huShort)
htons() wrapper with no annoying warnings.
Definition: sockset.c:140
fd_set m_sdSet
set to iterate over
Definition: sockset.h:57
int bool_t
"boolean" T/F
Definition: rnrconfig.h:187
RoadNarrows Robotics common configuration file.
#define _TBOOL(var)
boolean
Definition: log.h:588
int SockSetAdd(SockSet_T *pSockSet, Socket_T *pSocket, bool_t bActivateRead, bool_t bActivateWrite)
Add a Socket to a SockSet.
Definition: sockset.c:272
Socket_T * SockSetIterFirst(SockSet_T *pSockSet, int eSet, int eIO, SockSetIter_T *pIter)
Start iteration of Sockets in the given set in SockSet.
Definition: sockset.c:548
#define _TSTR(var)
string variable
Definition: log.h:578
#define SOCK_RC_ESYSERR
system error occurred
Definition: sock.h:125
Definition: sock.c:136
static void fdset_nowarn(int fd, fd_set *pset)
FD_SET() wrapper with no annoying warnings.
Definition: sockset.c:97
#define _TPTR(var)
pointer
Definition: log.h:587
#define LOGDIAG4CALL(...)
Standard Diagnostic Level 4 function call tracing.
Definition: log.h:442
#define PRAGMA_WARNING(filter)
Enable compiler warnings on the diagnostics filter.
Definition: rnrconfig.h:365
fd_set m_sdSetSelect[SOCK_IO_NUMOF]
select socket descriptor set
Definition: sockset.c:152
u16_t ushort_t
16-bit unsigned integer
Definition: rnrconfig.h:179
int SockSetRemove(SockSet_T *pSockSet, Socket_T *pSocket)
Remove Socket from SockSet.
Definition: sockset.c:336
int m_sdHighest
highest socket descriptor value
Definition: sockset.c:151
void SockSetDelete(SockSet_T *pSockSet)
Delete an allocated SockSet.
Definition: sockset.c:250
#define SOCK_IO_NUMOF
number of indices
Definition: sock.h:132
Logger declarations.
#define SOCK_IO_WRITE
write index
Definition: sock.h:131
int m_eSet
which socket set to iterate over
Definition: sockset.h:54
static int SockSetFindHighestSd(SockSet_T *pSockSet)
Find the highest socket descriptor number in the Active subset.
Definition: sockset.c:165