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(__APPLE__) || (defined(__linux__) && !defined(__na tive_client__)) | 7 #if defined(WIN32) || defined(__APPLE__) || (defined(__linux__) && !defined(__na tive_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, struct dirent* out_buf, size_t in_count, |
42 size_t* nread) { | |
43 #ifdef __linux__ | |
44 #define ROUND_UP(X, SIZE) ( ((X) + (SIZE)-1) & (~((SIZE)-1)) ) | |
45 | |
46 int out_offset = 0; | |
47 // 'out_buf' is to be filled with the native (glibc) 'dirent' whereas the | |
48 // syscall reads 'linux_dirent' into 'buf'. | |
49 // Since the linux_dirent is larger (by a single pad byte) we know that we | |
binji
2015/09/08 19:18:57
where is the single pad byte?
Sam Clegg
2015/09/09 10:11:54
At the end. See 'man getdents'.
| |
50 // will not read too many of them. | |
51 char* buf = (char*)alloca(in_count); | |
52 int offset = 0; | |
53 int count; | |
54 | |
55 count = syscall(SYS_getdents, fd, buf, in_count); | |
56 if (count < 0) | |
57 return errno; | |
58 | |
59 while (offset < count) { | |
60 struct linux_dirent* d = (struct linux_dirent*)(buf + offset); | |
61 struct dirent* out_d = (struct dirent*)((char*)out_buf + out_offset); | |
62 | |
63 // Copy fields | |
64 out_d->d_ino = d->d_ino; | |
65 out_d->d_off = d->d_off; | |
66 size_t name_len = strlen(d->d_name) + 1; | |
67 memcpy(out_d->d_name, d->d_name, name_len); | |
binji
2015/09/08 19:18:57
shouldn't this clamp to the max size of out_d->d_n
Sam Clegg
2015/09/09 10:11:54
Its variable size. The max size should be 256 in
| |
68 | |
69 // Calculate size of output dirent, rounding up for alignment | |
70 out_d->d_reclen = ROUND_UP(offsetof(dirent, d_name) + name_len, | |
71 sizeof(ino_t)); | |
binji
2015/09/08 19:18:57
why round to sizeof(ino_t)? Is this to align the s
| |
72 | |
73 offset += d->d_reclen; | |
74 out_offset += out_d->d_reclen; | |
75 } | |
76 | |
77 *nread = out_offset; | |
78 return 0; | |
79 #else | |
27 return ENOSYS; | 80 return ENOSYS; |
81 #endif | |
28 } | 82 } |
29 | 83 |
30 int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { | 84 int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { |
31 return ENOSYS; | 85 return ENOSYS; |
32 } | 86 } |
33 | 87 |
34 int _real_mkdir(const char* pathname, mode_t mode) { | 88 int _real_mkdir(const char* pathname, mode_t mode) { |
35 return ENOSYS; | 89 return ENOSYS; |
36 } | 90 } |
37 | 91 |
38 int _real_mmap(void** addr, | 92 int _real_mmap(void** addr, |
39 size_t length, | 93 size_t length, |
40 int prot, | 94 int prot, |
41 int flags, | 95 int flags, |
42 int fd, | 96 int fd, |
43 off_t offset) { | 97 off_t offset) { |
44 return ENOSYS; | 98 return ENOSYS; |
45 } | 99 } |
46 | 100 |
47 int _real_munmap(void* addr, size_t length) { | 101 int _real_munmap(void* addr, size_t length) { |
48 return ENOSYS; | 102 return ENOSYS; |
49 } | 103 } |
50 | 104 |
51 int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) { | 105 int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) { |
52 return ENOSYS; | 106 int fd = open(pathname, oflag, mode); |
107 if (fd < 0) | |
108 return errno; | |
109 | |
110 *newfd = fd; | |
111 return 0; | |
53 } | 112 } |
54 | 113 |
55 int _real_open_resource(const char* file, int* fd) { | 114 int _real_open_resource(const char* file, int* fd) { |
56 return ENOSYS; | 115 return ENOSYS; |
57 } | 116 } |
58 | 117 |
59 int _real_read(int fd, void* buf, size_t count, size_t* nread) { | 118 int _real_read(int fd, void* buf, size_t count, size_t* nread) { |
60 *nread = count; | 119 int rtn = read(fd, buf, count); |
120 if (rtn < 0) | |
121 return errno; | |
122 | |
123 *nread = rtn; | |
61 return 0; | 124 return 0; |
62 } | 125 } |
63 | 126 |
64 int _real_rmdir(const char* pathname) { | 127 int _real_rmdir(const char* pathname) { |
65 return ENOSYS; | 128 return ENOSYS; |
66 } | 129 } |
67 | 130 |
68 int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) { | 131 int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) { |
69 int rtn = write(fd, buf, count); | 132 int rtn = write(fd, buf, count); |
70 if (rtn < 0) | 133 if (rtn < 0) |
71 return -1; | 134 return errno; |
72 | 135 |
73 *nwrote = rtn; | 136 *nwrote = rtn; |
74 return 0; | 137 return 0; |
75 } | 138 } |
76 | 139 |
77 void _real_exit(int status) { | 140 void _real_exit(int status) { |
78 exit(status); | 141 exit(status); |
79 } | 142 } |
80 | 143 |
81 int _real_getcwd(char* pathname, size_t len) { | 144 int _real_getcwd(char* pathname, size_t len) { |
(...skipping 11 matching lines...) Expand all Loading... | |
93 // so guard against __native_client__ being defined as well. | 156 // so guard against __native_client__ being defined as well. |
94 #if defined(__APPLE__) || defined(__linux__) && !defined(__native_client__) | 157 #if defined(__APPLE__) || defined(__linux__) && !defined(__native_client__) |
95 | 158 |
96 void kernel_wrap_init() { | 159 void kernel_wrap_init() { |
97 } | 160 } |
98 | 161 |
99 void kernel_wrap_uninit() { | 162 void kernel_wrap_uninit() { |
100 } | 163 } |
101 | 164 |
102 #endif | 165 #endif |
OLD | NEW |