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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 int read(int fd, void *buf, size_t count) { | 167 int read(int fd, void *buf, size_t count) { |
168 return errno_value_call(linux_syscall3(__NR_read, fd, | 168 return errno_value_call(linux_syscall3(__NR_read, fd, |
169 (uintptr_t) buf, count)); | 169 (uintptr_t) buf, count)); |
170 } | 170 } |
171 | 171 |
172 int write(int fd, const void *buf, size_t count) { | 172 int write(int fd, const void *buf, size_t count) { |
173 return errno_value_call(linux_syscall3(__NR_write, fd, | 173 return errno_value_call(linux_syscall3(__NR_write, fd, |
174 (uintptr_t) buf, count)); | 174 (uintptr_t) buf, count)); |
175 } | 175 } |
176 | 176 |
177 int open(char const *pathname, int oflag, ...) { | 177 int open(const char *pathname, int oflag, ...) { |
178 mode_t cmode; | 178 mode_t cmode; |
179 va_list ap; | |
180 | 179 |
181 if (oflag & O_CREAT) { | 180 oflag = nacl_oflags_to_linux_oflags(oflag); |
181 if (oflag == -1) { | |
182 errno = EINVAL; | |
183 return -1; | |
184 } | |
185 | |
186 if (oflag & LINUX_O_CREAT) { | |
187 va_list ap; | |
182 va_start(ap, oflag); | 188 va_start(ap, oflag); |
183 cmode = va_arg(ap, mode_t); | 189 cmode = va_arg(ap, mode_t); |
184 va_end(ap); | 190 va_end(ap); |
185 } else { | 191 } else { |
186 cmode = 0; | 192 cmode = 0; |
187 } | 193 } |
188 | 194 |
189 return errno_value_call( | 195 return errno_value_call( |
190 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); | 196 linux_syscall3(__NR_open, (uintptr_t) pathname, oflag, cmode)); |
191 } | 197 } |
192 | 198 |
199 int openat(int dirfd, const char *pathname, int oflag, ...) { | |
200 mode_t cmode; | |
201 | |
202 oflag = nacl_oflags_to_linux_oflags(oflag); | |
203 if (oflag == -1) { | |
204 errno = EINVAL; | |
205 return -1; | |
206 } | |
207 | |
208 if (oflag & LINUX_O_CREAT) { | |
209 va_list ap; | |
210 va_start(ap, oflag); | |
211 cmode = va_arg(ap, mode_t); | |
212 va_end(ap); | |
213 } else { | |
214 cmode = 0; | |
215 } | |
216 | |
217 return errno_value_call( | |
218 linux_syscall4(__NR_openat, dirfd, (uintptr_t) pathname, oflag, cmode)); | |
219 } | |
220 | |
193 int close(int fd) { | 221 int close(int fd) { |
194 return errno_value_call(linux_syscall1(__NR_close, fd)); | 222 return errno_value_call(linux_syscall1(__NR_close, fd)); |
195 } | 223 } |
196 | 224 |
197 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { | 225 ssize_t pread(int fd, void *buf, size_t count, off_t offset) { |
198 uint32_t offset_low = (uint32_t) offset; | 226 uint32_t offset_low = (uint32_t) offset; |
199 uint32_t offset_high = offset >> 32; | 227 uint32_t offset_high = offset >> 32; |
200 #if defined(__i386__) | 228 #if defined(__i386__) |
201 return errno_value_call( | 229 return errno_value_call( |
202 linux_syscall5(__NR_pread64, fd, (uintptr_t) buf, count, | 230 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) { | 306 int lstat(const char *file, struct stat *st) { |
279 struct linux_abi_stat64 linux_st; | 307 struct linux_abi_stat64 linux_st; |
280 int rc = errno_value_call( | 308 int rc = errno_value_call( |
281 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); | 309 linux_syscall2(__NR_lstat64, (uintptr_t) file, (uintptr_t) &linux_st)); |
282 if (rc == -1) | 310 if (rc == -1) |
283 return -1; | 311 return -1; |
284 linux_stat_to_nacl_stat(&linux_st, st); | 312 linux_stat_to_nacl_stat(&linux_st, st); |
285 return 0; | 313 return 0; |
286 } | 314 } |
287 | 315 |
316 int fstatat(int dirfd, const char *file, struct stat *st, int flags) { | |
317 struct linux_abi_stat64 linux_st; | |
318 int rc = errno_value_call(linux_syscall4( | |
319 __NR_fstatat64, dirfd, (uintptr_t) file, (uintptr_t) &linux_st, flags)); | |
320 if (rc == -1) | |
321 return -1; | |
322 linux_stat_to_nacl_stat(&linux_st, st); | |
323 return 0; | |
324 } | |
325 | |
288 int mkdir(const char *path, mode_t mode) { | 326 int mkdir(const char *path, mode_t mode) { |
289 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); | 327 return errno_value_call(linux_syscall2(__NR_mkdir, (uintptr_t) path, mode)); |
290 } | 328 } |
291 | 329 |
292 int rmdir(const char *path) { | 330 int rmdir(const char *path) { |
293 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); | 331 return errno_value_call(linux_syscall1(__NR_rmdir, (uintptr_t) path)); |
294 } | 332 } |
295 | 333 |
296 int chdir(const char *path) { | 334 int chdir(const char *path) { |
297 return errno_value_call(linux_syscall1(__NR_chdir, (uintptr_t) path)); | 335 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)); | 393 linux_syscall2(__NR_access, (uintptr_t) path, amode)); |
356 } | 394 } |
357 | 395 |
358 int readlink(const char *path, char *buf, int bufsize) { | 396 int readlink(const char *path, char *buf, int bufsize) { |
359 return errno_value_call( | 397 return errno_value_call( |
360 linux_syscall3(__NR_readlink, (uintptr_t) path, | 398 linux_syscall3(__NR_readlink, (uintptr_t) path, |
361 (uintptr_t) buf, bufsize)); | 399 (uintptr_t) buf, bufsize)); |
362 } | 400 } |
363 | 401 |
364 int fcntl(int fd, int cmd, ...) { | 402 int fcntl(int fd, int cmd, ...) { |
365 if (cmd == F_GETFL || cmd == F_GETFD) { | 403 if (cmd == F_GETFD) { |
366 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); | 404 return errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); |
367 } | 405 } |
368 if (cmd == F_SETFL || cmd == F_SETFD) { | 406 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
| |
407 int rc = errno_value_call(linux_syscall2(__NR_fcntl64, fd, cmd)); | |
408 if (rc == -1) | |
409 return -1; | |
410 return linux_oflags_to_nacl_oflags(rc); | |
411 } | |
412 if (cmd == F_SETFD) { | |
369 va_list ap; | 413 va_list ap; |
370 va_start(ap, cmd); | 414 va_start(ap, cmd); |
371 int32_t arg = va_arg(ap, int32_t); | 415 int32_t arg = va_arg(ap, int32_t); |
372 va_end(ap); | 416 va_end(ap); |
373 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); | 417 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); |
374 } | 418 } |
419 if (cmd == F_SETFL) { | |
420 va_list ap; | |
421 va_start(ap, cmd); | |
422 int32_t arg = va_arg(ap, int32_t); | |
423 va_end(ap); | |
424 arg = nacl_oflags_to_linux_oflags(arg); | |
425 if (arg == -1) { | |
426 errno = EINVAL; | |
427 return -1; | |
428 } | |
429 return errno_value_call(linux_syscall3(__NR_fcntl64, fd, cmd, arg)); | |
430 } | |
375 /* We only support the fcntl commands above. */ | 431 /* We only support the fcntl commands above. */ |
376 errno = EINVAL; | 432 errno = EINVAL; |
377 return -1; | 433 return -1; |
378 } | 434 } |
379 | 435 |
380 int getpid(void) { | 436 int getpid(void) { |
381 return errno_value_call(linux_syscall0(__NR_getpid)); | 437 return errno_value_call(linux_syscall0(__NR_getpid)); |
382 } | 438 } |
383 | 439 |
384 int fork(void) { | 440 int fork(void) { |
(...skipping 19 matching lines...) Expand all Loading... | |
404 int isatty(int fd) { | 460 int isatty(int fd) { |
405 struct linux_termios term; | 461 struct linux_termios term; |
406 return errno_value_call( | 462 return errno_value_call( |
407 linux_syscall3(__NR_ioctl, fd, LINUX_TCGETS, (uintptr_t) &term)) == 0; | 463 linux_syscall3(__NR_ioctl, fd, LINUX_TCGETS, (uintptr_t) &term)) == 0; |
408 } | 464 } |
409 | 465 |
410 int pipe(int pipefd[2]) { | 466 int pipe(int pipefd[2]) { |
411 return errno_value_call(linux_syscall1(__NR_pipe, (uintptr_t) pipefd)); | 467 return errno_value_call(linux_syscall1(__NR_pipe, (uintptr_t) pipefd)); |
412 } | 468 } |
413 | 469 |
470 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
| |
471 flags = nacl_oflags_to_linux_oflags(flags); | |
472 if (flags == -1) { | |
473 errno = EINVAL; | |
474 return -1; | |
475 } | |
476 return errno_value_call( | |
477 linux_syscall2(__NR_pipe2, (uintptr_t) pipefd, flags)); | |
478 } | |
479 | |
414 int poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 480 int poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
415 return errno_value_call( | 481 return errno_value_call( |
416 linux_syscall3(__NR_poll, (uintptr_t) fds, nfds, timeout)); | 482 linux_syscall3(__NR_poll, (uintptr_t) fds, nfds, timeout)); |
417 } | 483 } |
418 | 484 |
419 int prctl(int option, uintptr_t arg2, uintptr_t arg3, | 485 int prctl(int option, uintptr_t arg2, uintptr_t arg3, |
420 uintptr_t arg4, uintptr_t arg5) { | 486 uintptr_t arg4, uintptr_t arg5) { |
421 return errno_value_call( | 487 return errno_value_call( |
422 linux_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5)); | 488 linux_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5)); |
423 } | 489 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
602 | 668 |
603 void *nacl_tls_get(void) { | 669 void *nacl_tls_get(void) { |
604 void *result; | 670 void *result; |
605 #if defined(__i386__) | 671 #if defined(__i386__) |
606 __asm__("mov %%gs:0, %0" : "=r"(result)); | 672 __asm__("mov %%gs:0, %0" : "=r"(result)); |
607 #elif defined(__arm__) | 673 #elif defined(__arm__) |
608 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); | 674 __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(result)); |
609 #endif | 675 #endif |
610 return result; | 676 return result; |
611 } | 677 } |
OLD | NEW |