kernel_proxy.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_proxy.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <assert.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <pthread.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <iterator> 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_handle.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_wrap_real.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_dev.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_html5fs.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_http.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_mem.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_node.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_passthrough.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osmman.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osstat.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/path.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/pepper_interface.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/typed_mount_factory.h" 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/auto_lock.h" 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/ref_object.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MAXPATHLEN 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAXPATHLEN 256 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(noelallen) : Grab/Redefine these in the kernel object once available. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define USR_ID 1002 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define GRP_ID 1003 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochKernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) { 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Clean up the MountFactories. 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (MountFactoryMap_t::iterator i = factories_.begin(); 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch i != factories_.end(); 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete ppapi_; 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KernelProxy::Init(PepperInterface* ppapi) { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi_ = ppapi; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_ = 1; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["memfs"] = new TypedMountFactory<MountMem>; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["dev"] = new TypedMountFactory<MountDev>; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>; 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["httpfs"] = new TypedMountFactory<MountHttp>; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result; 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/", "passthroughfs", 0, NULL); 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) assert(result == 0); 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/dev", "dev", 0, NULL); 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) assert(result == 0); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open the first three in order to get STDIN, STDOUT, STDERR 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open("/dev/stdin", O_RDONLY); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open("/dev/stdout", O_WRONLY); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) open("/dev/stderr", O_WRONLY); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open_resource(const char* path) { 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMountNode node; 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = mnt->OpenResource(rel, &node); 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OpenResource failed, try Open(). 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = mnt->Open(rel, O_RDONLY, &node); 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedKernelHandle handle(new KernelHandle(mnt, node)); 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Init(O_RDONLY); 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AllocateFD(handle); 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open(const char* path, int oflags) { 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMountNode node; 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndNode(path, oflags, &mnt, &node); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle(new KernelHandle(mnt, node)); 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Init(oflags); 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return AllocateFD(handle); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::close(int fd) { 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove the FD from the process open file descriptor map 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeFD(fd); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup(int oldfd) { 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(oldfd, &handle); 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return AllocateFD(handle); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup2(int oldfd, int newfd) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's the same file handle, just return 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (oldfd == newfd) 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return newfd; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle old_handle; 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(oldfd, &old_handle); 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeAndReassignFD(newfd, old_handle); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return newfd; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::chdir(const char* path) { 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = SetCWD(path); 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getcwd(char* buf, size_t size) { 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string cwd = GetCWD(); 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size <= 0) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If size is 0, allocate as much as we need. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size == 0) { 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size = cwd.size() + 1; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the buffer is large enough 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (size <= cwd.size()) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ERANGE; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allocate the buffer if needed 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (buf == NULL) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf = static_cast<char*>(malloc(size)); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch strcpy(buf, cwd.c_str()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buf; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getwd(char* buf) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NULL == buf) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EFAULT; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getcwd(buf, MAXPATHLEN); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::chmod(const char* path, mode_t mode) { 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int fd = KernelProxy::open(path, O_RDONLY); 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fchmod(fd, mode); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::utime(const char* filename, const struct utimbuf* times) { 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mkdir(const char* path, mode_t mode) { 240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Mkdir(rel, mode); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::rmdir(const char* path) { 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Rmdir(rel); 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::stat(const char* path, struct stat* buf) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open(path, O_RDONLY); 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fstat(fd, buf); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mount(const char* source, 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* target, 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* filesystemtype, 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned long mountflags, 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* data) { 2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string abs_path = GetAbsParts(target).Join(); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a factory of that type 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (factory == factories_.end()) { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ENODEV; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create a map of settings 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringMap_t smap; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap["SOURCE"] = source; 3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch smap["TARGET"] = abs_path; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data) { 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char* str = strdup(static_cast<const char*>(data)); 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char* ptr = strtok(str, ","); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* val; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (ptr != NULL) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) val = strchr(ptr, '='); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (val) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *val = 0; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap[ptr] = val + 1; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap[ptr] = "TRUE"; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ptr = strtok(NULL, ","); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) free(str); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt); 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = AttachMountAtPath(mnt, abs_path); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::umount(const char* path) { 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = DetachMountAtPath(path); 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Read(buf, nbytes, &cnt); 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Write(buf, nbytes, &cnt); 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fstat(int fd, struct stat* buf) { 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->GetStat(buf); 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int KernelProxy::ftruncate(int fd, off_t length) { 419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FTruncate(length); 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fsync(int fd) { 436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FSync(); 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::isatty(int fd) { 453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->IsaTTY(); 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::ioctl(int d, int request, char* argp) { 470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(d, &handle); 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->Ioctl(request, argp); 478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) off_t new_offset; 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Seek(offset, whence, &new_offset); 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new_offset; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::unlink(const char* path) { 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Unlink(rel); 515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::remove(const char* path) { 524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Remove(rel); 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(noelallen): Needs implementation. 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fchmod(int fd, int mode) { 544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(fd, &handle); 546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::access(const char* path, int amode) { 5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Path rel; 557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 562eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = mnt->Access(rel, amode); 565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(noelallen): Needs implementation. 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::link(const char* oldpath, const char* newpath) { 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::symlink(const char* oldpath, const char* newpath) { 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void* KernelProxy::mmap(void* addr, 584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t length, 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int prot, 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int flags, 587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int fd, 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset) { 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We shouldn't be getting anonymous mmaps here. 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((flags & MAP_ANONYMOUS) == 0); 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(fd != -1); 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MAP_FAILED; 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* new_addr; 6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return MAP_FAILED; 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_addr; 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::munmap(void* addr, size_t length) { 61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: The comment below is from a previous discarded implementation that 61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tracks mmap'd regions. For simplicity, we no longer do this; because we 61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "snapshot" the contents of the file in mmap(), and don't support 61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // write-back or updating the mapped region when the file is written, holding 61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on to the KernelHandle is pointless. 61690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If we ever do, these threading issues should be considered. 61890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WARNING: this function may be called by free(). 62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is a potential deadlock scenario: 62390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 1: open() -> takes lock1 -> free() -> takes lock2 62490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 62590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 62690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that open() above could be any function that takes a lock that is 62790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // shared with munmap (this includes munmap!) 62890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 62990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // To prevent this, we avoid taking locks in munmap() that are used by other 63090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nacl_io functions that may call free. Specifically, we only take the 63190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mmap_lock, which is only shared with mmap() above. There is still a 63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // possibility of deadlock if mmap() or munmap() calls free(), so this is not 63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allowed. 63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unfortunately, munmap still needs to acquire other locks; see the call to 63690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // ReleaseHandle below which takes the process lock. This is safe as long as 63790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // this is never executed from free() -- we can be reasonably sure this is 63890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // true, because malloc only makes anonymous mmap() requests, and should only 63990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be munmapping those allocations. We never add to mmap_info_list_ for 64090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anonymous maps, so the unmap_list should always be empty when called from 64190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // free(). 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 645