OLD | NEW |
(Empty) | |
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. |
| 4 */ |
| 5 |
| 6 #include "nacl_mounts/kernel_wrap.h" |
| 7 #include <alloca.h> |
| 8 #include <dirent.h> |
| 9 #include <errno.h> |
| 10 #include <irt.h> |
| 11 #include <irt_syscalls.h> |
| 12 #include <nacl_stat.h> |
| 13 #include <string.h> |
| 14 #include <sys/stat.h> |
| 15 #include "nacl_mounts/kernel_intercept.h" |
| 16 |
| 17 namespace { |
| 18 |
| 19 void stat_to_nacl_stat(const struct stat* buf, nacl_abi_stat* nacl_buf) { |
| 20 memset(nacl_buf, 0, sizeof(struct nacl_abi_stat)); |
| 21 nacl_buf->nacl_abi_st_dev = buf->st_dev; |
| 22 nacl_buf->nacl_abi_st_ino = buf->st_ino; |
| 23 nacl_buf->nacl_abi_st_mode = buf->st_mode; |
| 24 nacl_buf->nacl_abi_st_nlink = buf->st_nlink; |
| 25 nacl_buf->nacl_abi_st_uid = buf->st_uid; |
| 26 nacl_buf->nacl_abi_st_gid = buf->st_gid; |
| 27 nacl_buf->nacl_abi_st_rdev = buf->st_rdev; |
| 28 nacl_buf->nacl_abi_st_size = buf->st_size; |
| 29 nacl_buf->nacl_abi_st_blksize = buf->st_blksize; |
| 30 nacl_buf->nacl_abi_st_blocks = buf->st_blocks; |
| 31 nacl_buf->nacl_abi_st_atime = buf->st_atime; |
| 32 nacl_buf->nacl_abi_st_mtime = buf->st_mtime; |
| 33 nacl_buf->nacl_abi_st_ctime = buf->st_ctime; |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 38 // From native_client/src/trusted/service_runtime/include/sys/dirent.h |
| 39 |
| 40 #ifndef nacl_abi___ino_t_defined |
| 41 #define nacl_abi___ino_t_defined |
| 42 typedef int64_t nacl_abi___ino_t; |
| 43 typedef nacl_abi___ino_t nacl_abi_ino_t; |
| 44 #endif |
| 45 |
| 46 #ifndef nacl_abi___off_t_defined |
| 47 #define nacl_abi___off_t_defined |
| 48 typedef int64_t nacl_abi__off_t; |
| 49 typedef nacl_abi__off_t nacl_abi_off_t; |
| 50 #endif |
| 51 |
| 52 /* We need a way to define the maximum size of a name. */ |
| 53 #ifndef MAXNAMLEN |
| 54 # ifdef NAME_MAX |
| 55 # define MAXNAMLEN NAME_MAX |
| 56 # else |
| 57 # define MAXNAMLEN 255 |
| 58 # endif |
| 59 #endif |
| 60 |
| 61 struct nacl_abi_dirent { |
| 62 nacl_abi_ino_t nacl_abi_d_ino; |
| 63 nacl_abi_off_t nacl_abi_d_off; |
| 64 uint16_t nacl_abi_d_reclen; |
| 65 char nacl_abi_d_name[MAXNAMLEN + 1]; |
| 66 }; |
| 67 |
| 68 static const int d_name_shift = offsetof (dirent, d_name) - |
| 69 offsetof (struct nacl_abi_dirent, nacl_abi_d_name); |
| 70 |
| 71 EXTERN_C_BEGIN |
| 72 |
| 73 #define REAL(name) __nacl_irt_##name##_real |
| 74 #define WRAP(name) __nacl_irt_##name##_wrap |
| 75 #define MUX(name) __nacl_irt_##name |
| 76 #define DECLARE(name) typeof(MUX(name)) REAL(name); |
| 77 #define DO_WRAP(name) do { \ |
| 78 REAL(name) = MUX(name); \ |
| 79 MUX(name) = (typeof(REAL(name))) WRAP(name); \ |
| 80 } while (0) |
| 81 |
| 82 DECLARE(chdir) |
| 83 DECLARE(close) |
| 84 DECLARE(dup) |
| 85 DECLARE(fstat) |
| 86 DECLARE(getcwd) |
| 87 DECLARE(getdents) |
| 88 DECLARE(mkdir) |
| 89 DECLARE(open) |
| 90 DECLARE(read) |
| 91 DECLARE(rmdir) |
| 92 DECLARE(seek) |
| 93 DECLARE(stat) |
| 94 DECLARE(write) |
| 95 |
| 96 int access(const char* path, int amode) NOTHROW { |
| 97 return ki_access(path, amode); |
| 98 } |
| 99 |
| 100 int chdir(const char* path) NOTHROW { |
| 101 return ki_chdir(path); |
| 102 } |
| 103 |
| 104 int chmod(const char* path, mode_t mode) NOTHROW { |
| 105 return ki_chmod(path, mode); |
| 106 } |
| 107 |
| 108 int WRAP(chdir) (const char* pathname) { |
| 109 return (ki_chdir(pathname)) ? errno : 0; |
| 110 } |
| 111 |
| 112 int WRAP(close)(int fd) { |
| 113 return (ki_close(fd) < 0) ? errno : 0; |
| 114 } |
| 115 |
| 116 int WRAP(dup)(int fd, int* newfd) NOTHROW { |
| 117 *newfd = ki_dup(fd); |
| 118 return (*newfd < 0) ? errno : 0; |
| 119 } |
| 120 |
| 121 int WRAP(fstat)(int fd, struct nacl_abi_stat *nacl_buf) { |
| 122 struct stat buf; |
| 123 memset(&buf, 0, sizeof(struct stat)); |
| 124 int res = ki_fstat(fd, &buf); |
| 125 if (res < 0) |
| 126 return errno; |
| 127 stat_to_nacl_stat(&buf, nacl_buf); |
| 128 return 0; |
| 129 } |
| 130 |
| 131 int fsync(int fd) { |
| 132 return ki_fsync(fd); |
| 133 } |
| 134 |
| 135 char* getcwd(char* buf, size_t size) NOTHROW { |
| 136 // gtest uses getcwd in a static initializer. If we haven't initialized the |
| 137 // kernel-intercept yet, just return ".". |
| 138 if (!ki_is_initialized()) { |
| 139 if (size < 2) { |
| 140 errno = ERANGE; |
| 141 return NULL; |
| 142 } |
| 143 buf[0] = '.'; |
| 144 buf[1] = 0; |
| 145 return buf; |
| 146 } |
| 147 return ki_getcwd(buf, size); |
| 148 } |
| 149 |
| 150 char* WRAP(getcwd)(char* buf, size_t size) { |
| 151 return ki_getcwd(buf, size); |
| 152 } |
| 153 |
| 154 char* getwd(char* buf) NOTHROW { |
| 155 return ki_getwd(buf); |
| 156 } |
| 157 |
| 158 int getdents(int fd, void* buf, unsigned int count) NOTHROW { |
| 159 return ki_getdents(fd, buf, count); |
| 160 } |
| 161 |
| 162 int WRAP(getdents)(int fd, dirent* nacl_buf, size_t nacl_count, size_t *nread) { |
| 163 int nacl_offset = 0; |
| 164 // "buf" contains dirent(s); "nacl_buf" contains nacl_abi_dirent(s). |
| 165 // nacl_abi_dirent(s) are smaller than dirent(s), so nacl_count bytes buffer |
| 166 // is enough |
| 167 char* buf = (char*)alloca(nacl_count); |
| 168 int offset = 0; |
| 169 int count; |
| 170 |
| 171 count = ki_getdents(fd, buf, nacl_count); |
| 172 if (count < 0) |
| 173 return errno; |
| 174 |
| 175 while (offset < count) { |
| 176 dirent* d = (dirent*)(buf + offset); |
| 177 nacl_abi_dirent* nacl_d = (nacl_abi_dirent*)((char*)nacl_buf + nacl_offset); |
| 178 nacl_d->nacl_abi_d_ino = d->d_ino; |
| 179 nacl_d->nacl_abi_d_off = d->d_off; |
| 180 nacl_d->nacl_abi_d_reclen = d->d_reclen - d_name_shift; |
| 181 size_t d_name_len = d->d_reclen - offsetof(dirent, d_name); |
| 182 memcpy(nacl_d->nacl_abi_d_name, d->d_name, d_name_len); |
| 183 |
| 184 offset += d->d_reclen; |
| 185 nacl_offset += nacl_d->nacl_abi_d_reclen; |
| 186 } |
| 187 |
| 188 *nread = nacl_offset; |
| 189 return 0; |
| 190 } |
| 191 |
| 192 int isatty(int fd) NOTHROW { |
| 193 return ki_isatty(fd); |
| 194 } |
| 195 |
| 196 int mkdir(const char* path, mode_t mode) NOTHROW { |
| 197 return ki_mkdir(path, mode); |
| 198 } |
| 199 |
| 200 int WRAP(mkdir) (const char* pathname, mode_t mode) { |
| 201 return (ki_mkdir(pathname, mode)) ? errno : 0; |
| 202 } |
| 203 |
| 204 int mount(const char* source, const char* target, const char* filesystemtype, |
| 205 unsigned long mountflags, const void* data) NOTHROW { |
| 206 return ki_mount(source, target, filesystemtype, mountflags, data); |
| 207 } |
| 208 |
| 209 int WRAP(open)(const char* pathname, int oflag, mode_t cmode, int* newfd) { |
| 210 *newfd = ki_open(pathname, oflag); |
| 211 return (*newfd < 0) ? errno : 0; |
| 212 } |
| 213 |
| 214 int WRAP(read)(int fd, void *buf, size_t count, size_t *nread) { |
| 215 *nread = ki_read(fd, buf, count); |
| 216 return (*nread < 0) ? errno : 0; |
| 217 } |
| 218 |
| 219 int remove(const char* path) NOTHROW { |
| 220 return ki_remove(path); |
| 221 } |
| 222 |
| 223 int rmdir(const char* path) NOTHROW { |
| 224 return ki_rmdir(path); |
| 225 } |
| 226 |
| 227 int WRAP(rmdir)(const char* pathname) { |
| 228 return (ki_rmdir(pathname) < 0) ? errno : 0; |
| 229 } |
| 230 |
| 231 int WRAP(seek)(int fd, off_t offset, int whence, off_t* new_offset) { |
| 232 *new_offset = ki_lseek(fd, offset, whence); |
| 233 return (*new_offset < 0) ? errno : 0; |
| 234 } |
| 235 |
| 236 int WRAP(stat)(const char *pathname, struct nacl_abi_stat *nacl_buf) { |
| 237 struct stat buf; |
| 238 memset(&buf, 0, sizeof(struct stat)); |
| 239 int res = ki_stat(pathname, &buf); |
| 240 if (res < 0) |
| 241 return errno; |
| 242 stat_to_nacl_stat(&buf, nacl_buf); |
| 243 return 0; |
| 244 } |
| 245 |
| 246 int umount(const char* path) NOTHROW { |
| 247 return ki_umount(path); |
| 248 } |
| 249 |
| 250 int unlink(const char* path) NOTHROW { |
| 251 return ki_unlink(path); |
| 252 } |
| 253 |
| 254 int WRAP(write)(int fd, const void *buf, size_t count, size_t *nwrote) { |
| 255 *nwrote = ki_write(fd, buf, count); |
| 256 return (*nwrote < 0) ? errno : 0; |
| 257 } |
| 258 |
| 259 EXTERN_C_END |
| 260 |
| 261 static struct NaClMountsStaticInitializer { |
| 262 NaClMountsStaticInitializer() { |
| 263 DO_WRAP(chdir); |
| 264 DO_WRAP(close); |
| 265 DO_WRAP(dup); |
| 266 DO_WRAP(fstat); |
| 267 DO_WRAP(getcwd); |
| 268 DO_WRAP(getdents); |
| 269 DO_WRAP(mkdir); |
| 270 DO_WRAP(open); |
| 271 DO_WRAP(read); |
| 272 DO_WRAP(rmdir); |
| 273 DO_WRAP(seek); |
| 274 DO_WRAP(stat); |
| 275 DO_WRAP(write); |
| 276 } |
| 277 } nacl_mounts_static_initializer; |
OLD | NEW |