feat(fcntl): fcntl/open flag handling
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#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));
|
||||
}
|
||||
Reference in New Issue
Block a user