The argument is just an array of unsigned longs, each bit of which represents one file descriptor — there's no magic in there. The add/remove macros just do the typical shift-and-mask style bit twiddling. You can pass a bigger or smaller array than the one in fd_set if you want; TTBOMK the kernel doesn't care. It just looks at the numfds argument to know how large an array you passed in.