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..b7172948facb732ce6550448fd52fe6ad53c6345 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; |
| + } |
| + |
| + 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) { |
|
Mark Seaborn
2014/11/27 16:12:17
What in sandbox/linux/ requires using F_GETFL? Ca
hidehiko
2014/11/28 16:58:15
Used in some places at least in ipc_channel_posix.
Mark Seaborn
2014/12/08 22:09:02
So this is needed for ipc/ rather than for the sec
hidehiko
2014/12/09 08:38:48
Why it is working now is because the flags used by
|
| + 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; |
| @@ -411,6 +467,16 @@ int pipe(int pipefd[2]) { |
| return errno_value_call(linux_syscall1(__NR_pipe, (uintptr_t) pipefd)); |
| } |
| +int pipe2(int pipefd[2], int flags) { |
|
Mark Seaborn
2014/11/27 16:12:17
Same here -- what uses pipe2()? Is it something w
hidehiko
2014/11/28 16:58:15
Good catch. It was removed very recently, after th
|
| + flags = nacl_oflags_to_linux_oflags(flags); |
| + if (flags == -1) { |
| + errno = EINVAL; |
| + return -1; |
| + } |
| + return errno_value_call( |
| + linux_syscall2(__NR_pipe2, (uintptr_t) pipefd, flags)); |
| +} |
| + |
| int poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
| return errno_value_call( |
| linux_syscall3(__NR_poll, (uintptr_t) fds, nfds, timeout)); |