Chromium Code Reviews| Index: src/nonsfi/linux/linux_sys_private.c |
| diff --git a/src/nonsfi/linux/linux_sys_private.c b/src/nonsfi/linux/linux_sys_private.c |
| index e1beac0411063d28de21a0daf18bdf057494f834..b9e6752cdae3b5d574e3749897c1a2701557864c 100644 |
| --- a/src/nonsfi/linux/linux_sys_private.c |
| +++ b/src/nonsfi/linux/linux_sys_private.c |
| @@ -174,11 +174,17 @@ int write(int fd, const void *buf, size_t count) { |
| (uintptr_t) buf, count)); |
| } |
| -int open(char const *pathname, int oflag, ...) { |
| +int open(const char *pathname, int oflag, ...) { |
| mode_t cmode; |
| - va_list ap; |
| - if (oflag & O_CREAT) { |
| + oflag = nacl_oflags_to_linux_oflags(oflag); |
| + if (oflag == -1) { |
| + errno = EINVAL; |
| + return -1; |
| + } |
| + |
| + if (oflag & LINUX_O_CREAT) { |
| + va_list ap; |
| va_start(ap, oflag); |
| cmode = va_arg(ap, mode_t); |
| va_end(ap); |
| @@ -190,6 +196,28 @@ int open(char const *pathname, int oflag, ...) { |
| linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); |
| } |
| +int openat(int dirfd, const char *pathname, int oflag, ...) { |
| + mode_t cmode; |
| + |
| + oflag = nacl_oflags_to_linux_oflags(oflag); |
| + if (oflag == -1) { |
| + errno = EINVAL; |
| + return -1; |
| + } |
| + |
| + if (oflag & LINUX_O_CREAT) { |
| + va_list ap; |
| + va_start(ap, oflag); |
| + cmode = va_arg(ap, mode_t); |
| + va_end(ap); |
| + } else { |
| + cmode = 0; |
|
hamaji
2014/12/03 08:51:19
Any reason you don't call linux_syscall3 here? I'm
hidehiko
2014/12/03 17:34:49
what do you mean? I just write a code consistent w
hamaji
2014/12/08 07:38:39
I didn't realize this is consistent with open(). I
|
| + } |
| + |
|
hamaji
2014/12/03 08:51:19
Shouldn't we convert NACL_ABI_AT_FDCWD to AT_FDCWD
hidehiko
2014/12/03 17:34:49
As its value is same among NaCl, x86 and arm ABIs,
hidehiko
2014/12/04 16:23:30
Ah, no, my bad. AT_FDCWD is different value, thoug
|
| + return errno_value_call( |
| + linux_syscall4(__NR_openat, dirfd, (uintptr_t) pathname, oflag, cmode)); |
| +} |
| + |
| int close(int fd) { |
| return errno_value_call(linux_syscall1(__NR_close, fd)); |
| } |
| @@ -285,6 +313,16 @@ int lstat(const char *file, struct stat *st) { |
| return 0; |
| } |
| +int fstatat(int dirfd, const char *file, struct stat *st, int flags) { |
| + struct linux_abi_stat64 linux_st; |
| + int rc = errno_value_call(linux_syscall4( |
| + __NR_fstatat64, dirfd, (uintptr_t) file, (uintptr_t) &linux_st, flags)); |
| + if (rc == -1) |
| + return -1; |
| + linux_stat_to_nacl_stat(&linux_st, st); |
| + return 0; |
| +} |
| + |
| int mkdir(const char *path, mode_t mode) { |
| return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); |
| } |
| @@ -362,16 +400,34 @@ int readlink(const char *path, char *buf, int bufsize) { |
| } |
| int fcntl(int fd, int cmd, ...) { |
| - if (cmd == F_GETFL || cmd == F_GETFD) { |
| + if (cmd == F_GETFD) { |
| return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
| } |
| - if (cmd == F_SETFL || cmd == F_SETFD) { |
| + if (cmd == F_GETFL) { |
| + int rc = errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
| + if (rc == -1) |
| + return -1; |
| + return linux_oflags_to_nacl_oflags(rc); |
| + } |
| + if (cmd == F_SETFD) { |
| va_list ap; |
| va_start(ap, cmd); |
| int32_t arg = va_arg(ap, int32_t); |
| va_end(ap); |
| return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
| } |
| + if (cmd == F_SETFL) { |
| + va_list ap; |
| + va_start(ap, cmd); |
| + int32_t arg = va_arg(ap, int32_t); |
| + va_end(ap); |
| + arg = nacl_oflags_to_linux_oflags(arg); |
| + if (arg == -1) { |
| + errno = EINVAL; |
| + return -1; |
| + } |
| + return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
| + } |
| /* We only support the fcntl commands above. */ |
| errno = EINVAL; |
| return -1; |