kernel_proxy.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/memfs/mem_fs.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/node.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osmman.h" 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "nacl_io/ossocket.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osstat.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/passthroughfs/passthrough_fs.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/path.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/pepper_interface.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/pipe/pipe_node.h" 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/tcp_node.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/udp_node.h" 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/stream/stream_fs.h" 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/typed_fs_factory.h" 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/auto_lock.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/ref_object.h" 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sdk_util/string_util.h" 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MAXPATHLEN 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAXPATHLEN 256 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace nacl_io { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_(NULL), 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_(new EventEmitter) { 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_)); 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler = SIG_DFL; 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Clean up the MountFactories. 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end(); 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete ppapi_; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Error KernelProxy::Init(PepperInterface* ppapi) { 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Error rtn = 0; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi_ = ppapi; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_ = 1; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["memfs"] = new TypedFsFactory<MemFs>; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["dev"] = new TypedFsFactory<DevFs>; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["html5fs"] = new TypedFsFactory<Html5Fs>; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["httpfs"] = new TypedFsFactory<HttpFs>; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/", "passthroughfs", 0, NULL); 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/dev", "dev", 0, NULL); 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open the first three in order to get STDIN, STDOUT, STDERR 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int fd; 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdin", O_RDONLY); 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 0); 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdout", O_WRONLY); 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 1); 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stderr", O_WRONLY); 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 2); 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifdef PROVIDES_SOCKET_API 112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch host_resolver_.Init(ppapi_); 113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_mount_.reset(new StreamFs()); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = stream_mount_->Init(args); 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = result; 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return rtn; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::RegisterFsType(const char* fs_type, 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fuse_operations* fuse_ops) { 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter != factories_.end()) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_[fs_type] = new FuseFsFactory(fuse_ops); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KernelProxy::UnregisterFsType(const char* fs_type) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator iter = factories_.find(fs_type); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iter == factories_.end()) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete iter->second; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factories_.erase(iter); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool KernelProxy::RegisterExitHandler(nacl_io_exit_handler_t exit_handler, 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void* user_data) { 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (exit_handler_ != NULL) 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_ = exit_handler; 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_user_data_ = user_data; 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return true; 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open_resource(const char* path) { 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->OpenResource(rel, &node); 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OpenResource failed, try Open(). 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Open(rel, O_RDONLY, &node); 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Init(O_RDONLY); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::open(const char* path, int open_flags) { 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node; 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndNode(path, open_flags, &fs, &node); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(fs, node)); 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Init(open_flags); 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int KernelProxy::pipe(int pipefds[2]) { 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PipeNode* pipe = new PipeNode(stream_mount_.get()); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(pipe); 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pipe->Init(O_RDWR) == 0) { 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Should never fail, but... 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) { 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EACCES; 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[0] = AllocateFD(handle0); 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[1] = AllocateFD(handle1); 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return 0; 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = ENOSYS; 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::close(int fd) { 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove the FD from the process open file descriptor map 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeFD(fd); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup(int oldfd) { 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &handle, &path); 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AllocateFD(handle, path); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup2(int oldfd, int newfd) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's the same file handle, just return 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (oldfd == newfd) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return newfd; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle old_handle; 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string old_path; 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(oldfd, &old_handle, &old_path); 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FreeAndReassignFD(newfd, old_handle, old_path); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return newfd; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::chdir(const char* path) { 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = SetCWD(path); 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid KernelProxy::exit(int status) { 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (exit_handler_) 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch exit_handler_(status, exit_handler_user_data_); 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getcwd(char* buf, size_t size) { 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (NULL == buf) { 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EFAULT; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string cwd = GetCWD(); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the buffer is large enough 2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (size <= cwd.size()) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ERANGE; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch strcpy(buf, cwd.c_str()); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buf; 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getwd(char* buf) { 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NULL == buf) { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EFAULT; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getcwd(buf, MAXPATHLEN); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::chmod(const char* path, mode_t mode) { 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int fd = KernelProxy::open(path, O_RDONLY); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fchmod(fd, mode); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::utime(const char* filename, const struct utimbuf* times) { 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mkdir(const char* path, mode_t mode) { 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Mkdir(rel, mode); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::rmdir(const char* path) { 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rmdir(rel); 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::stat(const char* path, struct stat* buf) { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open(path, O_RDONLY); 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fstat(fd, buf); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mount(const char* source, 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* target, 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* filesystemtype, 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned long mountflags, 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* data) { 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string abs_path = GetAbsParts(target).Join(); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a factory of that type 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsFactoryMap_t::iterator factory = factories_.find(filesystemtype); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (factory == factories_.end()) { 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ENODEV; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create a map of settings 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringMap_t smap; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap["SOURCE"] = source; 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch smap["TARGET"] = abs_path; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data) { 40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> elements; 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (std::vector<std::string>::const_iterator it = elements.begin(); 41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it != elements.end(); ++it) { 41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t location = it->find('='); 41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (location != std::string::npos) { 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string key = it->substr(0, location); 41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string val = it->substr(location + 1); 41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[key] = val; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[*it] = "TRUE"; 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FsInitArgs args; 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.dev = dev_++; 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.string_map = smap; 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.ppapi = ppapi_; 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = factory->second->CreateFilesystem(args, &fs); 4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AttachFsAtPath(fs, abs_path); 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::umount(const char* path) { 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = DetachFsAtPath(path); 4467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Read(buf, nbytes, &cnt); 463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Write(buf, nbytes, &cnt); 481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fstat(int fd, struct stat* buf) { 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->GetStat(buf); 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fchdir(int fd) { 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedKernelHandle handle; 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireHandleAndPath(fd, &handle, &path); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!handle->node()->IsaDir()) { 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = ENOTDIR; 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (path.empty()) { 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = EBADF; 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = SetCWD(path); 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error) { 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // errno is return value from SetCWD 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errno = error; 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int KernelProxy::ftruncate(int fd, off_t length) { 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FTruncate(length); 559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fsync(int fd) { 568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FSync(); 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 581eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::fdatasync(int fd) { 5858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = ENOSYS; 5868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 5878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::isatty(int fd) { 590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 594effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 597effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch error = handle->node()->Isatty(); 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 600effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 603effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 1; 604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::ioctl(int fd, int request, va_list args) { 607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 608bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->node()->VIoctl(request, args); 615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 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) } 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) off_t new_offset; 632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Seek(offset, whence, &new_offset); 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new_offset; 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::unlink(const char* path) { 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Unlink(rel); 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::truncate(const char* path, off_t len) { 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int fd = KernelProxy::open(path, O_WRONLY); 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (-1 == fd) 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return -1; 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result = ftruncate(fd, len); 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd); 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 6688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::lstat(const char* path, struct stat* buf) { 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return stat(path, buf); 6728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 6738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::rename(const char* path, const char* newpath) { 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path rel; 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem newfs; 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Path newrel; 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = AcquireFsAndRelPath(newpath, &newfs, &newrel); 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (newfs.get() != fs.get()) { 692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Renaming accross mountpoints is not allowed 693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EXDEV; 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // They already point to the same path 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rel == newrel) 699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Rename(rel, newrel); 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) { 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = error; 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::remove(const char* path) { 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 7137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Remove(rel); 721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 726eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(noelallen): Needs implementation. 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fchmod(int fd, int mode) { 731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(fd, &handle); 733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int KernelProxy::fcntl(int fd, int request, va_list args) { 7421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Error error = 0; 7431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // F_GETFD and F_SETFD are descirptor specific flags that 7451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // are stored in the KernelObject's decriptor map unlink 7461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // F_GETFL and F_SETFL which are handle specific. 7471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (request) { 7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_GETFD: { 7491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int rtn = -1; 7501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = GetFDFlags(fd, &rtn); 7511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 7521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 7541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return rtn; 7561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case F_SETFD: { 7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int flags = va_arg(args, int); 7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = SetFDFlags(fd, flags); 7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error) { 7611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 7621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 7631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return 0; 7651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 7671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 76868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle; 7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) error = AcquireHandle(fd, &handle); 77068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (error) { 77168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = error; 77268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 77368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 77468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int rtn = 0; 7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->VFcntl(request, &rtn, args); 7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return rtn; 78368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 78468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::access(const char* path, int amode) { 7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedFilesystem fs; 787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Path rel; 788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Error error = AcquireFsAndRelPath(path, &fs, &rel); 790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = fs->Access(rel, amode); 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::readlink(const char *path, char *buf, size_t count) { 8048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = EINVAL; 8058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 8068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int KernelProxy::utimes(const char *filename, const struct timeval times[2]) { 8098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) errno = EINVAL; 8108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 8118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 8128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 813eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(noelallen): Needs implementation. 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::link(const char* oldpath, const char* newpath) { 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::symlink(const char* oldpath, const char* newpath) { 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void* KernelProxy::mmap(void* addr, 825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t length, 826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int prot, 827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int flags, 828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int fd, 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset) { 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We shouldn't be getting anonymous mmaps here. 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((flags & MAP_ANONYMOUS) == 0); 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(fd != -1); 8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MAP_FAILED; 839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* new_addr; 8427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return MAP_FAILED; 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_addr; 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::munmap(void* addr, size_t length) { 85290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: The comment below is from a previous discarded implementation that 85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tracks mmap'd regions. For simplicity, we no longer do this; because we 85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "snapshot" the contents of the file in mmap(), and don't support 85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // write-back or updating the mapped region when the file is written, holding 85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on to the KernelHandle is pointless. 85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If we ever do, these threading issues should be considered. 85990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 86090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 86190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WARNING: this function may be called by free(). 86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 86390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is a potential deadlock scenario: 86490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 1: open() -> takes lock1 -> free() -> takes lock2 86590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 86690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 86790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that open() above could be any function that takes a lock that is 86890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // shared with munmap (this includes munmap!) 86990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 87090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // To prevent this, we avoid taking locks in munmap() that are used by other 87190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nacl_io functions that may call free. Specifically, we only take the 87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mmap_lock, which is only shared with mmap() above. There is still a 87390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // possibility of deadlock if mmap() or munmap() calls free(), so this is not 87490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allowed. 87590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 87690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unfortunately, munmap still needs to acquire other locks; see the call to 87790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // ReleaseHandle below which takes the process lock. This is safe as long as 87890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // this is never executed from free() -- we can be reasonably sure this is 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // true, because malloc only makes anonymous mmap() requests, and should only 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be munmapping those allocations. We never add to mmap_info_list_ for 88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anonymous maps, so the unmap_list should always be empty when called from 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // free(). 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 886bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcflush(int fd, int queue_selector) { 887bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 888bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 889bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 890bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 891bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 892bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 893bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 894bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcflush(queue_selector); 895bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 896bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 897bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 898bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 899bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 900bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 901bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 902bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 903bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 904bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 905bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 906bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 907bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 908bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 909bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 910bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 911bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcgetattr(termios_p); 912bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 913bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 914bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 915bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 916bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 917bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 918bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 919bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 920bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcsetattr(int fd, int optional_actions, 921bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const struct termios *termios_p) { 922bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 923bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 924bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 925bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 926bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 927bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 928bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 929bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcsetattr(optional_actions, termios_p); 930bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 931bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 932bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 933bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 934bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 935bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 936bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 937bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 9383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int KernelProxy::kill(pid_t pid, int sig) { 9393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Currently we don't even pretend that other processes exist 9403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // so we can only send a signal to outselves. For kill(2) 9413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // pid 0 means the current process group and -1 means all the 9423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // processes we have permission to send signals to. 9433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (pid != getpid() && pid != -1 && pid != 0) { 9443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = ESRCH; 9453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 9463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Raise an event so that select/poll get interrupted. 94968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AUTO_LOCK(signal_emitter_->GetLock()) 95068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_->RaiseEvents_Locked(POLLERR); 9513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (sig) { 9523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: 953f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (sigwinch_handler_.sa_handler != SIG_IGN && 954f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler != SIG_DFL) { 955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_.sa_handler(SIGWINCH); 956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 9573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 9583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR1: 9603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR2: 9613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 9623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 9643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 9653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 9663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 9683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 9693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int KernelProxy::sigaction(int signum, const struct sigaction* action, 971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct sigaction* oaction) { 972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_flags & SA_SIGINFO) { 973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We don't support SA_SIGINFO (sa_sigaction field) yet 974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 9783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (signum) { 9793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Handled signals. 9803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: { 981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) 982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *oaction = sigwinch_handler_; 983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action) { 984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sigwinch_handler_ = *action; 985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 9873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 9893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Known signals 9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGHUP: 9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGINT: 9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPIPE: 9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPOLL: 9943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPROF: 9953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTERM: 9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGCHLD: 9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGURG: 9983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGFPE: 9993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGILL: 10003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGQUIT: 10013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGSEGV: 10023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTRAP: 1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (action && action->sa_handler != SIG_DFL) { 1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Trying to set this action to anything other than SIG_DFL 1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is not yet supported. 1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (oaction) { 1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memset(oaction, 0, sizeof(*oaction)); 1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) oaction->sa_handler = SIG_DFL; 1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // KILL and STOP cannot be handled 1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGKILL: 1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SIGSTOP: 1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Unknown signum 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 10263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1028a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef PROVIDES_SOCKET_API 1029ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 10303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 10313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch fd_set* exceptfds, struct timeval* timeout) { 103268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_set ignore; 103368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<pollfd> pollfds; 103468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 103568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Simplify logic, by using an IGNORE set for any undefined set 103668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(&ignore); 103768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == readfds) 103868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) readfds = &ignore; 103968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == writefds) 104068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) writefds = &ignore; 104168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == exceptfds) 104268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) exceptfds = &ignore; 104368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 104468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int fd = 0; fd < nfds; fd++) { 10453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch int events = 0; 104668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, readfds)) 10473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLIN; 10483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 104968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, writefds)) 10503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLOUT; 10513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 105268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, exceptfds)) 10533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLERR | POLLHUP; 10543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 105568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 105668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd info; 105768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.fd = fd; 105868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.events = events; 105968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfds.push_back(info); 10603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 106168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 10623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 106368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(readfds); 106468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(writefds); 106568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(exceptfds); 10663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 106768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // NULL timeout signals wait forever. 106868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int ms_timeout = -1; 106968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (timeout != NULL) { 107068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 10713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 107268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the timeout is invalid or too long (larger than signed 32 bit). 107368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 107468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || 107568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (ms < 0) || (ms >= INT_MAX)) { 107668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EINVAL; 107768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 10783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 10793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 108068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ms_timeout = static_cast<int>(ms); 10813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 10823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 108368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 108468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result == -1) 108568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 10863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 108768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_cnt = 0; 108868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t index = 0; index < pollfds.size(); index++) { 108968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd* info = &pollfds[index]; 109068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLIN) { 109168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, readfds); 109268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 10933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 109468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLOUT) { 109568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, writefds); 109668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 10973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 109868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & (POLLHUP | POLLERR)) { 109968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, exceptfds); 110068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 11013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 110468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return event_cnt; 110568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 110768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct PollInfo { 110868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo() : index(-1) {}; 11093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 111068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<struct pollfd*> fds; 111168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index; 111268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 11133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 111468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 11153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 111768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventPollMap_t event_map; 11183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 111968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<EventRequest> requests; 11203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch size_t event_cnt = 0; 112168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 112268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 11233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ScopedKernelHandle handle; 112468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = &fds[index]; 112568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = AcquireHandle(fd_info->fd, &handle); 112668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 112768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = 0; 11283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If the node isn't open, or somehow invalid, mark it so. 11303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (err != 0) { 113168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 11323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If it's already signaled, then just capture the event 113768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 113868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int events = POLLIN | POLLOUT; 113968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (emitter) 114068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events = emitter->GetEventStatus(); 114168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 114268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events & fd_info->events) { 114368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events & fd_info->events; 11443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 114868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == emitter) { 114968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 11503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 11513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 11523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 115368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 115468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Otherwise try to track it. 115568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* info = &event_map[emitter.get()]; 115668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->index == -1) { 115768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest request; 115868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.emitter = emitter; 115968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.filter = fd_info->events; 116068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.events = 0; 116168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 116268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->index = requests.size(); 116368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests.push_back(request); 116468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 116568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->fds.push_back(fd_info); 116668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests[info->index].filter |= fd_info->events; 11673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 116968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If nothing is signaled, then we must wait on the event map 11703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (0 == event_cnt) { 117168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventListenerPoll wait; 117268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 117368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((err != 0) && (err != ETIMEDOUT)) { 117468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = err; 11753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 11763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 117768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 117868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t rindex = 0; rindex < requests.size(); rindex++) { 117968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest* request = &requests[rindex]; 118068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (request->events) { 118168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* poll_info = &event_map[request->emitter.get()]; 118268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 118368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = poll_info->fds[findex]; 118468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint32_t events = fd_info->events & request->events; 118568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 118668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events; 118768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 118868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 118968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 119068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 119168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 11923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 11933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return event_cnt; 11953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 11963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 11973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Socket Functions 1199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 12064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 12074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 12084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 12104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PP_Resource new_sock = 0; 12134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Accept(&new_sock, addr, len); 12144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 12154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 12164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 12174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 12184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SocketNode* sock = new TcpNode(stream_mount_.get(), new_sock); 12204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The SocketNode now holds a reference to the new socket 12224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // so we release ours. 12234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ppapi_->ReleaseResource(new_sock); 1224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = sock->Init(O_RDWR); 12254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 12264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 12274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 12284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 12294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 12314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node)); 1232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error = new_handle->Init(O_RDWR); 12331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (error != 0) { 12341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = error; 12351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 12361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 12371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 12384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(new_handle); 1239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Bind(addr, len); 12523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 12533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 12674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 12684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 12694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 12714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Connect(addr, len); 12744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 12754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 12763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KernelProxy::freeaddrinfo(struct addrinfo *res) { 12835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.freeaddrinfo(res); 12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int KernelProxy::getaddrinfo(const char* node, const char* service, 12875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const struct addrinfo* hints, 12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct addrinfo** res) { 12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return host_resolver_.getaddrinfo(node, service, hints, res); 12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1292bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstruct hostent* KernelProxy::gethostbyname(const char* name) { 1293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return host_resolver_.gethostbyname(name); 1294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1295bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetPeerName(addr, len); 13073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetSockName(addr, len); 13263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockopt(int fd, 13354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int lvl, 13364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int optname, 13374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void* optval, 13384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) socklen_t* len) { 1339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval || NULL == len) { 1340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len); 13494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 13504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 13514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 13524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 13534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::listen(int fd, int backlog) { 1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->Listen(backlog); 13634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 13644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 13654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 13664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 13674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 13684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recv(int fd, 1372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags) { 1375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 13814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 13824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 13834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 13854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 13884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Recv(buf, len, flags, &out_len); 13894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 13904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 13913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvfrom(int fd, 1398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct sockaddr* addr, 1402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t* addrlen) { 1403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, recvfrom with a null addr is identical to recv. 1404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return recv(fd, buf, len, flags); 1406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf || NULL == addrlen) { 1409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); 14224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg ) { 1432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->Send(buf, len, flags, &out_len); 14594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendto(int fd, 1468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* buf, 1469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const struct sockaddr* addr, 1472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t addrlen) { 1473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, sendto with a null addr is identical to send. 1474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return send(fd, buf, len, flags); 1476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1481a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1482a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 14844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error error = AcquireHandle(fd, &handle); 14854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error) { 14864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 1487a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 14884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1489a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 14914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len); 14924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != 0) { 14934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = error; 14943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 14953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 14963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 14973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg) { 1502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::setsockopt(int fd, 1515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int lvl, 1516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int optname, 1517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* optval, 1518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t len) { 1519a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval) { 1520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len); 15294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (err != 0) { 15304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = err; 15314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 15324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 15334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 15344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 1535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::shutdown(int fd, int how) { 1538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Shutdown(how); 15433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 15443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 15453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 15463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 15473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socket(int domain, int type, int protocol) { 1552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int open_flags = O_RDWR; 1558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_CLOEXEC) { 1560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifdef O_CLOEXEC 1561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The NaCl newlib version of fcntl.h doesn't currently define 1562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // O_CLOEXEC. 1563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(sbc): remove this guard once it gets added. 1564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_CLOEXEC; 1565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 1566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_CLOEXEC; 1567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type & SOCK_NONBLOCK) { 1570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) open_flags |= O_NONBLOCK; 1571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type &= ~SOCK_NONBLOCK; 1572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 15745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SocketNode* sock = NULL; 15753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 15763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_DGRAM: 15775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sock = new UdpNode(stream_mount_.get()); 15783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 15793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 15803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_STREAM: 15815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sock = new TcpNode(stream_mount_.get()); 15823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 15833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_SEQPACKET: 1585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RDM: 1586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case SOCK_RAW: 15873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EPROTONOSUPPORT; 15883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 1589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 1591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errno = EINVAL; 1592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 1593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedNode node(sock); 1596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Error rtn = sock->Init(O_RDWR); 15974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (rtn != 0) { 15984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) errno = rtn; 15994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 16003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 16013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); 1603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rtn = handle->Init(open_flags); 16041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rtn != 0) { 16051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) errno = rtn; 16061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return -1; 16071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 16081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 16094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AllocateFD(handle); 1610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == sv) { 1614a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // socket pairs. Thus, this function always fails. 1620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_UNIX != domain) { 1621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EPROTONOSUPPORT; 1622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We cannot reach this point. 1631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOSYS; 1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Error error = AcquireHandle(fd, handle); 1637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (error) { 1639a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = error; 1640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOTSOCK; 1645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 1649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1651bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // PROVIDES_SOCKET_API 1652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1653bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace_nacl_io 1654