Updated: April 19, 2023 |
Check for files that are ready for reading or writing or have an exceptional condition pending
#include <sys/select.h> int select( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout ); int pselect( int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timespec * restrict timeout, const sigset_t * restrict sigmask ); FD_SET( int fd, fd_set * fdset ); FD_CLR( int fd, fd_set * fdset ); FD_ISSET( int fd, fd_set * fdset ); FD_ZERO( fd_set * fdset );
(highest valued file descriptor in the sets) + 1
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The select() function examines the file descriptor sets whose addresses are passed in readfds, writefds, and exceptfds to see if some of their descriptors are ready for reading, ready for writing, or have an exceptional condition pending. Any of readfds, writefds, and exceptfds may be NULL pointers if no descriptors are of interest.
The pselect() function is similar to select(); if sigmask isn't NULL, pselect() replaces the caller's signal mask with the set of signals pointed to by sigmask before examining the descriptors, and restores the caller's signal mask before returning. Calling pselect() with a sigmask of NULL is the same as calling select(). Both select() and pselect() are implemented using poll().
The QNX Neutrino implementation of select() is built on top of ionotify(). Generally, you use ionotify() if you want to combine input from file descriptors with QNX Neutrino messaging in the same process. Use select() when you're handling multiple file descriptors from sockets, pipes, serial ports, and so on.
The select() function replaces the given descriptor sets with subsets consisting of those descriptors that are ready for the requested operation, and returns the total number of ready descriptors in all the sets.
If timeout isn't NULL, it specifies a maximum interval to wait for the selection to complete. If timeout is NULL, select() blocks until one of the selected conditions occurs. To effect a poll, the timeout argument should be a non-NULL pointer, pointing to a zero-valued timeval or timespec structure.
FD_SETSIZE specifies the highest file descriptor number that the fd_set structure supports and must be set to one more than the highest file descriptor number that the fd_set objects use. Its default value is 256.
If you use select() with a timeout, you should reset the timeout value after calling select().
Manipulating file-descriptor sets
At least the following macros are defined in <sys/select.h> for manipulating file-descriptor sets:
The behavior of these macros is undefined if a descriptor value is less than zero, or greater than or equal to FD_SETSIZE.
The number of ready descriptors in the descriptor sets, 0 if the timeout expired, or -1 if an error occurs (errno is set).
/* * This example opens a console and a serial port for * read mode, and calls select() with a 5 second timeout. * It waits for data to be available on either descriptor. */ #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/select.h> int main( void ) { int console, serial; struct timeval tv; fd_set rfd; int n; if( ( console = open( "/dev/con1", O_RDONLY ) ) == -1 || ( serial = open( "/dev/ser1", O_RDONLY ) ) == -1 ) { perror( "open" ); return EXIT_FAILURE; } /* * Clear the set of read file descriptors, and * add the two we just got from the open calls. */ FD_ZERO( &rfd ); FD_SET( console, &rfd ); FD_SET( serial, &rfd ); /* * Set a 5 second timeout. */ tv.tv_sec = 5; tv.tv_usec = 0; switch ( n = select( 1 + max( console, serial ), &rfd, 0, 0, &tv ) ) { case -1: perror( "select" ); return EXIT_FAILURE; case 0: puts( "select timed out" ); break; default: printf( "%d descriptors ready ...\n", n ); if( FD_ISSET( console, &rfd ) ) puts( " -- console descriptor has data pending" ); if( FD_ISSET( serial, &rfd ) ) puts( " -- serial descriptor has data pending" ); } return EXIT_SUCCESS; }
Safety: | |
---|---|
Cancellation point | Yes |
Interrupt handler | No |
Signal handler | No |
Thread | Read the Caveats |
The select() function works only with raw file descriptors; it doesn't work with file descriptors in edited mode. See the ICANON flag in the description of the tcgetattr() function.
The select() function is thread safe as long as the fd sets used by each thread point to memory that is specific to that thread.
In QNX Neutrino, if multiple threads block in select() on the same fd for the same condition, all threads may unblock when the condition is satisfied. This may differ from other implementations where only one thread may unblock.