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