kernel_proxy.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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) 73240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <assert.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h> 113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <limits.h> 123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <poll.h> 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <pthread.h> 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <stdio.h> 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <sys/time.h> 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <unistd.h> 183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <iterator> 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/dbgprint.h" 23bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "nacl_io/host_resolver.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_handle.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_wrap_real.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_dev.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_html5fs.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_http.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_mem.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_node.h" 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "nacl_io/mount_node_pipe.h" 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/mount_node_tcp.h" 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "nacl_io/mount_node_udp.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_passthrough.h" 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "nacl_io/mount_stream.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osmman.h" 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "nacl_io/ossocket.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/osstat.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/path.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/pepper_interface.h" 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/typed_mount_factory.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/auto_lock.h" 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sdk_util/ref_object.h" 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sdk_util/string_util.h" 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MAXPATHLEN 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAXPATHLEN 256 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace nacl_io { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sigwinch_handler_(SIG_IGN), 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_(new EventEmitter) { 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Clean up the MountFactories. 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (MountFactoryMap_t::iterator i = factories_.begin(); 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch i != factories_.end(); 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete ppapi_; 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Error KernelProxy::Init(PepperInterface* ppapi) { 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Error rtn = 0; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi_ = ppapi; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_ = 1; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["memfs"] = new TypedMountFactory<MountMem>; 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["dev"] = new TypedMountFactory<MountDev>; 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>; 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["httpfs"] = new TypedMountFactory<MountHttp>; 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/", "passthroughfs", 0, NULL); 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = mount("", "/dev", "dev", 0, NULL); 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Open the first three in order to get STDIN, STDOUT, STDERR 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int fd; 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdin", O_RDONLY); 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 0); 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stdout", O_WRONLY); 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 1); 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fd = open("/dev/stderr", O_WRONLY); 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(fd == 2); 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fd < 0) 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = errno; 111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifdef PROVIDES_SOCKET_API 113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch host_resolver_.Init(ppapi_); 114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringMap_t args; 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) stream_mount_.reset(new MountStream()); 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) result = stream_mount_->Init(0, args, ppapi); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (result != 0) { 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) assert(false); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) rtn = result; 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return rtn; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open_resource(const char* path) { 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMountNode node; 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = mnt->OpenResource(rel, &node); 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OpenResource failed, try Open(). 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = mnt->Open(rel, O_RDONLY, &node); 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedKernelHandle handle(new KernelHandle(mnt, node)); 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Init(O_RDONLY); 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AllocateFD(handle); 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::open(const char* path, int oflags) { 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMountNode node; 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndNode(path, oflags, &mnt, &node); 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle(new KernelHandle(mnt, node)); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Init(oflags); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return AllocateFD(handle); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int KernelProxy::pipe(int pipefds[2]) { 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MountNodePipe* pipe = new MountNodePipe(stream_mount_.get()); 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedMountNode node(pipe); 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pipe->Init(S_IREAD | S_IWRITE) == 0) { 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Should never fail, but... 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (handle0->Init(S_IREAD) || handle1->Init(S_IWRITE)) { 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EACCES; 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[0] = AllocateFD(handle0); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pipefds[1] = AllocateFD(handle1); 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return 0; 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = ENOSYS; 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::close(int fd) { 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Remove the FD from the process open file descriptor map 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeFD(fd); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup(int oldfd) { 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(oldfd, &handle); 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return AllocateFD(handle); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::dup2(int oldfd, int newfd) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's the same file handle, just return 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (oldfd == newfd) 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return newfd; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle old_handle; 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(oldfd, &old_handle); 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FreeAndReassignFD(newfd, old_handle); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return newfd; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint KernelProxy::chdir(const char* path) { 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = SetCWD(path); 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getcwd(char* buf, size_t size) { 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string cwd = GetCWD(); 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size <= 0) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If size is 0, allocate as much as we need. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size == 0) { 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size = cwd.size() + 1; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify the buffer is large enough 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (size <= cwd.size()) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ERANGE; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allocate the buffer if needed 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (buf == NULL) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf = static_cast<char*>(malloc(size)); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch strcpy(buf, cwd.c_str()); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buf; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)char* KernelProxy::getwd(char* buf) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NULL == buf) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EFAULT; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return getcwd(buf, MAXPATHLEN); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::chmod(const char* path, mode_t mode) { 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int fd = KernelProxy::open(path, O_RDONLY); 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fchmod(fd, mode); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint KernelProxy::utime(const char* filename, const struct utimbuf* times) { 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mkdir(const char* path, mode_t mode) { 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Mkdir(rel, mode); 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::rmdir(const char* path) { 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Rmdir(rel); 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::stat(const char* path, struct stat* buf) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = open(path, O_RDONLY); 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (-1 == fd) 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = fstat(fd, buf); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::mount(const char* source, 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* target, 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char* filesystemtype, 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned long mountflags, 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* data) { 3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string abs_path = GetAbsParts(target).Join(); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a factory of that type 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (factory == factories_.end()) { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = ENODEV; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create a map of settings 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StringMap_t smap; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) smap["SOURCE"] = source; 3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch smap["TARGET"] = abs_path; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data) { 38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::vector<std::string> elements; 38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (std::vector<std::string>::const_iterator it = elements.begin(); 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it != elements.end(); ++it) { 38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t location = it->find('='); 38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (location != std::string::npos) { 38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string key = it->substr(0, location); 38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string val = it->substr(location + 1); 39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[key] = val; 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) smap[*it] = "TRUE"; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt); 3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return -1; 4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = AttachMountAtPath(mnt, abs_path); 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int KernelProxy::umount(const char* path) { 4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = DetachMountAtPath(path); 4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (error) { 4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch errno = error; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Read(buf, nbytes, &cnt); 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->Write(buf, nbytes, &cnt); 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fstat(int fd, struct stat* buf) { 459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->GetStat(buf); 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cnt = 0; 4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cnt; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int KernelProxy::ftruncate(int fd, off_t length) { 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FTruncate(length); 500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fsync(int fd) { 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->FSync(); 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::isatty(int fd) { 526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->IsaTTY(); 534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 542bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::ioctl(int fd, int request, char* argp) { 543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 544bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->Ioctl(request, argp); 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) off_t new_offset; 568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = handle->Seek(offset, whence, &new_offset); 569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return new_offset; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::unlink(const char* path) { 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Unlink(rel); 588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::remove(const char* path) { 597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedMount mnt; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Path rel; 5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = mnt->Remove(rel); 607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(noelallen): Needs implementation. 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::fchmod(int fd, int mode) { 617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error error = AcquireHandle(fd, &handle); 619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int KernelProxy::fcntl(int fd, int request, char *argp) { 62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle; 62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (error) { 63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = error; 63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(sbc): Needs implementation. 63668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = ENOSYS; 63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 63868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 63968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::access(const char* path, int amode) { 6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedMount mnt; 642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Path rel; 643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Error error = AcquireMountAndRelPath(path, &mnt, &rel); 645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 649eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = mnt->Access(rel, amode); 651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(noelallen): Needs implementation. 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::link(const char* oldpath, const char* newpath) { 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::symlink(const char* oldpath, const char* newpath) { 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = EINVAL; 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void* KernelProxy::mmap(void* addr, 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t length, 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int prot, 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int flags, 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int fd, 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset) { 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We shouldn't be getting anonymous mmaps here. 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((flags & MAP_ANONYMOUS) == 0); 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(fd != -1); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedKernelHandle handle; 680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Error error = AcquireHandle(fd, &handle); 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error) { 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errno = error; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MAP_FAILED; 684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* new_addr; 6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (error) { 689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errno = error; 690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return MAP_FAILED; 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_addr; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int KernelProxy::munmap(void* addr, size_t length) { 69790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: The comment below is from a previous discarded implementation that 69890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tracks mmap'd regions. For simplicity, we no longer do this; because we 69990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // "snapshot" the contents of the file in mmap(), and don't support 70090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // write-back or updating the mapped region when the file is written, holding 70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on to the KernelHandle is pointless. 70290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If we ever do, these threading issues should be considered. 70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 70590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 70690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // WARNING: this function may be called by free(). 70790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is a potential deadlock scenario: 70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 1: open() -> takes lock1 -> free() -> takes lock2 71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that open() above could be any function that takes a lock that is 71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // shared with munmap (this includes munmap!) 71490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 71590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // To prevent this, we avoid taking locks in munmap() that are used by other 71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // nacl_io functions that may call free. Specifically, we only take the 71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // mmap_lock, which is only shared with mmap() above. There is still a 71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // possibility of deadlock if mmap() or munmap() calls free(), so this is not 71990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // allowed. 72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 72190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Unfortunately, munmap still needs to acquire other locks; see the call to 72290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // ReleaseHandle below which takes the process lock. This is safe as long as 72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // this is never executed from free() -- we can be reasonably sure this is 72490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // true, because malloc only makes anonymous mmap() requests, and should only 72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be munmapping those allocations. We never add to mmap_info_list_ for 72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // anonymous maps, so the unmap_list should always be empty when called from 72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // free(). 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 731bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcflush(int fd, int queue_selector) { 732bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 733bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 734bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 735bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 736bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 737bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 738bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 739bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcflush(queue_selector); 740bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 741bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 742bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 743bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 744bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 745bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 746bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 747bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 748bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 749bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 750bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 751bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 752bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 753bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 754bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 755bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 756bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcgetattr(termios_p); 757bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 758bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 759bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 760bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 761bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 762bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 763bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 764bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 765bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochint KernelProxy::tcsetattr(int fd, int optional_actions, 766bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const struct termios *termios_p) { 767bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ScopedKernelHandle handle; 768bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch Error error = AcquireHandle(fd, &handle); 769bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 770bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 771bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 772bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 773bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 774bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch error = handle->node()->Tcsetattr(optional_actions, termios_p); 775bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (error) { 776bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch errno = error; 777bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return -1; 778bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 779bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 780bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return 0; 781bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 782bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 7833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int KernelProxy::kill(pid_t pid, int sig) { 7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Currently we don't even pretend that other processes exist 7853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // so we can only send a signal to outselves. For kill(2) 7863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // pid 0 means the current process group and -1 means all the 7873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // processes we have permission to send signals to. 7883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (pid != getpid() && pid != -1 && pid != 0) { 7893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = ESRCH; 7903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 7913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Raise an event so that select/poll get interrupted. 79468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AUTO_LOCK(signal_emitter_->GetLock()) 79568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) signal_emitter_->RaiseEvents_Locked(POLLERR); 7963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (sig) { 7973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: 7983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sigwinch_handler_ != SIG_IGN) 7993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sigwinch_handler_(SIGWINCH); 8003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 8013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR1: 8033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGUSR2: 8043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 8073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 8113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { 8143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (signum) { 8153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Handled signals. 8163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGWINCH: { 8173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sighandler_t old_value = sigwinch_handler_; 8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (handler == SIG_DFL) 8193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) handler = SIG_IGN; 8203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sigwinch_handler_ = handler; 8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return old_value; 8223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Known signals 8253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGHUP: 8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGINT: 8273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGKILL: 8283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPIPE: 8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPOLL: 8303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGPROF: 8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTERM: 8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGCHLD: 8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGURG: 8343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGFPE: 8353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGILL: 8363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGQUIT: 8373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGSEGV: 8383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SIGTRAP: 8393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (handler == SIG_DFL) 8403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return SIG_DFL; 8413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 8423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 8443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EINVAL; 8453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return SIG_ERR; 8463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 8473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 848a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef PROVIDES_SOCKET_API 849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 8513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch fd_set* exceptfds, struct timeval* timeout) { 85268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_set ignore; 85368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<pollfd> pollfds; 85468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 85568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Simplify logic, by using an IGNORE set for any undefined set 85668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(&ignore); 85768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == readfds) 85868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) readfds = &ignore; 85968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == writefds) 86068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) writefds = &ignore; 86168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == exceptfds) 86268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) exceptfds = &ignore; 86368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int fd = 0; fd < nfds; fd++) { 8653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch int events = 0; 86668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, readfds)) 8673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLIN; 8683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 86968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, writefds)) 8703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLOUT; 8713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 87268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (FD_ISSET(fd, exceptfds)) 8733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch events |= POLLERR | POLLHUP; 8743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 87568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 87668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd info; 87768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.fd = fd; 87868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info.events = events; 87968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfds.push_back(info); 8803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 88168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 8823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 88368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(readfds); 88468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(writefds); 88568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_ZERO(exceptfds); 8863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 88768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // NULL timeout signals wait forever. 88868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int ms_timeout = -1; 88968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (timeout != NULL) { 89068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 8913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 89268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If the timeout is invalid or too long (larger than signed 32 bit). 89368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 89468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || 89568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (ms < 0) || (ms >= INT_MAX)) { 89668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = EINVAL; 89768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 8983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 8993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 90068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ms_timeout = static_cast<int>(ms); 9013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 9023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 90368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 90468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result == -1) 90568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return -1; 9063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 90768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int event_cnt = 0; 90868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t index = 0; index < pollfds.size(); index++) { 90968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pollfd* info = &pollfds[index]; 91068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLIN) { 91168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, readfds); 91268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 9133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 91468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & POLLOUT) { 91568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, writefds); 91668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 9173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 91868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->revents & (POLLHUP | POLLERR)) { 91968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FD_SET(info->fd, exceptfds); 92068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 9213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 9223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 9233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 92468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return event_cnt; 92568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 9263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 92768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)struct PollInfo { 92868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo() : index(-1) {}; 9293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 93068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<struct pollfd*> fds; 93168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index; 93268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 9333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 93468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 9353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 9363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochint KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 93768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventPollMap_t event_map; 9383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 93968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<EventRequest> requests; 9403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch size_t event_cnt = 0; 94168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 94268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 9433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ScopedKernelHandle handle; 94468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = &fds[index]; 94568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = AcquireHandle(fd_info->fd, &handle); 94668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 94768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = 0; 9483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 9493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If the node isn't open, or somehow invalid, mark it so. 9503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (err != 0) { 95168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 9523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 9533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 9543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 9553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 9563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // If it's already signaled, then just capture the event 95768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 95868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int events = POLLIN | POLLOUT; 95968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (emitter) 96068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) events = emitter->GetEventStatus(); 96168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 96268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events & fd_info->events) { 96368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events & fd_info->events; 9643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 9653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 9663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 9673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 96868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (NULL == emitter) { 96968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = POLLNVAL; 9703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch event_cnt++; 9713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 9723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 97368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 97468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Otherwise try to track it. 97568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* info = &event_map[emitter.get()]; 97668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (info->index == -1) { 97768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest request; 97868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.emitter = emitter; 97968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.filter = fd_info->events; 98068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.events = 0; 98168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 98268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->index = requests.size(); 98368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests.push_back(request); 98468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 98568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) info->fds.push_back(fd_info); 98668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) requests[info->index].filter |= fd_info->events; 9873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 9883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 98968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If nothing is signaled, then we must wait on the event map 9903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (0 == event_cnt) { 99168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventListenerPoll wait; 99268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 99368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((err != 0) && (err != ETIMEDOUT)) { 99468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) errno = err; 9953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 99768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 99868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t rindex = 0; rindex < requests.size(); rindex++) { 99968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EventRequest* request = &requests[rindex]; 100068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (request->events) { 100168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PollInfo* poll_info = &event_map[request->emitter.get()]; 100268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 100368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) struct pollfd* fd_info = poll_info->fds[findex]; 100468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) uint32_t events = fd_info->events & request->events; 100568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (events) { 100668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) fd_info->revents = events; 100768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) event_cnt++; 100868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 100968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 101068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 101168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 10123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch } 10133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 10143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return event_cnt; 10153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch} 10163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 10173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 10183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 1019a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Socket Functions 1020a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1021a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1022a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1023a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1024a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1025a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1026a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1027a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1028a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1029a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1030a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EINVAL; 1031a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1032a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1033a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1034a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1035a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1036a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1037a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1038a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1039a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1040a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1041a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1042a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1043a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 10443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Bind(addr, len); 10453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 10463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 10473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1051a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1052a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1053a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1054a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1055a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1056a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1057a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1058a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1059a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1060a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1061a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1062a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 10633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Connect(addr, len); 10643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 10653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 10663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1070a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1071a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1072bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstruct hostent* KernelProxy::gethostbyname(const char* name) { 1073bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return host_resolver_.gethostbyname(name); 1074bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1075bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1076a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1077a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1079a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1080a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1081a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1082a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1083a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1084a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1085a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 10863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetPeerName(addr, len); 10873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 10883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 10893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 10903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 10913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1093a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1094a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1095a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1096a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr || NULL == len) { 1097a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1098a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1099a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 11053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->GetSockName(addr, len); 11063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 11073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 11083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 11093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::getsockopt(int fd, 1115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int lvl, 1116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int optname, 1117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* optval, 1118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t* len) { 1119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval || NULL == len) { 1120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EINVAL; 1129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::listen(int fd, int backlog) { 1133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recv(int fd, 1142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags) { 1145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 11543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 11553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Recv(buf, len, flags, &out_len); 11563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 11573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 11583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 11593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvfrom(int fd, 1165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void* buf, 1166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct sockaddr* addr, 1169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t* addrlen) { 1170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, recvfrom with a null addr is identical to recv. 1171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return recv(fd, buf, len, flags); 1173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf || NULL == addrlen) { 1176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 11843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 11853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->RecvFrom(buf, 11863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) len, 11873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) flags, 11883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) addr, 11893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) addrlen, 11903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &out_len); 11913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 11923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 11933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 11943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 11953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 11963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg ) { 1201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 12243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Send(buf, len, flags, &out_len); 12253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 12263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 12273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendto(int fd, 1234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* buf, 1235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t len, 1236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int flags, 1237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const struct sockaddr* addr, 1238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t addrlen) { 1239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // According to the manpage, sendto with a null addr is identical to send. 1240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == addr) { 1241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return send(fd, buf, len, flags); 1242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == buf) { 1245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 12533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int out_len = 0; 12543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = 12553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) handle->socket_node()->SendTo(buf, len, flags, addr, addrlen, &out_len); 12563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 12583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 12593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 12603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 12613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 12623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<ssize_t>(out_len); 1263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == msg) { 1267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EOPNOTSUPP; 1276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::setsockopt(int fd, 1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int lvl, 1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int optname, 1282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const void* optval, 1283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) socklen_t len) { 1284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == optval) { 1285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EINVAL; 1294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::shutdown(int fd, int how) { 1298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ScopedKernelHandle handle; 1299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AcquireSocketHandle(fd, &handle) == -1) 1300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Error err = handle->socket_node()->Shutdown(how); 13033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err != 0) { 13043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = err; 13053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 13063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 1309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socket(int domain, int type, int protocol) { 1312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MountNodeSocket* sock = NULL; 13183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (type) { 13193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_DGRAM: 132068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sock = new MountNodeUDP(stream_mount_.get()); 13213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 13223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case SOCK_STREAM: 132468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sock = new MountNodeTCP(stream_mount_.get()); 13253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 13263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 13283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) errno = EPROTONOSUPPORT; 13293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return -1; 1330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScopedMountNode node(sock); 13333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sock->Init(S_IREAD | S_IWRITE) == 0) { 133468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); 13353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return AllocateFD(handle); 13363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 13373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 13383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If we failed to init, assume we don't have access. 13393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return EACCES; 1340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (NULL == sv) { 1344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EFAULT; 1345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // socket pairs. Thus, this function always fails. 1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_UNIX != domain) { 1351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EPROTONOSUPPORT; 1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (AF_INET != domain && AF_INET6 != domain) { 1356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = EAFNOSUPPORT; 1357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // We cannot reach this point. 1361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOSYS; 1362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Error error = AcquireHandle(fd, handle); 1367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (error) { 1369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = error; 1370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) errno = ENOTSOCK; 1375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return -1; 1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0; 1379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1381bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif // PROVIDES_SOCKET_API 1382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1383bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace_nacl_io 1384