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; |