#include <cafe.h>
#include <cafe/network.h>

FD_CLR(fd, fd_set *fdset);

FD_COPY(fd_set *fdset_orig, fd_set *fdset_copy);

FD_ISSET(fd, fd_set *fdset);

FD_SET(fd, fd_set *fdset);

FD_ZERO(fd_set *fdset);

int SOSelect(int nfds, fd_set *readfds, fd_set *writefds,
             fd_set *exceptfds, struct timeval *timeout);


nfds Specifies the maximum number of sockets to check. Descriptors from 0 to nfds-1 in every descriptor set are checked.
readfds Descriptor set for read events.
writefds Descriptor set for write events.
exceptfds Descriptor set for exception events.
timeout Time to wait in select.

Return Values

positive value The number of ready sockets that are contained in the descriptor sets.
0 Timeout occurred before any descriptor was ready.
SOCKET_ERROR An error occurred. Use SOError to get the error number whenever an error occurs.


SO_ELIBNOTREADY Socket library is not initialized.
SO_ENOMEM Insufficient memory in the stack.
SO_EINVAL The specified time limit is invalid, one of its components is too large (larger than 999999) or negative, or nfds is greater than FD_SETSIZE.
SO_EBADF One of the descriptor sets specified an invalid descriptor.
SO_ENORESOURCES Could not obtain system resources to proceed (e.g. when a multithreaded application makes more than 16 concurrent SOSelect calls, from different threads)
SO_EBUSY Socket resource manager busy processing requests.
SO_EABORTED Indicates the operation was aborted. For example, this error can be returned for calls blocked on a socket after the socket is closed by another thread.
SO_EUNKNOWN Unknown error.
SO_ERANGEINVALID Internal API error, invalid error code.
SO_EAPIERROR Internal API error.


SOSelect allows a program to monitor multiple socket descriptors, waiting until one or more of the socket descriptors becomes ready for some class of I/O operation. A descriptor is considered ready if it is possible to perform socket operations like SORecv, SORecvFrom, SOSend, SOSendTo, SOConnect, SOAccept without blocking.

Five macros are provided to manipulate sets.

FD_CLR Removes given descriptor from a set.
FD_COPY Copies set (&fdset_orig) to another allocated set (&fdset_copy).
FD_ISSET Tests to see if a descriptor is part of the set. This is used to test the results of sets after SOSelect returns.
FD_SET Sets given descriptor to a set.
FD_ZERO Clears the fd set.

The nfds parameter specifies the highest number of the descriptor in any of the three sets, plus 1.

The timeout value is passed using the timeval structure pointer. SOSelect will block until the timeout has expired if no descriptor is ready. If any descriptor passed into the fd set becomes ready before the timeout, SOSelect returns immediately.

SOSelect provides a timeout resolution of 10 milliseconds.

Passing a timeout structure with a value of 0 causes SOSelect to return immediately with current readiness state for each descriptor. This functionality can be used by applications to implement a polling mechanism.

A NULL timeout value indicates that SOSelect will block indefinitely unless one of the descriptors from the sets becomes ready.

Passing a NULL descriptor sets with a timeout of either NULL or 0 will cause SOSelect to return an SO_EINVAL error.

Passing negative or larger than 999999 as a value for timeout components (tv_sec or tv_usec) will cause SOSelect to return SO_EINVAL error.

A multi-threaded application can make maximum up to 16 concurrent SOSelect calls (from different threads). SOSelect returns SO_ENORESOURCES if the application exceeds this limit.

If SOSelect is called with a NULL timeout and the associated descriptors are aborted by the system (e.g. when the network link is lost), SOSelect will set exceptfds and return the number of sockets contained. Corresponding sockets are no longer valid and this should be treated the same as receiving SO_EABORTED; sockets should be closed and recreated.

Do Not Call From

Callbacks Do not call this function from any callback function.
Interrupt handler Do not call this function from any interrupt handler.
Exception handler Do not call this function from any exception handler.

Revision History

2013/12/10 Added the description of the behavior upon socket abort.
2012/10/09 Added Errors section.
2012/08/16 Cleanup pass.
2011/09/22 Fixed typo and format.
2011/02/21 Initial version.