This article needs additional citations for verification .(March 2020) |
select is a system call and application programming interface (API) in Unix-like and POSIX-compliant operating systems for examining the status of file descriptors of open input/output channels. [1] The select system call is similar to the poll facility introduced in UNIX System V and later operating systems. However, with the c10k problem, both select and poll have been superseded by the likes of kqueue, epoll, /dev/poll and I/O completion ports. [2]
One common use of select outside of its stated use of waiting on filehandles is to implement a portable sub-second sleep. This can be achieved by passing NULL for all three fd_set arguments, and the duration of the desired sleep as the timeout argument.
In the C programming language, the select system call is declared in the header file sys/select.h or unistd.h, and has the following syntax:
intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*errorfds,structtimeval*timeout);
Argument | Description |
---|---|
nfds | This is an integer one more than the maximum of any file descriptor in any of the sets. In other words, while adding file descriptors to each of the sets, you must calculate the maximum integer value of all of them, then increment this value by one, and then pass this as nfds. |
readfds | fd_set type holding the file descriptors to be checked for being ready to read, and on output indicates which file descriptors are ready to read. Can be NULL. |
writefds | fd_set type holding the file descriptors to be checked for being ready to write, and on output indicates which file descriptors are ready to write. Can be NULL. |
errorfds | fd_set type holding the file descriptors to be checked for error conditions pending, and on output indicates which file descriptors have error conditions pending. Can be NULL. |
timeout | Structure of type struct timeval that specifies a maximum interval to wait for the selection to complete. If the timeout argument points to an object of type struct timeval whose members are 0, select() does not block. If the timeout argument is NULL, select() blocks until an event causes one of the masks to be returned with a valid (non-zero) value. Linux will update the timeout in place to indicate how much time was elapsed, though this behavior is not shared by most other Unix systems. |
fd_set type
arguments may be manipulated with four utility macros: FD_SET(), FD_CLR(), FD_ZERO(), and FD_ISSET().
Select returns the total number of bits set in readfds, writefds and errorfds, or zero if the timeout expired, and -1 on error.
The sets of file descriptor used in select are finite in size, depending on the operating system. The newer system call poll provides a more flexible solution.
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<sys/select.h>#include<fcntl.h>#include<unistd.h>#include<err.h>#include<errno.h>#define PORT "9421"/* function prototypes */voiddie(constchar*);intmain(intargc,char**argv){intsockfd,new,maxfd,on=1,nready,i;structaddrinfo*res0,*res,hints;charbuffer[BUFSIZ];fd_setmaster,readfds;interror;ssize_tnbytes;(void)memset(&hints,'\0',sizeof(structaddrinfo));hints.ai_family=AF_INET;hints.ai_socktype=SOCK_STREAM;hints.ai_protocol=IPPROTO_TCP;hints.ai_flags=AI_PASSIVE;if(0!=(error=getaddrinfo(NULL,PORT,&hints,&res0)))errx(EXIT_FAILURE,"%s",gai_strerror(error));for(res=res0;res;res=res->ai_next){if(-1==(sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol))){perror("socket()");continue;}if(-1==(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(int)))){perror("setsockopt()");continue;}if(-1==(bind(sockfd,res->ai_addr,res->ai_addrlen))){perror("bind()");continue;}break;}if(-1==sockfd)exit(EXIT_FAILURE);freeaddrinfo(res0);if(-1==(listen(sockfd,32)))die("listen()");if(-1==(fcntl(sockfd,F_SETFD,O_NONBLOCK)))die("fcntl()");FD_ZERO(&master);FD_ZERO(&readfds);FD_SET(sockfd,&master);maxfd=sockfd;while(1){memcpy(&readfds,&master,sizeof(master));(void)printf("running select()\n");if(-1==(nready=select(maxfd+1,&readfds,NULL,NULL,NULL)))die("select()");(void)printf("Number of ready descriptor: %d\n",nready);for(i=0;i<=maxfd&&nready>0;i++){if(FD_ISSET(i,&readfds)){nready--;if(i==sockfd){(void)printf("Trying to accept() new connection(s)\n");if(-1==(new=accept(sockfd,NULL,NULL))){if(EWOULDBLOCK!=errno)die("accept()");break;}else{if(-1==(fcntl(new,F_SETFD,O_NONBLOCK)))die("fcntl()");FD_SET(new,&master);if(maxfd<new)maxfd=new;}}else{(void)printf("recv() data from one of descriptors(s)\n");nbytes=recv(i,buffer,sizeof(buffer),0);if(nbytes<=0){if(EWOULDBLOCK!=errno)die("recv()");break;}buffer[nbytes]='\0';printf("%s",buffer);(void)printf("%zi bytes received.\n",nbytes);close(i);FD_CLR(i,&master);}}}}return0;}voiddie(constchar*msg){perror(msg);exit(EXIT_FAILURE);}
A Berkeley (BSD) socket is an application programming interface (API) for Internet domain sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly implemented as a library of linkable modules. It originated with the 4.2BSD Unix operating system, which was released in 1983.
The C programming language provides many standard library functions for file input and output. These functions make up the bulk of the C standard library header <stdio.h>. The functionality descends from a "portable I/O package" written by Mike Lesk at Bell Labs in the early 1970s, and officially became part of the Unix operating system in Version 7.
The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.
In computing, mmap(2)
is a POSIX-compliant Unix system call that maps files or devices into memory. It is a method of memory-mapped file I/O. It implements demand paging because file contents are not immediately read from disk and initially use no physical RAM at all. The actual reads from disk are performed after a specific location is accessed, in a lazy manner. After the mapping is no longer needed, the pointers must be unmapped with munmap(2)
. Protection information—for example, marking mapped regions as executable—can be managed using mprotect(2)
, and special treatment can be enforced using madvise(2)
.
In computing, vectored I/O, also known as scatter/gather I/O, is a method of input and output by which a single procedure call sequentially reads data from multiple buffers and writes it to a single data stream (gather), or reads data from a data stream and writes it to multiple buffers (scatter), as defined in a vector of buffers. Scatter/gather refers to the process of gathering data from, or scattering data into, the given set of buffers. Vectored I/O can operate synchronously or asynchronously. The main reasons for using vectored I/O are efficiency and convenience.
stat is a Unix system call that returns file attributes about an inode. The semantics of stat vary between operating systems. As an example, Unix command ls uses this system call to retrieve information on files that includes:
In computing, an uninitialized variable is a variable that is declared but is not set to a definite known value before it is used. It will have some value, but not a predictable one. As such, it is a programming error and a common source of bugs in software.
In computing, sigaction
is a function API defined by POSIX to give the programmer access to what a program's behavior should be when receiving specific OS signals.
In C programming, the functions getaddrinfo and getnameinfo convert domain names, hostnames, and IP addresses between human-readable text representations and structured binary formats for the operating system's networking API. Both functions are contained in the POSIX standard application programming interface (API).
In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook.
sizeof is a unary operator in the programming languages C and C++. It generates the storage size of an expression or a data type, measured in the number of char-sized units. Consequently, the construct sizeof (char) is guaranteed to be 1. The actual number of bits of type char is specified by the preprocessor macro CHAR_BIT, defined in the standard include file limits.h. On most modern computing platforms this is eight bits. The result of sizeof has an unsigned integer type that is usually denoted by size_t.
In client-server computing, a Unix domain socket is a Berkeley socket that allows data to be exchanged between two processes executing on the same Unix or Unix-like host computer. This is similar to an Internet domain socket that allows data to be exchanged between two processes executing on different host computers.
splice is a Linux-specific system call that moves data between a file descriptor and a pipe without a round trip to user space. The related system call vmsplice moves or copies data between a pipe and user space. Ideally, splice and vmsplice work by remapping pages and do not actually copy any data, which may improve I/O performance. As linear addresses do not necessarily correspond to contiguous physical addresses, this may not be possible in all cases and on all hardware combinations.
setcontext is one of a family of C library functions used for context control. The setcontext
family allows the implementation in C of advanced control flow patterns such as iterators, fibers, and coroutines. They may be viewed as an advanced version of setjmp/longjmp; whereas the latter allows only a single non-local jump up the stack, setcontext
allows the creation of multiple cooperative threads of control, each with its own stack.
setjmp.h is a header defined in the C standard library to provide "non-local jumps": control flow that deviates from the usual subroutine call and return sequence. The complementary functions setjmp
and longjmp
provide this functionality.
In computing, the producer-consumer problem is a family of problems described by Edsger W. Dijkstra since 1965.
SocketCAN is a set of open source CAN drivers and a networking stack contributed by Volkswagen Research to the Linux kernel. SocketCAN was formerly known as Low Level CAN Framework (LLCF).
Kqueue is a scalable event notification interface introduced in FreeBSD 4.1 in July 2000, also supported in NetBSD, OpenBSD, DragonFly BSD, and macOS. Kqueue was originally authored in 2000 by Jonathan Lemon, then involved with the FreeBSD Core Team. Kqueue makes it possible for software like nginx to solve the c10k problem. The term "kqueue" refers to its function as a "kernel event queue"
Getopt is a C library function used to parse command-line options of the Unix/POSIX style. It is a part of the POSIX specification, and is universal to Unix-like systems. It is also the name of a Unix program for parsing command line arguments in shell scripts.
can4linux is an open-source CAN Linux-Kernel device driver. Development started in the mid-1990s for the Philips 82C200 CAN controller stand alone chip on an ISA Board AT-CAN-MINI. In 1995 the first version was created to use the CAN bus with Linux for laboratory automation as a project of the Linux Lab Project at FU Berlin.
select(2)
in FreeBSD, NetBSD, OpenBSD and DragonFly BSD