#ifdef HAVE_CONFIG_H #include #endif #include #include #include "../internal/syscall.h" /* * fcntl over SYS_fcntl (72). The third argument is read from the varargs * only for the commands POSIX defines one for (F_DUPFD, F_DUPFD_CLOEXEC, * F_SETFD, F_SETFL, the lock commands, and the owner/signal commands); * every other command passes 0, which the kernel ignores. Pointers (the * struct flock * of F_GETLK/F_SETLK/F_SETLKW/F_OFD_*) ride the varargs * slot as a long — on x86_64 long and void * share one GPR slot, so the * read is ABI-exact. * * F_DUPFD_CLOEXEC passes straight through: the x86_64 kernel has supported * it as a single native operation since 2.6.24, so no F_DUPFD + F_SETFD * fallback is needed. F_SETFL needs no O_LARGEFILE massaging on x86_64 * (that is a 32-bit compat concern only). */ int fcntl(int fildes, int cmd, ...) { long arg = 0; va_list ap; switch (cmd) { case F_DUPFD: case F_DUPFD_CLOEXEC: case F_SETFD: case F_SETFL: case F_GETLK: case F_SETLK: case F_SETLKW: case F_SETOWN: case F_SETSIG: case F_GETOWN_EX: case F_SETOWN_EX: case F_OFD_GETLK: case F_OFD_SETLK: case F_OFD_SETLKW: va_start(ap, cmd); arg = va_arg(ap, long); va_end(ap); break; default: break; } return syscall_ret(__syscall3(SYS_fcntl, fildes, cmd, arg)); }