summaryrefslogtreecommitdiff
path: root/src/fcntl/fcntl.c
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-02-09 13:14:01 -0500
committerJakob Kaivo <jkk@ung.org>2019-02-09 13:14:01 -0500
commit253a32e2f9ff1cbb8edbe7c79834a678daebeb93 (patch)
tree599cf5baf01c6dae33a2f89989b08b7d553f7fd0 /src/fcntl/fcntl.c
parent88d0b5e7ffbf0554b236dc46225846061b5f4817 (diff)
merge POSIX.1-1988/1990
Diffstat (limited to 'src/fcntl/fcntl.c')
-rw-r--r--src/fcntl/fcntl.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/fcntl/fcntl.c b/src/fcntl/fcntl.c
new file mode 100644
index 00000000..18288776
--- /dev/null
+++ b/src/fcntl/fcntl.c
@@ -0,0 +1,61 @@
+#include "sys/types.h"
+#include <fcntl.h>
+#include "errno.h"
+#include "stdarg.h"
+#include "nonstd/types.h"
+#include "nonstd/syscall.h"
+
+int fcntl(int fildes, int cmd, ...)
+{
+ SCNO(scno, "fcntl", -1);
+
+ int r = -ENOSYS;
+ enum { NONE, INT, FLOCK } arg = NONE;
+
+ switch (cmd) {
+ case F_GETFD:
+ case F_GETFL:
+ break;
+
+ case F_DUPFD:
+ case F_SETFD:
+ case F_SETFL:
+ arg = INT;
+ break;
+
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ arg = FLOCK;
+ break;
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (arg == NONE) {
+ r = __libc.syscall(scno, fildes);
+ } else {
+ va_list ap;
+ va_start(ap, cmd);
+ if (arg == INT) {
+ int n = va_arg(ap, int);
+ r = __libc.syscall(scno, fildes, n);
+ } else if (arg == FLOCK) {
+ struct flock *fl = va_arg(ap, struct flock *);
+ r = __libc.syscall(scno, fildes, fl);
+ }
+ va_end(ap);
+ }
+
+ if (r < 0) {
+ errno = -r;
+ return -1;
+ }
+
+ return r;
+}
+/*
+POSIX(1)
+*/