OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * This file defines various POSIX-like functions directly using Linux | 8 * This file defines various POSIX-like functions directly using Linux |
9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which | 9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which |
10 * defines functions using NaCl syscalls directly. | 10 * defines functions using NaCl syscalls directly. |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" | 28 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" |
29 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" | 29 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" |
30 #include "native_client/src/nonsfi/linux/linux_syscalls.h" | 30 #include "native_client/src/nonsfi/linux/linux_syscalls.h" |
31 #include "native_client/src/public/linux_syscalls/poll.h" | 31 #include "native_client/src/public/linux_syscalls/poll.h" |
32 #include "native_client/src/public/linux_syscalls/sys/prctl.h" | 32 #include "native_client/src/public/linux_syscalls/sys/prctl.h" |
33 #include "native_client/src/public/linux_syscalls/sys/socket.h" | 33 #include "native_client/src/public/linux_syscalls/sys/socket.h" |
34 #include "native_client/src/untrusted/nacl/getcwd.h" | 34 #include "native_client/src/untrusted/nacl/getcwd.h" |
35 #include "native_client/src/untrusted/nacl/tls.h" | 35 #include "native_client/src/untrusted/nacl/tls.h" |
36 | 36 |
37 | 37 |
| 38 /* Used in openat() and fstatat(). */ |
| 39 #define LINUX_AT_FDCWD (-100) |
| 40 |
38 /* | 41 /* |
39 * Note that Non-SFI NaCl uses a 4k page size, in contrast to SFI NaCl's | 42 * Note that Non-SFI NaCl uses a 4k page size, in contrast to SFI NaCl's |
40 * 64k page size. | 43 * 64k page size. |
41 */ | 44 */ |
42 static const int kPageSize = 0x1000; | 45 static const int kPageSize = 0x1000; |
43 | 46 |
44 static uintptr_t errno_value_call(uintptr_t result) { | 47 static uintptr_t errno_value_call(uintptr_t result) { |
45 if (linux_is_error_result(result)) { | 48 if (linux_is_error_result(result)) { |
46 errno = -result; | 49 errno = -result; |
47 return -1; | 50 return -1; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 int read(int fd, void *buf, size_t count) { | 171 int read(int fd, void *buf, size_t count) { |
169 return errno_value_call(linux_syscall3(__NR_read, fd, | 172 return errno_value_call(linux_syscall3(__NR_read, fd, |
170 (uintptr_t) buf, count)); | 173 (uintptr_t) buf, count)); |
171 } | 174 } |
172 | 175 |
173 int write(int fd, const void *buf, size_t count) { | 176 int write(int fd, const void *buf, size_t count) { |
174 return errno_value_call(linux_syscall3(__NR_write, fd, | 177 return errno_value_call(linux_syscall3(__NR_write, fd, |
175 (uintptr_t) buf, count)); | 178 (uintptr_t) buf, count)); |
176 } | 179 } |
177 | 180 |
178 int open(char const *pathname, int oflag, ...) { | 181 int open(const char *pathname, int oflag, ...) { |
179 mode_t cmode; | 182 mode_t cmode; |
180 va_list ap; | |
181 | 183 |
182 if (oflag & O_CREAT) { | 184 oflag = nacl_oflags_to_linux_oflags(oflag); |
| 185 if (oflag == -1) { |
| 186 errno = EINVAL; |
| 187 return -1; |
| 188 } |
| 189 |
| 190 if (oflag & LINUX_O_CREAT) { |
| 191 va_list ap; |
183 va_start(ap, oflag); | 192 va_start(ap, oflag); |
184 cmode = va_arg(ap, mode_t); | 193 cmode = va_arg(ap, mode_t); |
185 va_end(ap); | 194 va_end(ap); |
186 } else { | 195 } else { |
187 cmode = 0; | 196 cmode = 0; |
188 } | 197 } |
189 | 198 |
190 return errno_value_call( | 199 return errno_value_call( |
191 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); | 200 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); |
192 } | 201 } |
193 | 202 |
| 203 int openat(int dirfd, const char *pathname, int oflag, ...) { |
| 204 mode_t cmode; |
| 205 |
| 206 if (dirfd == AT_FDCWD) |
| 207 dirfd = LINUX_AT_FDCWD; |
| 208 |
| 209 oflag = nacl_oflags_to_linux_oflags(oflag); |
| 210 if (oflag == -1) { |
| 211 errno = EINVAL; |
| 212 return -1; |
| 213 } |
| 214 |
| 215 if (oflag & LINUX_O_CREAT) { |
| 216 va_list ap; |
| 217 va_start(ap, oflag); |
| 218 cmode = va_arg(ap, mode_t); |
| 219 va_end(ap); |
| 220 } else { |
| 221 cmode = 0; |
| 222 } |
| 223 |
| 224 return errno_value_call( |
| 225 linux_syscall4(__NR_openat, dirfd, (uintptr_t) pathname, oflag, cmode)); |
| 226 } |
| 227 |
194 int close(int fd) { | 228 int close(int fd) { |
195 return errno_value_call(linux_syscall1(__NR_close, fd)); | 229 return errno_value_call(linux_syscall1(__NR_close, fd)); |
196 } | 230 } |
197 | 231 |
198 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { | 232 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { |
199 uint32_t offset_low = (uint32_t) offset; | 233 uint32_t offset_low = (uint32_t) offset; |
200 uint32_t offset_high = offset >> 32; | 234 uint32_t offset_high = offset >> 32; |
201 #if defined(__i386__) | 235 #if defined(__i386__) |
202 return errno_value_call( | 236 return errno_value_call( |
203 linux_syscall5(__NR_pread64, fd, (uintptr_t) buf, count, | 237 linux_syscall5(__NR_pread64, fd, (uintptr_t) buf, count, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 int lstat(const char *file, struct stat *st) { | 313 int lstat(const char *file, struct stat *st) { |
280 struct linux_abi_stat64 linux_st; | 314 struct linux_abi_stat64 linux_st; |
281 int rc = errno_value_call( | 315 int rc = errno_value_call( |
282 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); | 316 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); |
283 if (rc == -1) | 317 if (rc == -1) |
284 return -1; | 318 return -1; |
285 linux_stat_to_nacl_stat(&linux_st, st); | 319 linux_stat_to_nacl_stat(&linux_st, st); |
286 return 0; | 320 return 0; |
287 } | 321 } |
288 | 322 |
| 323 int fstatat(int dirfd, const char *file, struct stat *st, int flags) { |
| 324 struct linux_abi_stat64 linux_st; |
| 325 if (dirfd == AT_FDCWD) |
| 326 dirfd = LINUX_AT_FDCWD; |
| 327 int rc = errno_value_call(linux_syscall4( |
| 328 __NR_fstatat64, dirfd, (uintptr_t) file, (uintptr_t) &linux_st, flags)); |
| 329 if (rc == -1) |
| 330 return -1; |
| 331 linux_stat_to_nacl_stat(&linux_st, st); |
| 332 return 0; |
| 333 } |
| 334 |
289 int mkdir(const char *path, mode_t mode) { | 335 int mkdir(const char *path, mode_t mode) { |
290 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); | 336 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); |
291 } | 337 } |
292 | 338 |
293 int rmdir(const char *path) { | 339 int rmdir(const char *path) { |
294 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); | 340 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); |
295 } | 341 } |
296 | 342 |
297 int chdir(const char *path) { | 343 int chdir(const char *path) { |
298 return errno_value_call(linux_syscall1(__NR_chdir, (uintptr_t) path)); | 344 return errno_value_call(linux_syscall1(__NR_chdir, (uintptr_t) path)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 linux_syscall2(__NR_access, (uintptr_t) path, amode)); | 402 linux_syscall2(__NR_access, (uintptr_t) path, amode)); |
357 } | 403 } |
358 | 404 |
359 int readlink(const char *path, char *buf, int bufsize) { | 405 int readlink(const char *path, char *buf, int bufsize) { |
360 return errno_value_call( | 406 return errno_value_call( |
361 linux_syscall3(__NR_readlink, (uintptr_t) path, | 407 linux_syscall3(__NR_readlink, (uintptr_t) path, |
362 (uintptr_t) buf, bufsize)); | 408 (uintptr_t) buf, bufsize)); |
363 } | 409 } |
364 | 410 |
365 int fcntl(int fd, int cmd, ...) { | 411 int fcntl(int fd, int cmd, ...) { |
366 if (cmd == F_GETFL || cmd == F_GETFD) { | 412 if (cmd == F_GETFD) { |
367 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); | 413 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
368 } | 414 } |
369 if (cmd == F_SETFL || cmd == F_SETFD) { | 415 if (cmd == F_GETFL) { |
| 416 int rc = errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
| 417 if (rc == -1) |
| 418 return -1; |
| 419 return linux_oflags_to_nacl_oflags(rc); |
| 420 } |
| 421 if (cmd == F_SETFD) { |
370 va_list ap; | 422 va_list ap; |
371 va_start(ap, cmd); | 423 va_start(ap, cmd); |
372 int32_t arg = va_arg(ap, int32_t); | 424 int32_t arg = va_arg(ap, int32_t); |
373 va_end(ap); | 425 va_end(ap); |
374 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); | 426 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
375 } | 427 } |
| 428 if (cmd == F_SETFL) { |
| 429 va_list ap; |
| 430 va_start(ap, cmd); |
| 431 int32_t arg = va_arg(ap, int32_t); |
| 432 va_end(ap); |
| 433 arg = nacl_oflags_to_linux_oflags(arg); |
| 434 if (arg == -1) { |
| 435 errno = EINVAL; |
| 436 return -1; |
| 437 } |
| 438 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
| 439 } |
376 /* We only support the fcntl commands above. */ | 440 /* We only support the fcntl commands above. */ |
377 errno = EINVAL; | 441 errno = EINVAL; |
378 return -1; | 442 return -1; |
379 } | 443 } |
380 | 444 |
381 int getpid(void) { | 445 int getpid(void) { |
382 return errno_value_call(linux_syscall0(__NR_getpid)); | 446 return errno_value_call(linux_syscall0(__NR_getpid)); |
383 } | 447 } |
384 | 448 |
385 int fork(void) { | 449 int fork(void) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 | 667 |
604 void *nacl_tls_get(void) { | 668 void *nacl_tls_get(void) { |
605 void *result; | 669 void *result; |
606 #if defined(__i386__) | 670 #if defined(__i386__) |
607 __asm__("mov %%gs:0, %0" : "=r"(result)); | 671 __asm__("mov %%gs:0, %0" : "=r"(result)); |
608 #elif defined(__arm__) | 672 #elif defined(__arm__) |
609 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); | 673 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); |
610 #endif | 674 #endif |
611 return result; | 675 return result; |
612 } | 676 } |
OLD | NEW |