Chromium Code Reviews| Index: components/nacl/loader/nonsfi/irt_fdio.cc |
| diff --git a/components/nacl/loader/nonsfi/irt_fdio.cc b/components/nacl/loader/nonsfi/irt_fdio.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..947d04bbfa21f603f19e7b365eb0981c86a810d4 |
| --- /dev/null |
| +++ b/components/nacl/loader/nonsfi/irt_fdio.cc |
| @@ -0,0 +1,139 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <errno.h> |
| +#include <unistd.h> |
| +#include <sys/types.h> |
| +#include <sys/stat.h> |
| + |
| +#include "base/logging.h" |
| +#include "components/nacl/loader/nonsfi/irt_interfaces.h" |
| +#include "native_client/src/trusted/service_runtime/include/sys/dirent.h" |
| +#include "native_client/src/trusted/service_runtime/include/sys/stat.h" |
| +#include "native_client/src/trusted/service_runtime/include/sys/unistd.h" |
| + |
| +namespace nacl { |
| +namespace nonsfi { |
| +namespace { |
| + |
| +int IrtClose(int fd) { |
| + if (::close(fd) < 0) |
| + return errno; |
| + return 0; |
| +} |
| + |
| +int IrtDup(int fd, int* newfd) { |
| + int result = ::dup(fd); |
| + if (result < 0) |
| + return errno; |
| + |
| + *newfd = result; |
| + return 0; |
| +} |
| + |
| +int IrtDup2(int fd, int newfd) { |
| + if (::dup2(fd, newfd) < 0) |
| + return errno; |
| + return 0; |
| +} |
| + |
| +int IrtRead(int fd, void* buf, size_t count, size_t* nread) { |
| + ssize_t result = ::read(fd, buf, count); |
| + if (result < 0) |
| + return errno; |
| + |
| + *nread =result; |
| + return 0; |
| +} |
| + |
| +int IrtWrite(int fd, const void* buf, size_t count, size_t* nwrote) { |
| + ssize_t result = ::write(fd, buf, count); |
| + if (result < 0) |
| + return errno; |
| + |
| + *nwrote = result; |
| + return 0; |
| +} |
| + |
| +int IrtSeek(int fd, nacl_abi_off_t offset, int whence, |
| + nacl_abi_off_t* new_offset) { |
| + off_t result = ::lseek(fd, offset, whence); |
|
hamaji
2014/01/09 10:47:22
Same as fstat. Probably better to check if this ca
hidehiko
2014/01/09 12:41:19
Yes, I've checked. common.gypi defines _FILE_OFFSE
|
| + if (result < 0) |
| + return errno; |
| + *new_offset = result; |
| + return 0; |
| +} |
| + |
| +int IrtFstat(int fd, struct nacl_abi_stat* st) { |
| + struct stat host_st; |
| + if (::fstat(fd, &host_st) < 0) |
|
hamaji
2014/01/09 10:47:22
As locally chatted, I think we need to call fstat6
hidehiko
2014/01/09 12:41:19
Done.
|
| + return errno; |
| + |
| + memset(st, 0, sizeof(*st)); |
| + st->nacl_abi_st_dev = 0; |
|
hamaji
2014/01/09 10:47:22
You'll need to use this code when you implement Ir
hidehiko
2014/01/09 12:41:19
Yes, I was planning to do it in a following CL (w/
|
| + st->nacl_abi_st_ino = host_st.st_ino; |
| + nacl_abi_mode_t m; |
| + switch (host_st.st_mode & S_IFMT) { |
| + case S_IFREG: |
| + m = NACL_ABI_S_IFREG; |
| + break; |
| + case S_IFDIR: |
| + m = NACL_ABI_S_IFDIR; |
| + break; |
| + case S_IFCHR: |
| + m = NACL_ABI_S_IFCHR; |
| + break; |
|
hamaji
2014/01/09 10:47:22
I'm not sure, but I'd translate all possible value
hidehiko
2014/01/09 12:41:19
I just mimic'ed the NaCl's original implementation
|
| + default: |
| + LOG(ERROR) << "Unusual NaCl descriptor type."; |
|
hamaji
2014/01/09 10:47:22
LOG(ERROR) might be over kill? And, how about outp
hidehiko
2014/01/09 12:41:19
Done. Redcued to LOG(WARNING).
|
| + m = NACL_ABI_S_UNSUP; |
| + } |
| + if (host_st.st_mode & S_IRUSR) |
| + m |= NACL_ABI_S_IRUSR; |
| + if (host_st.st_mode & S_IWUSR) |
| + m |= NACL_ABI_S_IWUSR; |
| + if (host_st.st_mode & S_IXUSR) |
| + m |= NACL_ABI_S_IXUSR; |
|
hamaji
2014/01/09 10:47:22
Is it intentional we are dropping S_I*GRP and S_I*
hidehiko
2014/01/09 12:41:19
Acknowledged.
|
| + st->nacl_abi_st_mode = m; |
| + st->nacl_abi_st_nlink = host_st.st_nlink; |
| + st->nacl_abi_st_uid = -1; // Not root |
| + st->nacl_abi_st_gid = -1; // Not wheel |
| + st->nacl_abi_st_rdev = 0; |
| + st->nacl_abi_st_size = host_st.st_size; |
| + st->nacl_abi_st_blksize = 0; |
| + st->nacl_abi_st_blocks = 0; |
| + st->nacl_abi_st_atime = host_st.st_atime; |
| + st->nacl_abi_st_mtime = host_st.st_mtime; |
| + st->nacl_abi_st_ctime = host_st.st_ctime; |
|
hamaji
2014/01/09 10:47:22
Any reason we don't copy nano seconds? For compati
hidehiko
2014/01/09 12:41:19
Acknowledged.
|
| + |
| + return 0; |
| +} |
| + |
| +int IrtGetDents(int fd, struct nacl_abi_dirent* buf, size_t count, |
| + size_t* nread) { |
| + // Note: getdents() can return several directory entries in packed format. |
| + // So, here, because we need to convert the abi from host's to nacl's, |
| + // there is no straightforward way to ensure reading only entries which can |
| + // be fit to the buf after abi conversion actually. |
|
hamaji
2014/01/09 10:47:22
TODO maybe?
hidehiko
2014/01/09 12:41:19
Done.
|
| + return ENOSYS; |
| +} |
| + |
| +} // namespace |
| + |
| +// for seek, fstat and getdents, their argument types should be nacl_abi_X, |
| +// rather than host type, such as off_t, struct stat or struct dirent. |
| +// However, the definition of nacl_irt_fdio uses host types, so here we need |
| +// to cast them. |
| +const nacl_irt_fdio kIrtFdIO = { |
| + IrtClose, |
| + IrtDup, |
| + IrtDup2, |
| + IrtRead, |
| + IrtWrite, |
| + reinterpret_cast<int(*)(int, off_t, int, off_t*)>(IrtSeek), |
| + reinterpret_cast<int(*)(int, struct stat*)>(IrtFstat), |
| + reinterpret_cast<int(*)(int, struct dirent*, size_t, size_t*)>(IrtGetDents), |
| +}; |
| + |
| +} // namespace nonsfi |
| +} // namespace nacl |