| OLD | NEW |
| 1 #define _GNU_SOURCE | 1 #define _GNU_SOURCE |
| 2 #include <fcntl.h> | 2 #include <fcntl.h> |
| 3 #include <stdarg.h> | 3 #include <stdarg.h> |
| 4 #include <errno.h> | 4 #include <errno.h> |
| 5 #include "syscall.h" | 5 #include "syscall.h" |
| 6 #include "libc.h" | 6 #include "libc.h" |
| 7 | 7 |
| 8 int fcntl(int fd, int cmd, ...) | 8 int fcntl(int fd, int cmd, ...) { |
| 9 { | 9 unsigned long arg; |
| 10 » unsigned long arg; | 10 va_list ap; |
| 11 » va_list ap; | 11 va_start(ap, cmd); |
| 12 » va_start(ap, cmd); | 12 arg = va_arg(ap, unsigned long); |
| 13 » arg = va_arg(ap, unsigned long); | 13 va_end(ap); |
| 14 » va_end(ap); | 14 if (cmd == F_SETFL) |
| 15 » if (cmd == F_SETFL) arg |= O_LARGEFILE; | 15 arg |= O_LARGEFILE; |
| 16 » if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg); | 16 if (cmd == F_SETLKW) |
| 17 » if (cmd == F_GETOWN) { | 17 return syscall_cp(SYS_fcntl, fd, cmd, (void*)arg); |
| 18 » » struct f_owner_ex ex; | 18 if (cmd == F_GETOWN) { |
| 19 » » int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); | 19 struct f_owner_ex ex; |
| 20 » » if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *
)arg); | 20 int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); |
| 21 » » if (ret) return __syscall_ret(ret); | 21 if (ret == -EINVAL) |
| 22 » » return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; | 22 return __syscall(SYS_fcntl, fd, cmd, (void*)arg); |
| 23 » } | 23 if (ret) |
| 24 » if (cmd == F_DUPFD_CLOEXEC) { | 24 return __syscall_ret(ret); |
| 25 » » int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); | 25 return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; |
| 26 » » if (ret != -EINVAL) { | 26 } |
| 27 » » » if (ret >= 0) | 27 if (cmd == F_DUPFD_CLOEXEC) { |
| 28 » » » » __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); | 28 int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); |
| 29 » » » return __syscall_ret(ret); | 29 if (ret != -EINVAL) { |
| 30 » » } | 30 if (ret >= 0) |
| 31 » » ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0); | 31 __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); |
| 32 » » if (ret != -EINVAL) { | 32 return __syscall_ret(ret); |
| 33 » » » if (ret >= 0) __syscall(SYS_close, ret); | 33 } |
| 34 » » » return __syscall_ret(-EINVAL); | 34 ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0); |
| 35 » » } | 35 if (ret != -EINVAL) { |
| 36 » » ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg); | 36 if (ret >= 0) |
| 37 » » if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); | 37 __syscall(SYS_close, ret); |
| 38 » » return __syscall_ret(ret); | 38 return __syscall_ret(-EINVAL); |
| 39 » } | 39 } |
| 40 » switch (cmd) { | 40 ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg); |
| 41 » case F_SETLK: | 41 if (ret >= 0) |
| 42 » case F_GETLK: | 42 __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); |
| 43 » case F_GETOWN_EX: | 43 return __syscall_ret(ret); |
| 44 » case F_SETOWN_EX: | 44 } |
| 45 » » return syscall(SYS_fcntl, fd, cmd, (void *)arg); | 45 switch (cmd) { |
| 46 » default: | 46 case F_SETLK: |
| 47 » » return syscall(SYS_fcntl, fd, cmd, arg); | 47 case F_GETLK: |
| 48 » } | 48 case F_GETOWN_EX: |
| 49 case F_SETOWN_EX: |
| 50 return syscall(SYS_fcntl, fd, cmd, (void*)arg); |
| 51 default: |
| 52 return syscall(SYS_fcntl, fd, cmd, arg); |
| 53 } |
| 49 } | 54 } |
| OLD | NEW |