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), 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit_callback_(NULL), 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit_callback_user_data_(NULL), 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_(NULL), 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_user_data_(NULL), 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) signal_emitter_(new EventEmitter) { 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_)); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sigwinch_handler_.sa_handler = SIG_DFL; 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Clean up the FsFactories. 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end(); 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Error KernelProxy::Init(PepperInterface* ppapi) { 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Error rtn = 0; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi_ = ppapi; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_ = 1; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["memfs"] = new TypedFsFactory<MemFs>; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["dev"] = new TypedFsFactory<DevFs>; 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["html5fs"] = new TypedFsFactory<Html5Fs>; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["httpfs"] = new TypedFsFactory<HttpFs>; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem root_fs; 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = MountInternal("", "/", "passthroughfs", 0, NULL, false, &root_fs); 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = MountInternal("", "/dev", "dev", 0, NULL, false, &fs); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(false); 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dev_fs_ = sdk_util::static_scoped_ref_cast<DevFs>(fs); 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Create the filesystem nodes for / and /dev afterward. They can't be 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // created the normal way because the dev filesystem didn't exist yet. 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = CreateFsNode(root_fs); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(false); 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rtn = CreateFsNode(dev_fs_); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rtn != 0) 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open the first three in order to get STDIN, STDOUT, STDERR 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int fd; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fd = open("/dev/stdin", O_RDONLY, 0); 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 0); 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fd = open("/dev/stdout", O_WRONLY, 0); 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 1); 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fd = open("/dev/stderr", O_WRONLY, 0); 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 2); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 122bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifdef PROVIDES_SOCKET_API 123bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch host_resolver_.Init(ppapi_); 124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_fs_.reset(new StreamFs()); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int result = stream_fs_->Init(args); 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = result; 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return rtn; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::RegisterFsType(const char* fs_type, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fuse_operations* fuse_ops) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter != factories_.end()) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_[fs_type] = new FuseFsFactory(fuse_ops); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::UnregisterFsType(const char* fs_type) { 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == factories_.end()) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete iter->second; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_.erase(iter); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid KernelProxy::SetExitCallback(nacl_io_exit_callback_t exit_callback, 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void* user_data) { 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit_callback_ = exit_callback; 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit_callback_user_data_ = user_data; 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid KernelProxy::SetMountCallback(nacl_io_mount_callback_t mount_callback, 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void* user_data) { 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_ = mount_callback; 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_user_data_ = user_data; 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open_resource(const char* path) { 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->OpenResource(rel, &node); 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OpenResource failed, try Open(). 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Open(rel, O_RDONLY, &node); 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Init(O_RDONLY); 1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint KernelProxy::open(const char* path, int open_flags, mode_t mode) { 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Error error = AcquireFsAndNode(path, open_flags, mode, &fs, &node); 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Init(open_flags); 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int KernelProxy::pipe(int pipefds[2]) { 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PipeNode* pipe = new PipeNode(stream_fs_.get()); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(pipe); 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pipe->Init(O_RDWR) == 0) { 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node)); 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node)); 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Should never fail, but... 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) { 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EACCES; 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[0] = AllocateFD(handle0); 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[1] = AllocateFD(handle1); 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return 0; 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = ENOSYS; 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::close(int fd) { 246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove the FD from the process open file descriptor map 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeFD(fd); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup(int oldfd) { 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &handle, &path); 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup2(int oldfd, int newfd) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's the same file handle, just return 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (oldfd == newfd) 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return newfd; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle old_handle; 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string old_path; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &old_handle, &old_path); 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FreeAndReassignFD(newfd, old_handle, old_path); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return newfd; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::chdir(const char* path) { 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = SetCWD(path); 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid KernelProxy::exit(int status) { 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (exit_callback_) 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit_callback_(status, exit_callback_user_data_); 298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getcwd(char* buf, size_t size) { 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (NULL == buf) { 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EFAULT; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string cwd = GetCWD(); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the buffer is large enough 3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (size <= cwd.size()) { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ERANGE; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch strcpy(buf, cwd.c_str()); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buf; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getwd(char* buf) { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NULL == buf) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EFAULT; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getcwd(buf, MAXPATHLEN); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::chmod(const char* path, mode_t mode) { 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int fd = open(path, O_RDONLY, mode); 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fchmod(fd, mode); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mkdir(const char* path, mode_t mode) { 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Mkdir(rel, mode); 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::rmdir(const char* path) { 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rmdir(rel); 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::stat(const char* path, struct stat* buf) { 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int fd = open(path, O_RDONLY, 0); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fstat(fd, buf); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mount(const char* source, 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* target, 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* filesystemtype, 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned long mountflags, 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* data) { 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Error error = MountInternal( 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) source, target, filesystemtype, mountflags, data, true, &fs); 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) { 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) errno = error; 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return -1; 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return 0; 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Error KernelProxy::MountInternal(const char* source, 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* target, 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* filesystemtype, 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned long mountflags, 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const void* data, 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool create_fs_node, 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem* out_filesystem) { 4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string abs_path = GetAbsParts(target).Join(); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a factory of that type 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator factory = factories_.find(filesystemtype); 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (factory == factories_.end()) { 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_ERROR("Unknown filesystem type: %s", filesystemtype); 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return ENODEV; 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create a map of settings 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringMap_t smap; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap["SOURCE"] = source; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data) { 43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> elements; 43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (std::vector<std::string>::const_iterator it = elements.begin(); 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != elements.end(); 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t location = it->find('='); 44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (location != std::string::npos) { 44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string key = it->substr(0, location); 44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string val = it->substr(location + 1); 44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[key] = val; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[*it] = "TRUE"; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.string_map = smap; 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = factory->second->CreateFilesystem(args, &fs); 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AttachFsAtPath(fs, abs_path); 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (create_fs_node) { 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = CreateFsNode(fs); 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (error) { 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DetachFsAtPath(abs_path, &fs); 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *out_filesystem = fs; 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (mount_callback_) { 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_(source, 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target, 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch filesystemtype, 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mountflags, 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data, 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fs->dev(), 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mount_callback_user_data_); 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) { 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assert(dev_fs_); 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return dev_fs_->CreateFsNode(fs.get()); 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::umount(const char* path) { 494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedFilesystem fs; 495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Error error = DetachFsAtPath(path, &fs); 4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error = dev_fs_->DestroyFsNode(fs.get()); 502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error) { 503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore any errors here, just log. 504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG_ERROR("Unable to destroy FsNode: %s", strerror(error)); 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Read(buf, nbytes, &cnt); 519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Write(buf, nbytes, &cnt); 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fstat(int fd, struct stat* buf) { 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) 5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->GetStat(buf); 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 563eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) 573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fchdir(int fd) { 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle; 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(fd, &handle, &path); 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!handle->node()->IsaDir()) { 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = ENOTDIR; 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (path.empty()) { 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EBADF; 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = SetCWD(path); 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // errno is return value from SetCWD 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int KernelProxy::ftruncate(int fd, off_t length) { 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) } 61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FTruncate(length); 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fsync(int fd) { 624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FSync(); 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fdatasync(int fd) { 6418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = ENOSYS; 6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 6438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::isatty(int fd) { 646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 650effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 653effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch error = handle->node()->Isatty(); 654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 656effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 659effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 1; 660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::ioctl(int fd, int request, va_list args) { 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 664bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->node()->VIoctl(request, args); 671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint KernelProxy::futimens(int fd, const struct timespec times[2]) { 6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedKernelHandle handle; 6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Error error = AcquireHandle(fd, &handle); 6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error) { 6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci errno = error; 6841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -1; 6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error = handle->node()->Futimens(times); 6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error) { 6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci errno = error; 6901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -1; 6911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) off_t new_offset; 705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Seek(offset, whence, &new_offset); 706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new_offset; 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::unlink(const char* path) { 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 7177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Unlink(rel); 725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::truncate(const char* path, off_t len) { 7341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int fd = open(path, O_WRONLY, 0); 7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (-1 == fd) 7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result = ftruncate(fd, len); 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd); 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 7418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::lstat(const char* path, struct stat* buf) { 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return stat(path, buf); 7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::rename(const char* path, const char* newpath) { 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path rel; 7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem newfs; 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path newrel; 7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AcquireFsAndRelPath(newpath, &newfs, &newrel); 759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (newfs.get() != fs.get()) { 765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Renaming accross mountpoints is not allowed 766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EXDEV; 767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // They already point to the same path 771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rel == newrel) 772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rename(rel, newrel); 775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 7818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::remove(const char* path) { 7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Remove(rel); 794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint KernelProxy::fchmod(int fd, mode_t mode) { 803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(fd, &handle); 805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error = handle->node()->Fchmod(mode); 8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error) { 8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci errno = error; 8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -1; 8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::fcntl(int fd, int request, va_list args) { 8201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Error error = 0; 8211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // F_GETFD and F_SETFD are descriptor specific flags that 823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // are stored in the KernelObject's decriptor map unlike 8241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // F_GETFL and F_SETFL which are handle specific. 8251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (request) { 8261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_GETFD: { 8271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int rtn = -1; 8281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = GetFDFlags(fd, &rtn); 8291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 8301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 8311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 8321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return rtn; 8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_SETFD: { 8361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int flags = va_arg(args, int); 8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = SetFDFlags(fd, flags); 8381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 8391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 8401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 8411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return 0; 8431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 8451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 84668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle; 8471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = AcquireHandle(fd, &handle); 84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (error) { 84968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = error; 85068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 85168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 85268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int rtn = 0; 8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->VFcntl(request, &rtn, args); 8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return rtn; 86168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 86268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::access(const char* path, int amode) { 8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct stat buf; 8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rtn = stat(path, &buf); 8661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rtn != 0) 8671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return rtn; 868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (((amode & R_OK) && !(buf.st_mode & S_IREAD)) || 8701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ((amode & W_OK) && !(buf.st_mode & S_IWRITE)) || 8711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ((amode & X_OK) && !(buf.st_mode & S_IEXEC))) { 8721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci errno = EACCES; 873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 875eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::readlink(const char* path, char* buf, size_t count) { 880116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("readlink is not implemented."); 8818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = EINVAL; 8828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 8838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint KernelProxy::utimens(const char* path, const struct timespec times[2]) { 8861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int fd = open(path, O_RDONLY, 0); 8871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (-1 == fd) 8881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return -1; 8891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int result = futimens(fd, times); 8911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci close(fd); 8921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result; 8938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 895eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(noelallen): Needs implementation. 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::link(const char* oldpath, const char* newpath) { 897116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("link is not implemented."); 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::symlink(const char* oldpath, const char* newpath) { 903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("symlink is not implemented."); 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void* KernelProxy::mmap(void* addr, 909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t length, 910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int prot, 911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int flags, 912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int fd, 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset) { 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We shouldn't be getting anonymous mmaps here. 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((flags & MAP_ANONYMOUS) == 0); 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(fd != -1); 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MAP_FAILED; 923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* new_addr; 9267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return MAP_FAILED; 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_addr; 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::munmap(void* addr, size_t length) { 93690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: The comment below is from a previous discarded implementation that 93790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tracks mmap'd regions. For simplicity, we no longer do this; because we 93890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "snapshot" the contents of the file in mmap(), and don't support 93990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // write-back or updating the mapped region when the file is written, holding 94090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on to the KernelHandle is pointless. 94190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 94290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If we ever do, these threading issues should be considered. 94390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 94490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 94590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WARNING: this function may be called by free(). 94690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 94790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is a potential deadlock scenario: 94890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 1: open() -> takes lock1 -> free() -> takes lock2 94990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 95090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 95190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that open() above could be any function that takes a lock that is 95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // shared with munmap (this includes munmap!) 95390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 95490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // To prevent this, we avoid taking locks in munmap() that are used by other 95590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nacl_io functions that may call free. Specifically, we only take the 95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mmap_lock, which is only shared with mmap() above. There is still a 95790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // possibility of deadlock if mmap() or munmap() calls free(), so this is not 95890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allowed. 95990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 96090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unfortunately, munmap still needs to acquire other locks; see the call to 96190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // ReleaseHandle below which takes the process lock. This is safe as long as 96290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // this is never executed from free() -- we can be reasonably sure this is 96390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // true, because malloc only makes anonymous mmap() requests, and should only 96490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be munmapping those allocations. We never add to mmap_info_list_ for 96590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anonymous maps, so the unmap_list should always be empty when called from 96690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // free(). 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 970bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcflush(int fd, int queue_selector) { 971bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 972bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 973bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 974bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 975bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 976bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 977bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 978bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcflush(queue_selector); 979bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 980bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 981bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 982bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 983bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 984bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 985bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 986bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 987bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 988bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 989bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 990bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 991bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 992bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 993bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 994bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 995bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcgetattr(termios_p); 996bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 997bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 998bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 999bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 1000bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1001bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 1002bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1003bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::tcsetattr(int fd, 1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int optional_actions, 1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const struct termios* termios_p) { 1007bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 1008bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 1009bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 1010bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 1011bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 1012bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 1013bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1014bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcsetattr(optional_actions, termios_p); 1015bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 1016bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 1017bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 1018bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 1019bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1020bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 1021bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1022bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 10233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int KernelProxy::kill(pid_t pid, int sig) { 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Currently we don't even pretend that other processes exist 10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // so we can only send a signal to outselves. For kill(2) 10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // pid 0 means the current process group and -1 means all the 10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // processes we have permission to send signals to. 10283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (pid != getpid() && pid != -1 && pid != 0) { 10293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = ESRCH; 10303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Raise an event so that select/poll get interrupted. 103468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AUTO_LOCK(signal_emitter_->GetLock()) 103568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_->RaiseEvents_Locked(POLLERR); 10363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (sig) { 10373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: 1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (sigwinch_handler_.sa_handler != SIG_IGN && 1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler != SIG_DFL) { 1040f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler(SIGWINCH); 1041f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 10423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 10433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR1: 10453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR2: 10463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 10473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 1049116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("Unsupported signal: %d", sig); 10503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 10513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 10543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1056cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::sigaction(int signum, 1057cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const struct sigaction* action, 1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct sigaction* oaction) { 1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_flags & SA_SIGINFO) { 1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We don't support SA_SIGINFO (sa_sigaction field) yet 1061f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (signum) { 10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Handled signals. 10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: { 1068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) 1069f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *oaction = sigwinch_handler_; 1070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action) { 1071f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_ = *action; 1072f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 10743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Known signals 10773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGHUP: 10783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGINT: 10793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPIPE: 10803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPOLL: 10813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPROF: 10823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTERM: 10833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGCHLD: 10843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGURG: 10853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGFPE: 10863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGILL: 10873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGQUIT: 10883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGSEGV: 10893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTRAP: 1090f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_handler != SIG_DFL) { 1091f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Trying to set this action to anything other than SIG_DFL 1092f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is not yet supported. 1093116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("sigaction on signal %d != SIG_DFL not supported.", sig); 1094f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1095f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1098f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) { 1099f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memset(oaction, 0, sizeof(*oaction)); 1100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) oaction->sa_handler = SIG_DFL; 1101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 1103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // KILL and STOP cannot be handled 1105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGKILL: 1106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGSTOP: 1107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("sigaction on SIGKILL/SIGSTOP not supported."); 1108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 11103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Unknown signum 11133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 1114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 11153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 11163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef PROVIDES_SOCKET_API 1118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::select(int nfds, 1120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* readfds, 1121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* writefds, 1122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) fd_set* exceptfds, 1123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) struct timeval* timeout) { 112468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<pollfd> pollfds; 112568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 112668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int fd = 0; fd < nfds; fd++) { 11273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch int events = 0; 1128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (readfds && FD_ISSET(fd, readfds)) { 11293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLIN; 1130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, readfds); 1131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 11323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (writefds && FD_ISSET(fd, writefds)) { 11343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLOUT; 1135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, writefds); 1136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 11373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (exceptfds && FD_ISSET(fd, exceptfds)) { 11393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLERR | POLLHUP; 1140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FD_CLR(fd, exceptfds); 1141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 11423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 114368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 114468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd info; 114568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.fd = fd; 114668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.events = events; 114768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfds.push_back(info); 11483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 114968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 11503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 115168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // NULL timeout signals wait forever. 115268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int ms_timeout = -1; 115368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (timeout != NULL) { 115468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 11553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 115668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the timeout is invalid or too long (larger than signed 32 bit). 115768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 1158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) || 1159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (ms >= INT_MAX)) { 1160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG_TRACE("Invalid timeout: tv_sec=%d tv_usec=%d.", 1161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeout->tv_sec, 1162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeout->tv_usec); 116368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EINVAL; 116468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 11653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 116768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ms_timeout = static_cast<int>(ms); 11683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 117068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 117168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result == -1) 117268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 11733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 117468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_cnt = 0; 117568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t index = 0; index < pollfds.size(); index++) { 117668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd* info = &pollfds[index]; 117768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLIN) { 117868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, readfds); 117968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 118168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLOUT) { 118268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, writefds); 118368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 118568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & (POLLHUP | POLLERR)) { 118668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, exceptfds); 118768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 119168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return event_cnt; 119268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 119468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct PollInfo { 119568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo() : index(-1) {}; 11963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 119768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<struct pollfd*> fds; 119868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index; 119968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 12003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 120168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 12023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) { 120468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventPollMap_t event_map; 12053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 120668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<EventRequest> requests; 12073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch size_t event_cnt = 0; 120868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 120968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 12103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ScopedKernelHandle handle; 121168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = &fds[index]; 121268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = AcquireHandle(fd_info->fd, &handle); 121368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 121468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = 0; 12153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 12163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If the node isn't open, or somehow invalid, mark it so. 12173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (err != 0) { 121868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 12193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 12203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 12213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 12233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If it's already signaled, then just capture the event 122468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 122568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int events = POLLIN | POLLOUT; 122668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (emitter) 122768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events = emitter->GetEventStatus(); 122868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 122968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events & fd_info->events) { 123068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events & fd_info->events; 12313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 12323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 12333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 123568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == emitter) { 123668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 12373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 12383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 12393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 124068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 124168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Otherwise try to track it. 124268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* info = &event_map[emitter.get()]; 124368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->index == -1) { 124468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest request; 124568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.emitter = emitter; 124668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.filter = fd_info->events; 124768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.events = 0; 124868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 124968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->index = requests.size(); 125068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests.push_back(request); 125168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 125268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->fds.push_back(fd_info); 125368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests[info->index].filter |= fd_info->events; 12543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 125668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If nothing is signaled, then we must wait on the event map 12573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (0 == event_cnt) { 125868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventListenerPoll wait; 125968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 126068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((err != 0) && (err != ETIMEDOUT)) { 126168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = err; 12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 126468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 126568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t rindex = 0; rindex < requests.size(); rindex++) { 126668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest* request = &requests[rindex]; 126768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (request->events) { 126868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* poll_info = &event_map[request->emitter.get()]; 126968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 127068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = poll_info->fds[findex]; 127168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint32_t events = fd_info->events & request->events; 127268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 127368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events; 127468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 127568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 127668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 127768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 127868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 12793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 12803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 12813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return event_cnt; 12823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 12833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Socket Functions 1285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 12924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 12934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 12944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 12964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PP_Resource new_sock = 0; 12994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Accept(&new_sock, addr, len); 13004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 13014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 13024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 13034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 13044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock); 13064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The SocketNode now holds a reference to the new socket 13084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // so we release ours. 13094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ppapi_->ReleaseResource(new_sock); 1310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = sock->Init(O_RDWR); 13114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 13124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 13134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 13144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 13154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node)); 1318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = new_handle->Init(O_RDWR); 13191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error != 0) { 13201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 13211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 13221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 13231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 13244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(new_handle); 1325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Bind(addr, len); 13383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 13534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 13544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 13554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 13574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Connect(addr, len); 13604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 13614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 13623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void KernelProxy::freeaddrinfo(struct addrinfo* res) { 13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.freeaddrinfo(res); 13705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int KernelProxy::getaddrinfo(const char* node, 1373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const char* service, 13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const struct addrinfo* hints, 13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo** res) { 13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.getaddrinfo(node, service, hints, res); 13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint KernelProxy::getnameinfo(const struct sockaddr *sa, 13801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socklen_t salen, 13811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char *host, 13821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t hostlen, 13831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char *serv, 13841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t servlen, 13851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int flags) { 13861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return host_resolver_.getnameinfo(sa, salen, host, hostlen, serv, servlen, 13871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flags); 13881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 13891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1390bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstruct hostent* KernelProxy::gethostbyname(const char* name) { 1391bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return host_resolver_.gethostbyname(name); 1392bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1393bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetPeerName(addr, len); 14053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 14063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 14073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetSockName(addr, len); 14243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 14253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 14263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockopt(int fd, 14334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int lvl, 14344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int optname, 14354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void* optval, 14364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) socklen_t* len) { 1437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval || NULL == len) { 1438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len); 14474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 14484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 14494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 14504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 14514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::listen(int fd, int backlog) { 1456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->Listen(backlog); 14614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 14624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 14634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 14644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 14654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 14664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) { 1470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1481a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Recv(buf, len, flags, &out_len); 14844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1490a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1491a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvfrom(int fd, 1493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct sockaddr* addr, 1497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t* addrlen) { 1498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, recvfrom with a null addr is identical to recv. 1499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return recv(fd, buf, len, flags); 1501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf || NULL == addrlen) { 1504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 15094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 15104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 15114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 15134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 15164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); 15174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 15184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 15193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (NULL == msg) { 1527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 15464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 15474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 15484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 15504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 15534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Send(buf, len, flags, &out_len); 15544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 15554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 15563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1561a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendto(int fd, 1563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* buf, 1564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const struct sockaddr* addr, 1567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t addrlen) { 1568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, sendto with a null addr is identical to send. 1569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return send(fd, buf, len, flags); 1571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 15794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 15804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 15814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 15834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 15864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len); 15874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 15884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 15893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg) { 1597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::setsockopt(int fd, 1610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int lvl, 1611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int optname, 1612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* optval, 1613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t len) { 1614a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval) { 1615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len); 16244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 16254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 16264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 16274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 16284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::shutdown(int fd, int how) { 1633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Shutdown(how); 16383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 16393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 16403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 16413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socket(int domain, int type, int protocol) { 1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int open_flags = O_RDWR; 1653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_CLOEXEC) { 1655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifdef O_CLOEXEC 1656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The NaCl newlib version of fcntl.h doesn't currently define 1657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // O_CLOEXEC. 1658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(sbc): remove this guard once it gets added. 1659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_CLOEXEC; 1660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 1661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_CLOEXEC; 1662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_NONBLOCK) { 1665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_NONBLOCK; 1666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_NONBLOCK; 1667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SocketNode* sock = NULL; 16703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 16713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_DGRAM: 1672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sock = new UdpNode(stream_fs_.get()); 16733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_STREAM: 1676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sock = new TcpNode(stream_fs_.get()); 16773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 16783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_SEQPACKET: 1680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RDM: 1681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RAW: 16823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EPROTONOSUPPORT; 16833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 1684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 1686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 1691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Error rtn = sock->Init(O_RDWR); 16924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (rtn != 0) { 16934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = rtn; 16944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 16953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(stream_fs_, node)); 1698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rtn = handle->Init(open_flags); 16991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rtn != 0) { 17001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = rtn; 17011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 17021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 17031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 17044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(handle); 1705a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1706a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1707a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1708a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == sv) { 1709a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1710a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1711a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1712a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1714a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // socket pairs. Thus, this function always fails. 1715a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_UNIX != domain) { 1716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EPROTONOSUPPORT; 1717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1725a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We cannot reach this point. 1726a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOSYS; 1727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1731a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Error error = AcquireHandle(fd, handle); 1732a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1733a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (error) { 1734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = error; 1735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1736a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1738a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1739a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOTSOCK; 1740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 1744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1746bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // PROVIDES_SOCKET_API 1747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1748bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace_nacl_io 1749