In every example and discussion I run across in the context of BSD socket programming, it seems that the recommended way to set a file descriptor to nonblocking I/O mode is using the O_NONBLOCK
flag to fcntl()
, e.g.
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
I've been doing network programming in UNIX for over ten years, and have always used the FIONBIO ioctl()
call to do this:
int opt = 1;
ioctl(fd, FIONBIO, &opt);
Never really gave much thought to why. Just learned it that way.
Does anyone have any commentary on the possible respective merits of one or the other? I imagine the portability locus differs somewhat, but do not know to what extent as ioctl_list(2)
doesn't speak to that aspect of individual ioctl
methods.
This question is related to
c
network-programming
unix
sockets
As @Sean said, fcntl()
is largely standardized, and therefore available across platforms. The ioctl()
function predates fcntl()
in Unix, but is not standardized at all. That the ioctl()
worked for you across all the platforms of relevance to you is fortunate, but not guaranteed. In particular, the names used for the second argument are arcane and not reliable across platforms. Indeed, they are often unique to the particular device driver that the file descriptor references. (The ioctl()
calls used for a bit-mapped graphics device running on an ICL Perq running PNX (Perq Unix) of twenty years ago never translated to anything else anywhere else, for example.)
I believe fcntl()
is a POSIX function. Where as ioctl()
is a standard UNIX thing. Here is a list of POSIX io. ioctl()
is a very kernel/driver/OS specific thing, but i am sure what you use works on most flavors of Unix. some other ioctl()
stuff might only work on certain OS or even certain revs of it's kernel.
Source: Stackoverflow.com