| Index: native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
|
| diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
|
| index b0c449ffba1cb08c754c5287043e8668b9da64fc..2f49395ee019fe05a24c46053c7d6b2dfac6fdd2 100644
|
| --- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
|
| +++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
|
| @@ -36,16 +36,9 @@
|
| #define USR_ID 1002
|
| #define GRP_ID 1003
|
|
|
| +KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) {}
|
|
|
| -
|
| -KernelProxy::KernelProxy()
|
| - : dev_(0),
|
| - ppapi_(NULL) {
|
| -}
|
| -
|
| -KernelProxy::~KernelProxy() {
|
| - delete ppapi_;
|
| -}
|
| +KernelProxy::~KernelProxy() { delete ppapi_; }
|
|
|
| void KernelProxy::Init(PepperInterface* ppapi) {
|
| ppapi_ = ppapi;
|
| @@ -58,11 +51,12 @@ void KernelProxy::Init(PepperInterface* ppapi) {
|
| factories_["httpfs"] = MountHttp::Create<MountHttp>;
|
| factories_["passthroughfs"] = MountPassthrough::Create<MountPassthrough>;
|
|
|
| - // Create passthrough mount at root
|
| - StringMap_t smap;
|
| - mounts_["/"] = MountPassthrough::Create<MountPassthrough>(
|
| - dev_++, smap, ppapi_);
|
| - mounts_["/dev"] = MountDev::Create<MountDev>(dev_++, smap, ppapi_);
|
| + int result;
|
| + result = mount("", "/", "passthroughfs", 0, NULL);
|
| + assert(result == 0);
|
| +
|
| + result = mount("", "/dev", "dev", 0, NULL);
|
| + assert(result == 0);
|
|
|
| // Open the first three in order to get STDIN, STDOUT, STDERR
|
| open("/dev/stdin", O_RDONLY);
|
| @@ -70,19 +64,32 @@ void KernelProxy::Init(PepperInterface* ppapi) {
|
| open("/dev/stderr", O_WRONLY);
|
| }
|
|
|
| -int KernelProxy::open(const char *path, int oflags) {
|
| +int KernelProxy::open(const char* path, int oflags) {
|
| Path rel;
|
|
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| + Mount* mnt;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - MountNode* node = mnt->Open(rel, oflags);
|
| - if (node == NULL) {
|
| + MountNode* node = NULL;
|
| + error = mnt->Open(rel, oflags, &node);
|
| + if (error) {
|
| + errno = error;
|
| + ReleaseMount(mnt);
|
| + return -1;
|
| + }
|
| +
|
| + KernelHandle* handle = new KernelHandle(mnt, node);
|
| + error = handle->Init(oflags);
|
| + if (error) {
|
| + errno = error;
|
| ReleaseMount(mnt);
|
| return -1;
|
| }
|
|
|
| - KernelHandle* handle = new KernelHandle(mnt, node, oflags);
|
| int fd = AllocateFD(handle);
|
| mnt->AcquireNode(node);
|
|
|
| @@ -93,9 +100,12 @@ int KernelProxy::open(const char *path, int oflags) {
|
| }
|
|
|
| int KernelProxy::close(int fd) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - if (NULL == handle) return -1;
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| Mount* mount = handle->mount_;
|
| // Acquire the mount to ensure FreeFD doesn't prematurely destroy it.
|
| @@ -115,8 +125,12 @@ int KernelProxy::close(int fd) {
|
| }
|
|
|
| int KernelProxy::dup(int oldfd) {
|
| - KernelHandle* handle = AcquireHandle(oldfd);
|
| - if (NULL == handle) return -1;
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(oldfd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| int newfd = AllocateFD(handle);
|
| ReleaseHandle(handle);
|
| @@ -126,17 +140,21 @@ int KernelProxy::dup(int oldfd) {
|
|
|
| int KernelProxy::dup2(int oldfd, int newfd) {
|
| // If it's the same file handle, just return
|
| - if (oldfd == newfd) return newfd;
|
| + if (oldfd == newfd)
|
| + return newfd;
|
|
|
| - KernelHandle* old_handle = AcquireHandle(oldfd);
|
| - if (NULL == old_handle) return -1;
|
| + KernelHandle* old_handle;
|
| + Error error = AcquireHandle(oldfd, &old_handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| FreeAndReassignFD(newfd, old_handle);
|
| ReleaseHandle(old_handle);
|
| return newfd;
|
| }
|
|
|
| -
|
| char* KernelProxy::getcwd(char* buf, size_t size) {
|
| AutoLock lock(&process_lock_);
|
| if (size <= 0) {
|
| @@ -171,42 +189,64 @@ char* KernelProxy::getwd(char* buf) {
|
| return getcwd(buf, MAXPATHLEN);
|
| }
|
|
|
| -int KernelProxy::chmod(const char *path, mode_t mode) {
|
| +int KernelProxy::chmod(const char* path, mode_t mode) {
|
| int fd = KernelProxy::open(path, O_RDWR);
|
| - if (-1 == fd) return -1;
|
| + if (-1 == fd)
|
| + return -1;
|
|
|
| - int ret = fchmod(fd, mode);
|
| + int result = fchmod(fd, mode);
|
| close(fd);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| -int KernelProxy::mkdir(const char *path, mode_t mode) {
|
| +int KernelProxy::mkdir(const char* path, mode_t mode) {
|
| + Mount* mnt;
|
| Path rel;
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
| +
|
| + int result = 0;
|
| + error = mnt->Mkdir(rel, mode);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| - int val = mnt->Mkdir(rel, mode);
|
| ReleaseMount(mnt);
|
| - return val;
|
| + return result;
|
| }
|
|
|
| -int KernelProxy::rmdir(const char *path) {
|
| +int KernelProxy::rmdir(const char* path) {
|
| + Mount* mnt;
|
| Path rel;
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
| +
|
| + int result = 0;
|
| + error = mnt->Rmdir(rel);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| - int val = mnt->Rmdir(rel);
|
| ReleaseMount(mnt);
|
| - return val;
|
| + return result;
|
| }
|
|
|
| -int KernelProxy::stat(const char *path, struct stat *buf) {
|
| +int KernelProxy::stat(const char* path, struct stat* buf) {
|
| int fd = open(path, O_RDONLY);
|
| - if (-1 == fd) return -1;
|
| + if (-1 == fd)
|
| + return -1;
|
|
|
| - int ret = fstat(fd, buf);
|
| + int result = fstat(fd, buf);
|
| close(fd);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| int KernelProxy::chdir(const char* path) {
|
| @@ -215,19 +255,21 @@ int KernelProxy::chdir(const char* path) {
|
| return -1;
|
|
|
| bool is_dir = (statbuf.st_mode & S_IFDIR) != 0;
|
| - if (is_dir) {
|
| - AutoLock lock(&process_lock_);
|
| - cwd_ = GetAbsPathLocked(path).Join();
|
| - return 0;
|
| + if (!is_dir) {
|
| + errno = ENOTDIR;
|
| + return -1;
|
| }
|
|
|
| - errno = ENOTDIR;
|
| - return -1;
|
| + AutoLock lock(&process_lock_);
|
| + cwd_ = GetAbsPathLocked(path).Join();
|
| + return 0;
|
| }
|
|
|
| -int KernelProxy::mount(const char *source, const char *target,
|
| - const char *filesystemtype, unsigned long mountflags,
|
| - const void *data) {
|
| +int KernelProxy::mount(const char* source,
|
| + const char* target,
|
| + const char* filesystemtype,
|
| + unsigned long mountflags,
|
| + const void* data) {
|
| // See if it's already mounted
|
| std::string abs_targ;
|
|
|
| @@ -255,8 +297,8 @@ int KernelProxy::mount(const char *source, const char *target,
|
| smap["TARGET"] = abs_targ;
|
|
|
| if (data) {
|
| - char* str = strdup(static_cast<const char *>(data));
|
| - char* ptr = strtok(str,",");
|
| + char* str = strdup(static_cast<const char*>(data));
|
| + char* ptr = strtok(str, ",");
|
| char* val;
|
| while (ptr != NULL) {
|
| val = strchr(ptr, '=');
|
| @@ -271,16 +313,18 @@ int KernelProxy::mount(const char *source, const char *target,
|
| free(str);
|
| }
|
|
|
| - Mount* mnt = factory->second(dev_++, smap, ppapi_);
|
| - if (mnt) {
|
| - mounts_[abs_targ] = mnt;
|
| - return 0;
|
| + Mount* mnt = NULL;
|
| + Error error = factory->second(dev_++, smap, ppapi_, &mnt);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| }
|
| - errno = EINVAL;
|
| - return -1;
|
| +
|
| + mounts_[abs_targ] = mnt;
|
| + return 0;
|
| }
|
|
|
| -int KernelProxy::umount(const char *path) {
|
| +int KernelProxy::umount(const char* path) {
|
| Path abs_path;
|
|
|
| // Scope this lock to prevent holding both process and kernel locks
|
| @@ -307,125 +351,204 @@ int KernelProxy::umount(const char *path) {
|
| return 0;
|
| }
|
|
|
| -ssize_t KernelProxy::read(int fd, void *buf, size_t nbytes) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| +ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| AutoLock lock(&handle->lock_);
|
| - ssize_t cnt = handle->node_->Read(handle->offs_, buf, nbytes);
|
| - if (cnt > 0) handle->offs_ += cnt;
|
| + int cnt = 0;
|
| + error = handle->node_->Read(handle->offs_, buf, nbytes, &cnt);
|
| + if (error)
|
| + errno = error;
|
| +
|
| + if (cnt > 0)
|
| + handle->offs_ += cnt;
|
|
|
| ReleaseHandle(handle);
|
| return cnt;
|
| }
|
|
|
| -ssize_t KernelProxy::write(int fd, const void *buf, size_t nbytes) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| +ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| AutoLock lock(&handle->lock_);
|
| - ssize_t cnt = handle->node_->Write(handle->offs_, buf, nbytes);
|
| - if (cnt > 0) handle->offs_ += cnt;
|
| + int cnt = 0;
|
| + error = handle->node_->Write(handle->offs_, buf, nbytes, &cnt);
|
| + if (error)
|
| + errno = error;
|
| +
|
| + if (cnt > 0)
|
| + handle->offs_ += cnt;
|
|
|
| ReleaseHandle(handle);
|
| return cnt;
|
| }
|
|
|
| int KernelProxy::fstat(int fd, struct stat* buf) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| + int result = 0;
|
| + error = handle->node_->GetStat(buf);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| - int ret = handle->node_->GetStat(buf);
|
| ReleaseHandle(handle);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| AutoLock lock(&handle->lock_);
|
| - int cnt = handle->node_->GetDents(handle->offs_,
|
| - static_cast<dirent *>(buf), count);
|
| + int cnt = 0;
|
| + error = handle->node_
|
| + ->GetDents(handle->offs_, static_cast<dirent*>(buf), count, &cnt);
|
| + if (error)
|
| + errno = error;
|
|
|
| - if (cnt > 0) handle->offs_ += cnt;
|
| + if (cnt > 0)
|
| + handle->offs_ += cnt;
|
|
|
| ReleaseHandle(handle);
|
| return cnt;
|
| }
|
|
|
| int KernelProxy::ftruncate(int fd, off_t length) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| - int ret = handle->node_->FTruncate(length);
|
| + int result = 0;
|
| + error = handle->node_->FTruncate(length);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| ReleaseHandle(handle);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| int KernelProxy::fsync(int fd) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| - int ret = handle->node_->FSync();
|
| + int result = 0;
|
| + error = handle->node_->FSync();
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| ReleaseHandle(handle);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| int KernelProxy::isatty(int fd) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| - int ret = handle->node_->IsaTTY();
|
| + int result = 0;
|
| + error = handle->node_->IsaTTY();
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| ReleaseHandle(handle);
|
| - return ret;
|
| + return result;
|
| }
|
|
|
| off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - // check if fd is valid and handle exists
|
| - if (NULL == handle) return -1;
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| AutoLock lock(&handle->lock_);
|
| - int ret = handle->Seek(offset, whence);
|
| + off_t new_offset;
|
| + error = handle->Seek(offset, whence, &new_offset);
|
| + if (error) {
|
| + errno = error;
|
| + new_offset = -1;
|
| + }
|
|
|
| ReleaseHandle(handle);
|
| - return ret;
|
| + return new_offset;
|
| }
|
|
|
| int KernelProxy::unlink(const char* path) {
|
| + Mount* mnt;
|
| Path rel;
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
| +
|
| + int result = 0;
|
| + error = mnt->Unlink(rel);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| - int val = mnt->Unlink(rel);
|
| ReleaseMount(mnt);
|
| - return val;
|
| + return result;
|
| }
|
|
|
| int KernelProxy::remove(const char* path) {
|
| + Mount* mnt;
|
| Path rel;
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
| +
|
| + int result = 0;
|
| + error = mnt->Remove(rel);
|
| + if (error) {
|
| + errno = error;
|
| + result = -1;
|
| + }
|
|
|
| - int val = mnt->Remove(rel);
|
| ReleaseMount(mnt);
|
| - return val;
|
| + return result;
|
| }
|
|
|
| // TODO(noelallen): Needs implementation.
|
| @@ -449,22 +572,29 @@ int KernelProxy::symlink(const char* oldpath, const char* newpath) {
|
| return -1;
|
| }
|
|
|
| -void* KernelProxy::mmap(void* addr, size_t length, int prot, int flags, int fd,
|
| +void* KernelProxy::mmap(void* addr,
|
| + size_t length,
|
| + int prot,
|
| + int flags,
|
| + int fd,
|
| size_t offset) {
|
| // We shouldn't be getting anonymous mmaps here.
|
| assert((flags & MAP_ANONYMOUS) == 0);
|
| assert(fd != -1);
|
|
|
| - KernelHandle* handle = AcquireHandle(fd);
|
| -
|
| - if (NULL == handle)
|
| + KernelHandle* handle;
|
| + Error error = AcquireHandle(fd, &handle);
|
| + if (error) {
|
| + errno = error;
|
| return MAP_FAILED;
|
| + }
|
|
|
| void* new_addr;
|
| {
|
| AutoLock lock(&handle->lock_);
|
| - new_addr = handle->node_->MMap(addr, length, prot, flags, offset);
|
| - if (new_addr == MAP_FAILED) {
|
| + error = handle->node_->MMap(addr, length, prot, flags, offset, &new_addr);
|
| + if (error) {
|
| + errno = error;
|
| ReleaseHandle(handle);
|
| return MAP_FAILED;
|
| }
|
| @@ -510,23 +640,34 @@ int KernelProxy::munmap(void* addr, size_t length) {
|
| }
|
|
|
| int KernelProxy::open_resource(const char* path) {
|
| + Mount* mnt;
|
| Path rel;
|
| + Error error = AcquireMountAndPath(path, &mnt, &rel);
|
| + if (error) {
|
| + errno = error;
|
| + return -1;
|
| + }
|
|
|
| - Mount* mnt = AcquireMountAndPath(path, &rel);
|
| - if (mnt == NULL) return -1;
|
| -
|
| - MountNode* node = mnt->OpenResource(rel);
|
| - if (node == NULL) {
|
| - node = mnt->Open(rel, O_RDONLY);
|
| - if (node == NULL) {
|
| + MountNode* node = NULL;
|
| + error = mnt->OpenResource(rel, &node);
|
| + if (error) {
|
| + // OpenResource failed, try Open().
|
| + error = mnt->Open(rel, O_RDONLY, &node);
|
| + if (error) {
|
| + errno = error;
|
| ReleaseMount(mnt);
|
| return -1;
|
| }
|
| }
|
|
|
| - // OpenResource failed, try Open().
|
| + KernelHandle* handle = new KernelHandle(mnt, node);
|
| + error = handle->Init(O_RDONLY);
|
| + if (error) {
|
| + errno = error;
|
| + ReleaseMount(mnt);
|
| + return -1;
|
| + }
|
|
|
| - KernelHandle* handle = new KernelHandle(mnt, node, O_RDONLY);
|
| int fd = AllocateFD(handle);
|
| mnt->AcquireNode(node);
|
|
|
|
|