1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file. 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 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> 103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <limits.h> 113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <poll.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <pthread.h> 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <stdio.h> 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <sys/time.h> 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <unistd.h> 173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <iterator> 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/devfs/dev_fs.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/filesystem.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/fusefs/fuse_fs_factory.h" 24bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/host_resolver.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/html5fs/html5_fs.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/httpfs/http_fs.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_handle.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_wrap_real.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "nacl_io/log.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/memfs/mem_fs.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/node.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osmman.h" 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "nacl_io/ossocket.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osstat.h" 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/passthroughfs/passthrough_fs.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/path.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/pepper_interface.h" 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/pipe/pipe_node.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/tcp_node.h" 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/udp_node.h" 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/stream/stream_fs.h" 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/typed_fs_factory.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/auto_lock.h" 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/ref_object.h" 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sdk_util/string_util.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MAXPATHLEN 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAXPATHLEN 256 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace nacl_io { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)KernelProxy::KernelProxy() 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : dev_(0), 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ppapi_(NULL), 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) exit_handler_(NULL), 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) signal_emitter_(new EventEmitter) { 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_)); 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sigwinch_handler_.sa_handler = SIG_DFL; 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Clean up the FsFactories. 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end(); 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Error KernelProxy::Init(PepperInterface* ppapi) { 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Error rtn = 0; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi_ = ppapi; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_ = 1; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["memfs"] = new TypedFsFactory<MemFs>; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["dev"] = new TypedFsFactory<DevFs>; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["html5fs"] = new TypedFsFactory<Html5Fs>; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["httpfs"] = new TypedFsFactory<HttpFs>; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem root_fs; 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = MountInternal("", "/", "passthroughfs", 0, NULL, false, &root_fs); 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = MountInternal("", "/dev", "dev", 0, NULL, false, &fs); 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(false); 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dev_fs_ = sdk_util::static_scoped_ref_cast<DevFs>(fs); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create the filesystem nodes for / and /dev afterward. They can't be 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // created the normal way because the dev filesystem didn't exist yet. 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = CreateFsNode(root_fs); 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(false); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = CreateFsNode(dev_fs_); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open the first three in order to get STDIN, STDOUT, STDERR 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int fd; 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdin", O_RDONLY); 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 0); 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdout", O_WRONLY); 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 1); 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stderr", O_WRONLY); 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 2); 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifdef PROVIDES_SOCKET_API 120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch host_resolver_.Init(ppapi_); 121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_fs_.reset(new StreamFs()); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int result = stream_fs_->Init(args); 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = result; 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return rtn; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::RegisterFsType(const char* fs_type, 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fuse_operations* fuse_ops) { 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter != factories_.end()) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_[fs_type] = new FuseFsFactory(fuse_ops); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::UnregisterFsType(const char* fs_type) { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == factories_.end()) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete iter->second; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_.erase(iter); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool KernelProxy::RegisterExitHandler(nacl_io_exit_handler_t exit_handler, 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void* user_data) { 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (exit_handler_ != NULL) 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_ = exit_handler; 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_user_data_ = user_data; 162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return true; 163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open_resource(const char* path) { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->OpenResource(rel, &node); 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OpenResource failed, try Open(). 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Open(rel, O_RDONLY, &node); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Init(O_RDONLY); 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::open(const char* path, int open_flags) { 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndNode(path, open_flags, &fs, &node); 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Init(open_flags); 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int KernelProxy::pipe(int pipefds[2]) { 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PipeNode* pipe = new PipeNode(stream_fs_.get()); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(pipe); 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pipe->Init(O_RDWR) == 0) { 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node)); 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node)); 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Should never fail, but... 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) { 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EACCES; 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[0] = AllocateFD(handle0); 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[1] = AllocateFD(handle1); 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return 0; 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = ENOSYS; 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::close(int fd) { 240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove the FD from the process open file descriptor map 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeFD(fd); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup(int oldfd) { 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &handle, &path); 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup2(int oldfd, int newfd) { 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's the same file handle, just return 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (oldfd == newfd) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return newfd; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle old_handle; 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string old_path; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &old_handle, &old_path); 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FreeAndReassignFD(newfd, old_handle, old_path); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return newfd; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::chdir(const char* path) { 2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = SetCWD(path); 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid KernelProxy::exit(int status) { 290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (exit_handler_) 291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_(status, exit_handler_user_data_); 292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getcwd(char* buf, size_t size) { 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (NULL == buf) { 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EFAULT; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string cwd = GetCWD(); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the buffer is large enough 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (size <= cwd.size()) { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ERANGE; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch strcpy(buf, cwd.c_str()); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buf; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getwd(char* buf) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NULL == buf) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EFAULT; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getcwd(buf, MAXPATHLEN); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::chmod(const char* path, mode_t mode) { 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int fd = KernelProxy::open(path, O_RDONLY); 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fchmod(fd, mode); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::utime(const char* filename, const struct utimbuf* times) { 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mkdir(const char* path, mode_t mode) { 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Mkdir(rel, mode); 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::rmdir(const char* path) { 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rmdir(rel); 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::stat(const char* path, struct stat* buf) { 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open(path, O_RDONLY); 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fstat(fd, buf); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mount(const char* source, 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* target, 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* filesystemtype, 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned long mountflags, 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* data) { 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Error error = MountInternal( 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) source, target, filesystemtype, mountflags, data, true, &fs); 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) { 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) errno = error; 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return -1; 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0; 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Error KernelProxy::MountInternal(const char* source, 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* target, 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* filesystemtype, 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned long mountflags, 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const void* data, 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool create_fs_node, 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem* out_filesystem) { 4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string abs_path = GetAbsParts(target).Join(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a factory of that type 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator factory = factories_.find(filesystemtype); 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (factory == factories_.end()) 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ENODEV; 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create a map of settings 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringMap_t smap; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap["SOURCE"] = source; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data) { 42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> elements; 43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (std::vector<std::string>::const_iterator it = elements.begin(); 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != elements.end(); 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t location = it->find('='); 43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (location != std::string::npos) { 43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string key = it->substr(0, location); 43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string val = it->substr(location + 1); 43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[key] = val; 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[*it] = "TRUE"; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.string_map = smap; 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = factory->second->CreateFilesystem(args, &fs); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AttachFsAtPath(fs, abs_path); 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (create_fs_node) { 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = CreateFsNode(fs); 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *out_filesystem = fs; 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) { 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(dev_fs_); 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return dev_fs_->CreateFsNode(fs.get()); 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::umount(const char* path) { 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Error error = DetachFsAtPath(path, &fs); 4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = dev_fs_->DestroyFsNode(fs.get()); 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) { 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore any errors here, just log. 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG_ERROR("Unable to destroy FsNode: %s", strerror(error)); 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Read(buf, nbytes, &cnt); 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Write(buf, nbytes, &cnt); 520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fstat(int fd, struct stat* buf) { 529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->GetStat(buf); 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) 556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fchdir(int fd) { 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle; 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(fd, &handle, &path); 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!handle->node()->IsaDir()) { 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = ENOTDIR; 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (path.empty()) { 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EBADF; 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = SetCWD(path); 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // errno is return value from SetCWD 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 5878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int KernelProxy::ftruncate(int fd, off_t length) { 590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 59690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FTruncate(length); 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 60290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fsync(int fd) { 607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FSync(); 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fdatasync(int fd) { 6248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = ENOSYS; 6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::isatty(int fd) { 629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 633effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 636effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch error = handle->node()->Isatty(); 637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 639effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 1; 643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::ioctl(int fd, int request, va_list args) { 646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 647bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->node()->VIoctl(request, args); 654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) off_t new_offset; 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Seek(offset, whence, &new_offset); 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new_offset; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::unlink(const char* path) { 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 6837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Unlink(rel); 691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::truncate(const char* path, off_t len) { 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int fd = KernelProxy::open(path, O_WRONLY); 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (-1 == fd) 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result = ftruncate(fd, len); 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd); 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 7078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::lstat(const char* path, struct stat* buf) { 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return stat(path, buf); 7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::rename(const char* path, const char* newpath) { 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path rel; 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem newfs; 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path newrel; 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AcquireFsAndRelPath(newpath, &newfs, &newrel); 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (newfs.get() != fs.get()) { 731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Renaming accross mountpoints is not allowed 732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EXDEV; 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // They already point to the same path 737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rel == newrel) 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rename(rel, newrel); 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::remove(const char* path) { 7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 7527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Remove(rel); 760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(noelallen): Needs implementation. 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fchmod(int fd, int mode) { 770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(fd, &handle); 772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::fcntl(int fd, int request, va_list args) { 7811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Error error = 0; 7821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // F_GETFD and F_SETFD are descriptor specific flags that 784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // are stored in the KernelObject's decriptor map unlike 7851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // F_GETFL and F_SETFL which are handle specific. 7861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (request) { 7871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_GETFD: { 7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int rtn = -1; 7891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = GetFDFlags(fd, &rtn); 7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 7911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 7921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 7931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return rtn; 7951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_SETFD: { 7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int flags = va_arg(args, int); 7981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = SetFDFlags(fd, flags); 7991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 8001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 8011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 8021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return 0; 8041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 80768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle; 8081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = AcquireHandle(fd, &handle); 80968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (error) { 81068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = error; 81168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 81268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 81368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int rtn = 0; 8154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->VFcntl(request, &rtn, args); 8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 8184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return rtn; 82268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 82368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::access(const char* path, int amode) { 8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Path rel; 827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Access(rel, amode); 835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::readlink(const char* path, char* buf, size_t count) { 8438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = EINVAL; 8448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 8458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::utimes(const char* filename, const struct timeval times[2]) { 8488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = EINVAL; 8498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 8508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(noelallen): Needs implementation. 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::link(const char* oldpath, const char* newpath) { 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::symlink(const char* oldpath, const char* newpath) { 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void* KernelProxy::mmap(void* addr, 864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t length, 865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int prot, 866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int flags, 867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int fd, 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset) { 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We shouldn't be getting anonymous mmaps here. 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((flags & MAP_ANONYMOUS) == 0); 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(fd != -1); 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MAP_FAILED; 878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* new_addr; 8817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 883eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return MAP_FAILED; 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_addr; 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::munmap(void* addr, size_t length) { 89190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: The comment below is from a previous discarded implementation that 89290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tracks mmap'd regions. For simplicity, we no longer do this; because we 89390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "snapshot" the contents of the file in mmap(), and don't support 89490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // write-back or updating the mapped region when the file is written, holding 89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on to the KernelHandle is pointless. 89690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 89790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If we ever do, these threading issues should be considered. 89890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 89990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 90090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WARNING: this function may be called by free(). 90190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 90290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is a potential deadlock scenario: 90390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 1: open() -> takes lock1 -> free() -> takes lock2 90490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 90590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 90690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that open() above could be any function that takes a lock that is 90790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // shared with munmap (this includes munmap!) 90890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 90990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // To prevent this, we avoid taking locks in munmap() that are used by other 91090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nacl_io functions that may call free. Specifically, we only take the 91190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mmap_lock, which is only shared with mmap() above. There is still a 91290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // possibility of deadlock if mmap() or munmap() calls free(), so this is not 91390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allowed. 91490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 91590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unfortunately, munmap still needs to acquire other locks; see the call to 91690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // ReleaseHandle below which takes the process lock. This is safe as long as 91790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // this is never executed from free() -- we can be reasonably sure this is 91890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // true, because malloc only makes anonymous mmap() requests, and should only 91990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be munmapping those allocations. We never add to mmap_info_list_ for 92090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anonymous maps, so the unmap_list should always be empty when called from 92190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // free(). 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 925bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcflush(int fd, int queue_selector) { 926bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 927bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 928bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 929bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 930bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 931bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 932bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 933bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcflush(queue_selector); 934bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 935bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 936bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 937bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 938bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 939bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 940bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 941bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 942bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 943bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 944bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 945bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 946bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 947bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 948bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 949bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 950bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcgetattr(termios_p); 951bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 952bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 953bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 954bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 955bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 956bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 957bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 958bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::tcsetattr(int fd, 960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int optional_actions, 961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const struct termios* termios_p) { 962bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 963bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 964bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 965bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 966bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 967bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 968bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 969bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcsetattr(optional_actions, termios_p); 970bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 971bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 972bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 973bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 974bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 975bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 976bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 977bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 9783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int KernelProxy::kill(pid_t pid, int sig) { 9793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Currently we don't even pretend that other processes exist 9803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // so we can only send a signal to outselves. For kill(2) 9813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // pid 0 means the current process group and -1 means all the 9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // processes we have permission to send signals to. 9833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (pid != getpid() && pid != -1 && pid != 0) { 9843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = ESRCH; 9853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 9863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Raise an event so that select/poll get interrupted. 98968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AUTO_LOCK(signal_emitter_->GetLock()) 99068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_->RaiseEvents_Locked(POLLERR); 9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (sig) { 9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: 993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (sigwinch_handler_.sa_handler != SIG_IGN && 994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler != SIG_DFL) { 995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler(SIGWINCH); 996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 9983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR1: 10003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR2: 10013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 10023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 10043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 10083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::sigaction(int signum, 1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const struct sigaction* action, 1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct sigaction* oaction) { 1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_flags & SA_SIGINFO) { 1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We don't support SA_SIGINFO (sa_sigaction field) yet 1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (signum) { 10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Handled signals. 10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: { 1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) 1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *oaction = sigwinch_handler_; 1024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action) { 1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_ = *action; 1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 10283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Known signals 10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGHUP: 10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGINT: 10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPIPE: 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPOLL: 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPROF: 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTERM: 10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGCHLD: 10383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGURG: 10393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGFPE: 10403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGILL: 10413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGQUIT: 10423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGSEGV: 10433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTRAP: 1044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_handler != SIG_DFL) { 1045f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Trying to set this action to anything other than SIG_DFL 1046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is not yet supported. 1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1048f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1050f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) { 1052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memset(oaction, 0, sizeof(*oaction)); 1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) oaction->sa_handler = SIG_DFL; 1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // KILL and STOP cannot be handled 1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGKILL: 1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGSTOP: 1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1061f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 10623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Unknown signum 10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 1066f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1069a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef PROVIDES_SOCKET_API 1070ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::select(int nfds, 1072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* readfds, 1073cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* writefds, 1074cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* exceptfds, 1075cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) struct timeval* timeout) { 107668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<pollfd> pollfds; 107768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 107868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int fd = 0; fd < nfds; fd++) { 10793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch int events = 0; 1080c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (readfds && FD_ISSET(fd, readfds)) { 10813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLIN; 1082c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, readfds); 1083c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 10843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1085c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (writefds && FD_ISSET(fd, writefds)) { 10863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLOUT; 1087c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, writefds); 1088c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 10893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1090c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (exceptfds && FD_ISSET(fd, exceptfds)) { 10913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLERR | POLLHUP; 1092c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, exceptfds); 1093c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 10943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 109568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 109668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd info; 109768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.fd = fd; 109868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.events = events; 109968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfds.push_back(info); 11003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 110168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 11023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 110368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // NULL timeout signals wait forever. 110468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int ms_timeout = -1; 110568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (timeout != NULL) { 110668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 11073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 110868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the timeout is invalid or too long (larger than signed 32 bit). 110968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 1110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) || 1111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (ms >= INT_MAX)) { 111268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EINVAL; 111368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 11143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 111668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ms_timeout = static_cast<int>(ms); 11173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 111968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 112068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result == -1) 112168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 11223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 112368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_cnt = 0; 112468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t index = 0; index < pollfds.size(); index++) { 112568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd* info = &pollfds[index]; 112668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLIN) { 112768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, readfds); 112868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 113068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLOUT) { 113168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, writefds); 113268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 113468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & (POLLHUP | POLLERR)) { 113568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, exceptfds); 113668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 114068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return event_cnt; 114168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 114368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct PollInfo { 114468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo() : index(-1) {}; 11453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 114668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<struct pollfd*> fds; 114768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index; 114868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 11493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 115068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 11513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) { 115368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventPollMap_t event_map; 11543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 115568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<EventRequest> requests; 11563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch size_t event_cnt = 0; 115768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 115868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 11593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ScopedKernelHandle handle; 116068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = &fds[index]; 116168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = AcquireHandle(fd_info->fd, &handle); 116268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 116368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = 0; 11643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If the node isn't open, or somehow invalid, mark it so. 11663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (err != 0) { 116768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 11683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If it's already signaled, then just capture the event 117368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 117468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int events = POLLIN | POLLOUT; 117568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (emitter) 117668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events = emitter->GetEventStatus(); 117768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 117868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events & fd_info->events) { 117968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events & fd_info->events; 11803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 118468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == emitter) { 118568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 11863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 118968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 119068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Otherwise try to track it. 119168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* info = &event_map[emitter.get()]; 119268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->index == -1) { 119368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest request; 119468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.emitter = emitter; 119568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.filter = fd_info->events; 119668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.events = 0; 119768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 119868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->index = requests.size(); 119968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests.push_back(request); 120068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 120168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->fds.push_back(fd_info); 120268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests[info->index].filter |= fd_info->events; 12033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 120568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If nothing is signaled, then we must wait on the event map 12063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (0 == event_cnt) { 120768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventListenerPoll wait; 120868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 120968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((err != 0) && (err != ETIMEDOUT)) { 121068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = err; 12113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 121368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 121468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t rindex = 0; rindex < requests.size(); rindex++) { 121568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest* request = &requests[rindex]; 121668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (request->events) { 121768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* poll_info = &event_map[request->emitter.get()]; 121868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 121968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = poll_info->fds[findex]; 122068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint32_t events = fd_info->events & request->events; 122168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 122268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events; 122368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 122468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 122568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 122668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 122768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 12303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return event_cnt; 12313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 12323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Socket Functions 1234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 12414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 12424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 12434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 12454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PP_Resource new_sock = 0; 12484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Accept(&new_sock, addr, len); 12494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 12504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 12514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 12524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 12534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock); 12554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The SocketNode now holds a reference to the new socket 12574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // so we release ours. 12584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ppapi_->ReleaseResource(new_sock); 1259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = sock->Init(O_RDWR); 12604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 12614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 12624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 12634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 12644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 1266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node)); 1267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = new_handle->Init(O_RDWR); 12681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error != 0) { 12691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 12701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 12711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 12721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 12734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(new_handle); 1274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Bind(addr, len); 12873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 12883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 12893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 13024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 13034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 13044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 13064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Connect(addr, len); 13094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 13104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 13113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void KernelProxy::freeaddrinfo(struct addrinfo* res) { 13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.freeaddrinfo(res); 13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::getaddrinfo(const char* node, 1322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* service, 13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const struct addrinfo* hints, 13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo** res) { 13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.getaddrinfo(node, service, hints, res); 13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1328bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstruct hostent* KernelProxy::gethostbyname(const char* name) { 1329bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return host_resolver_.gethostbyname(name); 1330bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1331bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetPeerName(addr, len); 13433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetSockName(addr, len); 13623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockopt(int fd, 13714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int lvl, 13724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int optname, 13734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void* optval, 13744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) socklen_t* len) { 1375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval || NULL == len) { 1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len); 13854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 13864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 13874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 13884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 13894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::listen(int fd, int backlog) { 1394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->Listen(backlog); 13994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 14004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 14014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 14024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 14034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) { 1408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Recv(buf, len, flags, &out_len); 14224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvfrom(int fd, 1431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct sockaddr* addr, 1435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t* addrlen) { 1436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, recvfrom with a null addr is identical to recv. 1437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return recv(fd, buf, len, flags); 1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf || NULL == addrlen) { 1442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); 14554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (NULL == msg) { 1465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1481a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1482a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1487a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1489a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Send(buf, len, flags, &out_len); 14924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendto(int fd, 1501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* buf, 1502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const struct sockaddr* addr, 1505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t addrlen) { 1506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, sendto with a null addr is identical to send. 1507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return send(fd, buf, len, flags); 1509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 15174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 15184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 15194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 15214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 15244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len); 15254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 15264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 15273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg) { 1535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1546a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1547a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::setsockopt(int fd, 1548a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int lvl, 1549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int optname, 1550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* optval, 1551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t len) { 1552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval) { 1553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len); 15624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 15634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 15644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 15654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 15664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 15674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::shutdown(int fd, int how) { 1571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Shutdown(how); 15763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 15773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 15783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socket(int domain, int type, int protocol) { 1585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int open_flags = O_RDWR; 1591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_CLOEXEC) { 1593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifdef O_CLOEXEC 1594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The NaCl newlib version of fcntl.h doesn't currently define 1595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // O_CLOEXEC. 1596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(sbc): remove this guard once it gets added. 1597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_CLOEXEC; 1598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 1599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_CLOEXEC; 1600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_NONBLOCK) { 1603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_NONBLOCK; 1604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_NONBLOCK; 1605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SocketNode* sock = NULL; 16083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 16093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_DGRAM: 1610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sock = new UdpNode(stream_fs_.get()); 16113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_STREAM: 1614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sock = new TcpNode(stream_fs_.get()); 16153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_SEQPACKET: 1618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RDM: 1619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RAW: 16203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EPROTONOSUPPORT; 16213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 1622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 1624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 1629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Error rtn = sock->Init(O_RDWR); 16304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (rtn != 0) { 16314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = rtn; 16324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 16333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(stream_fs_, node)); 1636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rtn = handle->Init(open_flags); 16371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rtn != 0) { 16381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = rtn; 16391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 16401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 16411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 16424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(handle); 1643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == sv) { 1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // socket pairs. Thus, this function always fails. 1653a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_UNIX != domain) { 1654a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EPROTONOSUPPORT; 1655a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1656a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1657a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1659a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1660a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1661a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1662a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We cannot reach this point. 1664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOSYS; 1665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1667a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Error error = AcquireHandle(fd, handle); 1670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (error) { 1672a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = error; 1673a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1674a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1675a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1676a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1677a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOTSOCK; 1678a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1679a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1681a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 1682a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1683a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1684bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // PROVIDES_SOCKET_API 1685a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1686bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace_nacl_io 1687