Chromium Code Reviews| Index: native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc |
| diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc |
| index c4d0df8607039cbc471947fc99f975357a8372d9..a4c2a68c065ea4e9e7d2e54d81fdf7a24f3267a6 100644 |
| --- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc |
| +++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc |
| @@ -8,6 +8,20 @@ |
| #include <errno.h> |
| +#ifdef __linux__ |
| +#include <dirent.h> |
| +#include <stddef.h> |
| +#include <string.h> |
| +#include <sys/syscall.h> |
| +#include <unistd.h> |
| +struct linux_dirent { |
| + unsigned long d_ino; /* Inode number */ |
| + unsigned long d_off; /* Offset to next linux_dirent */ |
| + unsigned short d_reclen; /* Length of this linux_dirent */ |
| + char d_name[]; /* Filename (null-terminated) */ |
| +}; |
| +#endif |
| + |
| #include "nacl_io/kernel_wrap.h" |
| #include "nacl_io/kernel_wrap_real.h" |
| @@ -20,11 +34,41 @@ int _real_close(int fd) { |
| } |
| int _real_fstat(int fd, struct stat* buf) { |
| + return fstat(fd, buf); |
| +} |
| + |
| +int _real_getdents(int fd, void* in_buf, size_t in_count, size_t* nread) { |
| +#ifdef __linux__ |
| + int in_offset = 0; |
| + // "buf" contains linux_dirent(s); "in_buf" contains dirent(s). |
| + // dirents(s) are smaller than linux_dirent(s), so in_count bytes buffer |
| + // is enough |
|
binji
2015/01/07 19:14:59
Will this do the right thing if you request one di
Sam Clegg
2015/01/08 12:59:07
in_count is normally much bigger than the size of
|
| + char* buf = (char*)alloca(in_count); |
| + int offset = 0; |
| + int count; |
| + |
| + count = syscall(SYS_getdents, fd, buf, in_count); |
| + if (count < 0) |
| + return errno; |
| + |
| + while (offset < count) { |
| + struct linux_dirent* d = (struct linux_dirent*)(buf + offset); |
| + struct dirent* nacl_d = (struct dirent*)((char*)in_buf + in_offset); |
|
binji
2015/01/07 19:14:59
consistency between in_ and nacl_ prefixes?
Sam Clegg
2015/01/08 12:59:07
Done.
|
| + nacl_d->d_ino = d->d_ino; |
| + nacl_d->d_off = d->d_off; |
| + nacl_d->d_reclen = d->d_reclen; |
| + size_t d_name_len = d->d_reclen - offsetof(linux_dirent, d_name); |
| + memcpy(nacl_d->d_name, d->d_name, d_name_len); |
| + |
| + offset += d->d_reclen; |
| + in_offset += nacl_d->d_reclen; |
| + } |
| + |
| + *nread = in_offset; |
| return 0; |
| -} |
| - |
| -int _real_getdents(int fd, void* nacl_buf, size_t nacl_count, size_t* nread) { |
| +#else |
| return ENOSYS; |
| +#endif |
| } |
| int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { |
| @@ -49,7 +93,12 @@ int _real_munmap(void* addr, size_t length) { |
| } |
| int _real_open(const char* pathname, int oflag, mode_t mode, int* newfd) { |
| - return ENOSYS; |
| + int fd = open(pathname, oflag, mode); |
| + if (fd < 0) |
| + return errno; |
| + |
| + *newfd = fd; |
| + return 0; |
| } |
| int _real_open_resource(const char* file, int* fd) { |
| @@ -57,7 +106,11 @@ int _real_open_resource(const char* file, int* fd) { |
| } |
| int _real_read(int fd, void* buf, size_t count, size_t* nread) { |
| - *nread = count; |
| + int rtn = read(fd, buf, count); |
| + if (rtn < 0) |
| + return errno; |
| + |
| + *nread = rtn; |
| return 0; |
| } |
| @@ -68,7 +121,7 @@ int _real_rmdir(const char* pathname) { |
| int _real_write(int fd, const void* buf, size_t count, size_t* nwrote) { |
| int rtn = write(fd, buf, count); |
| if (rtn < 0) |
| - return -1; |
| + return errno; |
| *nwrote = rtn; |
| return 0; |