diff options
author | Vladimir Azarov <avm@intermediate-node.net> | 2024-10-01 15:47:05 +0200 |
---|---|---|
committer | Vladimir Azarov <avm@intermediate-node.net> | 2024-10-01 15:47:05 +0200 |
commit | 4abab5ad6c8465a7528ccdd5f49367da05f78bbd (patch) | |
tree | ebf009bf1376a5a223a915bc27cbbd791a1316bc /src/fcntl |
Initial version
Diffstat (limited to 'src/fcntl')
-rw-r--r-- | src/fcntl/creat.c | 6 | ||||
-rw-r--r-- | src/fcntl/fcntl.c | 48 | ||||
-rw-r--r-- | src/fcntl/open.c | 21 | ||||
-rw-r--r-- | src/fcntl/openat.c | 17 | ||||
-rw-r--r-- | src/fcntl/posix_fadvise.c | 16 | ||||
-rw-r--r-- | src/fcntl/posix_fallocate.c | 8 |
6 files changed, 116 insertions, 0 deletions
diff --git a/src/fcntl/creat.c b/src/fcntl/creat.c new file mode 100644 index 0000000..c9c4391 --- /dev/null +++ b/src/fcntl/creat.c @@ -0,0 +1,6 @@ +#include <fcntl.h> + +int creat(const char *filename, mode_t mode) +{ + return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode); +} diff --git a/src/fcntl/fcntl.c b/src/fcntl/fcntl.c new file mode 100644 index 0000000..d3bff5c --- /dev/null +++ b/src/fcntl/fcntl.c @@ -0,0 +1,48 @@ +#define _GNU_SOURCE +#include <fcntl.h> +#include <stdarg.h> +#include <errno.h> +#include "syscall.h" + +int fcntl(int fd, int cmd, ...) +{ + unsigned long arg; + va_list ap; + va_start(ap, cmd); + arg = va_arg(ap, unsigned long); + va_end(ap); + if (cmd == F_SETFL) arg |= O_LARGEFILE; + if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg); + if (cmd == F_GETOWN) { + struct f_owner_ex ex; + int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); + if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg); + if (ret) return __syscall_ret(ret); + return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; + } + if (cmd == F_DUPFD_CLOEXEC) { + int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); + if (ret != -EINVAL) { + if (ret >= 0) + __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); + return __syscall_ret(ret); + } + ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0); + if (ret != -EINVAL) { + if (ret >= 0) __syscall(SYS_close, ret); + return __syscall_ret(-EINVAL); + } + ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg); + if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); + return __syscall_ret(ret); + } + switch (cmd) { + case F_SETLK: + case F_GETLK: + case F_GETOWN_EX: + case F_SETOWN_EX: + return syscall(SYS_fcntl, fd, cmd, (void *)arg); + default: + return syscall(SYS_fcntl, fd, cmd, arg); + } +} diff --git a/src/fcntl/open.c b/src/fcntl/open.c new file mode 100644 index 0000000..4c3c827 --- /dev/null +++ b/src/fcntl/open.c @@ -0,0 +1,21 @@ +#include <fcntl.h> +#include <stdarg.h> +#include "syscall.h" + +int open(const char *filename, int flags, ...) +{ + mode_t mode = 0; + + if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } + + int fd = __sys_open_cp(filename, flags, mode); + if (fd>=0 && (flags & O_CLOEXEC)) + __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); + + return __syscall_ret(fd); +} diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c new file mode 100644 index 0000000..83a9e0d --- /dev/null +++ b/src/fcntl/openat.c @@ -0,0 +1,17 @@ +#include <fcntl.h> +#include <stdarg.h> +#include "syscall.h" + +int openat(int fd, const char *filename, int flags, ...) +{ + mode_t mode = 0; + + if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } + + return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode); +} diff --git a/src/fcntl/posix_fadvise.c b/src/fcntl/posix_fadvise.c new file mode 100644 index 0000000..07346d2 --- /dev/null +++ b/src/fcntl/posix_fadvise.c @@ -0,0 +1,16 @@ +#include <fcntl.h> +#include "syscall.h" + +int posix_fadvise(int fd, off_t base, off_t len, int advice) +{ +#if defined(SYSCALL_FADVISE_6_ARG) + /* Some archs, at least arm and powerpc, have the syscall + * arguments reordered to avoid needing 7 argument registers + * due to 64-bit argument alignment. */ + return -__syscall(SYS_fadvise, fd, advice, + __SYSCALL_LL_E(base), __SYSCALL_LL_E(len)); +#else + return -__syscall(SYS_fadvise, fd, __SYSCALL_LL_O(base), + __SYSCALL_LL_E(len), advice); +#endif +} diff --git a/src/fcntl/posix_fallocate.c b/src/fcntl/posix_fallocate.c new file mode 100644 index 0000000..80a65cb --- /dev/null +++ b/src/fcntl/posix_fallocate.c @@ -0,0 +1,8 @@ +#include <fcntl.h> +#include "syscall.h" + +int posix_fallocate(int fd, off_t base, off_t len) +{ + return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base), + __SYSCALL_LL_E(len)); +} |