diff options
Diffstat (limited to 'src/unistd')
-rw-r--r-- | src/unistd/dup3.c | 6 | ||||
-rw-r--r-- | src/unistd/faccessat.c | 2 | ||||
-rw-r--r-- | src/unistd/pipe2.c | 1 | ||||
-rw-r--r-- | src/unistd/pwrite.c | 11 | ||||
-rw-r--r-- | src/unistd/pwritev.c | 10 | ||||
-rw-r--r-- | src/unistd/setxid.c | 2 |
6 files changed, 27 insertions, 5 deletions
diff --git a/src/unistd/dup3.c b/src/unistd/dup3.c index f919f791..40798bde 100644 --- a/src/unistd/dup3.c +++ b/src/unistd/dup3.c @@ -9,12 +9,14 @@ int __dup3(int old, int new, int flags) int r; #ifdef SYS_dup2 if (old==new) return __syscall_ret(-EINVAL); - if (flags & O_CLOEXEC) { + if (flags) { while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY); if (r!=-ENOSYS) return __syscall_ret(r); + if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL); } while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); - if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC); + if (r >= 0 && (flags & O_CLOEXEC)) + __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC); #else while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY); #endif diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c index 557503eb..43052dd7 100644 --- a/src/unistd/faccessat.c +++ b/src/unistd/faccessat.c @@ -53,7 +53,7 @@ int faccessat(int fd, const char *filename, int amode, int flag) if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret)) ret = -EBUSY; __syscall(SYS_close, p[0]); - __syscall(SYS_wait4, pid, &status, __WCLONE, 0); + __sys_wait4(pid, &status, __WCLONE, 0); __restore_sigs(&set); diff --git a/src/unistd/pipe2.c b/src/unistd/pipe2.c index f24f74fb..a096990b 100644 --- a/src/unistd/pipe2.c +++ b/src/unistd/pipe2.c @@ -8,6 +8,7 @@ int pipe2(int fd[2], int flag) if (!flag) return pipe(fd); int ret = __syscall(SYS_pipe2, fd, flag); if (ret != -ENOSYS) return __syscall_ret(ret); + if (flag & ~(O_CLOEXEC|O_NONBLOCK)) return __syscall_ret(-EINVAL); ret = pipe(fd); if (ret) return ret; if (flag & O_CLOEXEC) { diff --git a/src/unistd/pwrite.c b/src/unistd/pwrite.c index 869b69f0..a008b3ec 100644 --- a/src/unistd/pwrite.c +++ b/src/unistd/pwrite.c @@ -1,7 +1,18 @@ +#define _GNU_SOURCE #include <unistd.h> +#include <sys/uio.h> +#include <fcntl.h> #include "syscall.h" ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, + (&(struct iovec){ .iov_base = (void *)buf, .iov_len = size }), + 1, (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs)); } diff --git a/src/unistd/pwritev.c b/src/unistd/pwritev.c index becf9deb..44a53d85 100644 --- a/src/unistd/pwritev.c +++ b/src/unistd/pwritev.c @@ -1,10 +1,18 @@ -#define _BSD_SOURCE +#define _GNU_SOURCE #include <sys/uio.h> #include <unistd.h> +#include <fcntl.h> #include "syscall.h" ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, iov, count, + (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwritev, fd, iov, count, (long)(ofs), (long)(ofs>>32)); } diff --git a/src/unistd/setxid.c b/src/unistd/setxid.c index 487c1a16..a629ed4b 100644 --- a/src/unistd/setxid.c +++ b/src/unistd/setxid.c @@ -30,5 +30,5 @@ int __setxid(int nr, int id, int eid, int sid) * trigger the safety kill above. */ struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .ret = 1 }; __synccall(do_setxid, &c); - return __syscall_ret(c.ret); + return __syscall_ret(c.ret > 0 ? -EAGAIN : c.ret); } |