Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // The Chromium build system defines __linux__ even for native client builds, | 5 // The Chromium build system defines __linux__ even for native client builds, |
| 6 // so guard against __native_client__ being defined as well. | 6 // so guard against __native_client__ being defined as well. |
| 7 #if defined(WIN32) || (defined(__linux__) && !defined(__native_client__)) | 7 #if defined(WIN32) || (defined(__linux__) && !defined(__native_client__)) |
| 8 | 8 |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 | 10 |
| 11 #ifdef __linux__ | |
| 12 #include <dirent.h> | |
| 13 #include <stddef.h> | |
| 14 #include <string.h> | |
| 15 #include <sys/syscall.h> | |
| 16 #include <unistd.h> | |
| 17 struct linux_dirent { | |
| 18 unsigned long d_ino; /* Inode number */ | |
| 19 unsigned long d_off; /* Offset to next linux_dirent */ | |
| 20 unsigned short d_reclen; /* Length of this linux_dirent */ | |
| 21 char d_name[]; /* Filename (null-terminated) */ | |
| 22 }; | |
| 23 #endif | |
| 24 | |
| 11 #include "nacl_io/kernel_wrap.h" | 25 #include "nacl_io/kernel_wrap.h" |
| 12 #include "nacl_io/kernel_wrap_real.h" | 26 #include "nacl_io/kernel_wrap_real.h" |
| 27 #include "nacl_io/log.h" | |
| 13 | 28 |
| 14 // "real" functions, i.e. the unwrapped original functions. For Windows/Linux | 29 // "real" functions, i.e. the unwrapped original functions. For Windows/Linux |
| 15 // host builds we don't wrap, so the real functions aren't accessible. In most | 30 // host builds we don't wrap, so the real functions aren't accessible. In most |
| 16 // cases, we just fail. | 31 // cases, we just fail. |
| 17 | 32 |
| 18 int _real_close(int fd) { | 33 int _real_close(int fd) { |
| 19 return ENOSYS; | 34 return ENOSYS; |
| 20 } | 35 } |
| 21 | 36 |
| 22 int _real_fstat(int fd, struct stat* buf) { | 37 int _real_fstat(int fd, struct stat* buf) { |
| 23 return 0; | 38 return fstat(fd, buf); |
| 24 } | 39 } |
| 25 | 40 |
| 26 int _real_getdents(int fd, void* nacl_buf, size_t nacl_count, size_t* nread) { | 41 int _real_getdents(int fd, void* out_buf, size_t in_count, size_t* nread) { |
| 42 #ifdef __linux__ | |
| 43 #define ROUND_UP(X, SIZE) ( (X + SIZE-1) & (~(SIZE-1)) ) | |
|
binji
2015/01/09 21:11:45
parens around X and SIZE
| |
| 44 | |
| 45 int out_offset = 0; | |
| 46 // 'out_buf' is to be filled with the native (glibc) 'dirent' whereas the | |
| 47 // syscall reads 'linux_dirent' into 'buf'. | |
| 48 // Since the linux_dirent is larger (by a single pad byte) we know that we | |
| 49 // will not read too many of them. | |
| 50 char* buf = (char*)alloca(in_count); | |
| 51 int offset = 0; | |
| 52 int count; | |
| 53 | |
| 54 count = syscall(SYS_getdents, fd, buf, in_count); | |
| 55 if (count < 0) | |
| 56 return errno; | |
| 57 | |
| 58 while (offset < count) { | |
| 59 struct linux_dirent* d = (struct linux_dirent*)(buf + offset); | |
| 60 struct dirent* out_d = (struct dirent*)((char*)out_buf + out_offset); | |
| 61 | |
| 62 // Copy fields | |
| 63 out_d->d_ino = d->d_ino; | |
| 64 out_d->d_off = d->d_off; | |
| 65 size_t name_len = strlen(d->d_name) + 1; | |
| 66 memcpy(out_d->d_name, d->d_name, name_len); | |
| 67 | |
| 68 // Calculate size of output dirent, rounding up for alignment | |
| 69 out_d->d_reclen = ROUND_UP(offsetof(dirent, d_name) + name_len, | |
| 70 sizeof(ino_t)); | |
| 71 | |
| 72 offset += d->d_reclen; | |
| 73 out_offset += out_d->d_reclen; | |
| 74 } | |
| 75 | |
| 76 *nread = out_offset; | |
| 77 return 0; | |
| 78 #else | |
| 27 return ENOSYS; | 79 return ENOSYS; |
| 80 #endif | |
| 28 } | 81 } |
| 29 | 82 |
| 30 int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { | 83 int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { |
| 31 return ENOSYS; | 84 return ENOSYS; |
| 32 } | 85 } |
| 33 | 86 |
| 34 int _real_mkdir(const char* pathname, mode_t mode) { | 87 int _real_mkdir(const char* pathname, mode_t mode) { |
| 35 return ENOSYS; | 88 return ENOSYS; |
| 36 } | 89 } |
| 37 | 90 |
| 38 int _real_mmap(void** addr, | 91 int _real_mmap(void** addr, |
| 39 size_t length, | 92 size_t length, |
| 40 int prot, | 93 int prot, |
| 41 int flags, | 94 int flags, |
| 42 int fd, | 95 int fd, |
| 43 off_t offset) { | 96 off_t offset) { |
| 44 return ENOSYS; | 97 return ENOSYS; |
| 45 } | 98 } |
| 46 | 99 |
| 47 int _real_munmap(void* addr, size_t length) { | 100 int _real_munmap(void* addr, size_t length) { |
| 48 return ENOSYS; | 101 return ENOSYS; |
| 49 } | 102 } |
| 50 | 103 |
| 51 int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) { | 104 int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) { |
| 52 return ENOSYS; | 105 int fd = open(pathname, oflag, mode); |
| 106 if (fd < 0) | |
| 107 return errno; | |
| 108 | |
| 109 *newfd = fd; | |
| 110 return 0; | |
| 53 } | 111 } |
| 54 | 112 |
| 55 int _real_open_resource(const char* file, int* fd) { | 113 int _real_open_resource(const char* file, int* fd) { |
| 56 return ENOSYS; | 114 return ENOSYS; |
| 57 } | 115 } |
| 58 | 116 |
| 59 int _real_read(int fd, void* buf, size_t count, size_t* nread) { | 117 int _real_read(int fd, void* buf, size_t count, size_t* nread) { |
| 60 *nread = count; | 118 int rtn = read(fd, buf, count); |
| 119 if (rtn < 0) | |
| 120 return errno; | |
| 121 | |
| 122 *nread = rtn; | |
| 61 return 0; | 123 return 0; |
| 62 } | 124 } |
| 63 | 125 |
| 64 int _real_rmdir(const char* pathname) { | 126 int _real_rmdir(const char* pathname) { |
| 65 return ENOSYS; | 127 return ENOSYS; |
| 66 } | 128 } |
| 67 | 129 |
| 68 int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) { | 130 int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) { |
| 69 int rtn = write(fd, buf, count); | 131 int rtn = write(fd, buf, count); |
| 70 if (rtn < 0) | 132 if (rtn < 0) |
| 71 return -1; | 133 return errno; |
| 72 | 134 |
| 73 *nwrote = rtn; | 135 *nwrote = rtn; |
| 74 return 0; | 136 return 0; |
| 75 } | 137 } |
| 76 | 138 |
| 77 void _real_exit(int status) { | 139 void _real_exit(int status) { |
| 78 exit(status); | 140 exit(status); |
| 79 } | 141 } |
| 80 | 142 |
| 81 int _real_getcwd(char* pathname, size_t len) { | 143 int _real_getcwd(char* pathname, size_t len) { |
| 82 return ENOSYS; | 144 return ENOSYS; |
| 83 } | 145 } |
| 84 | 146 |
| 85 #endif | 147 #endif |
| 86 | 148 |
| 87 // The Chromium build system defines __linux__ even for native client builds, | 149 // The Chromium build system defines __linux__ even for native client builds, |
| 88 // so guard against __native_client__ being defined as well. | 150 // so guard against __native_client__ being defined as well. |
| 89 #if defined(__linux__) && !defined(__native_client__) | 151 #if defined(__linux__) && !defined(__native_client__) |
| 90 | 152 |
| 91 void kernel_wrap_init() { | 153 void kernel_wrap_init() { |
| 92 } | 154 } |
| 93 | 155 |
| 94 void kernel_wrap_uninit() { | 156 void kernel_wrap_uninit() { |
| 95 } | 157 } |
| 96 | 158 |
| 97 #endif | 159 #endif |
| OLD | NEW |