1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef LIBRARIES_NACL_IO_KERNEL_PROXY_H_ 6#define LIBRARIES_NACL_IO_KERNEL_PROXY_H_ 7 8#include <map> 9#include <string> 10 11#include "nacl_io/devfs/dev_fs.h" 12#include "nacl_io/event_emitter.h" 13#include "nacl_io/fs_factory.h" 14#include "nacl_io/host_resolver.h" 15#include "nacl_io/kernel_object.h" 16#include "nacl_io/nacl_io.h" 17#include "nacl_io/ossignal.h" 18#include "nacl_io/ossocket.h" 19#include "nacl_io/ostypes.h" 20#include "nacl_io/osutime.h" 21#include "nacl_io/stream/stream_fs.h" 22 23struct fuse_operations; 24struct timeval; 25 26namespace nacl_io { 27 28class PepperInterface; 29 30 31// KernelProxy provide one-to-one mapping for libc kernel calls. Calls to the 32// proxy will result in IO access to the provided Filesystem and Node objects. 33// 34// NOTE: The KernelProxy does not directly take any kernel locks, all locking 35// is done by the parent class KernelObject. Instead, KernelProxy is 36// responsible for taking the locks of the KernelHandle, and Node objects. For 37// this reason, a KernelObject call should not be done while holding a handle 38// or node lock. In addition, to ensure locking order, a KernelHandle lock 39// must never be taken after taking the associated Node's lock. 40// 41// NOTE: The KernelProxy is the only class that should be setting errno. All 42// other classes should return Error (as defined by nacl_io/error.h). 43class KernelProxy : protected KernelObject { 44 public: 45 typedef std::map<std::string, FsFactory*> FsFactoryMap_t; 46 47 KernelProxy(); 48 virtual ~KernelProxy(); 49 50 // |ppapi| may be NULL. If so, no filesystem that uses pepper calls can be 51 // mounted. 52 virtual Error Init(PepperInterface* ppapi); 53 54 // Register/Unregister a new filesystem type. See the documentation in 55 // nacl_io.h for more info. 56 bool RegisterFsType(const char* fs_type, fuse_operations* fuse_ops); 57 bool UnregisterFsType(const char* fs_type); 58 59 void SetExitCallback(nacl_io_exit_callback_t exit_callback, void* user_data); 60 61 void SetMountCallback(nacl_io_mount_callback_t mount_callback, 62 void* user_data); 63 64 virtual int pipe(int pipefds[2]); 65 66 // NaCl-only function to read resources specified in the NMF file. 67 virtual int open_resource(const char* file); 68 69 // KernelHandle and FD allocation and manipulation functions. 70 virtual int open(const char* path, int open_flags, mode_t mode); 71 virtual int close(int fd); 72 virtual int dup(int fd); 73 virtual int dup2(int fd, int newfd); 74 75 virtual void exit(int status); 76 77 // Path related System calls handled by KernelProxy (not filesystem-specific) 78 virtual int chdir(const char* path); 79 virtual char* getcwd(char* buf, size_t size); 80 virtual char* getwd(char* buf); 81 virtual int mount(const char* source, 82 const char* target, 83 const char* filesystemtype, 84 unsigned long mountflags, 85 const void* data); 86 virtual int umount(const char* path); 87 88 // Stub system calls that don't do anything (yet), handled by KernelProxy. 89 virtual int chown(const char* path, uid_t owner, gid_t group); 90 virtual int fchown(int fd, uid_t owner, gid_t group); 91 virtual int lchown(const char* path, uid_t owner, gid_t group); 92 93 // System calls that take a path as an argument: The kernel proxy will look 94 // for the Node associated to the path. To find the node, the kernel proxy 95 // calls the corresponding filesystem's GetNode() method. The corresponding 96 // method will be called. If the node cannot be found, errno is set and -1 is 97 // returned. 98 virtual int chmod(const char* path, mode_t mode); 99 virtual int mkdir(const char* path, mode_t mode); 100 virtual int rmdir(const char* path); 101 virtual int stat(const char* path, struct stat* buf); 102 103 // System calls that take a file descriptor as an argument: 104 // The kernel proxy will determine to which filesystem the file 105 // descriptor's corresponding file handle belongs. The 106 // associated filesystem's function will be called. 107 virtual ssize_t read(int fd, void* buf, size_t nbyte); 108 virtual ssize_t write(int fd, const void* buf, size_t nbyte); 109 110 virtual int fchmod(int fd, mode_t mode); 111 virtual int fcntl(int fd, int request, va_list args); 112 virtual int fstat(int fd, struct stat* buf); 113 virtual int getdents(int fd, void* buf, unsigned int count); 114 virtual int fchdir(int fd); 115 virtual int ftruncate(int fd, off_t length); 116 virtual int fsync(int fd); 117 virtual int fdatasync(int fd); 118 virtual int isatty(int fd); 119 virtual int ioctl(int fd, int request, va_list args); 120 virtual int futimens(int fd, const struct timespec times[2]); 121 122 // lseek() relies on the filesystem's Stat() to determine whether or not the 123 // file handle corresponding to fd is a directory 124 virtual off_t lseek(int fd, off_t offset, int whence); 125 126 // remove() uses the filesystem's GetNode() and Stat() to determine whether 127 // or not the path corresponds to a directory or a file. The filesystem's 128 // Rmdir() or Unlink() is called accordingly. 129 virtual int remove(const char* path); 130 // unlink() is a simple wrapper around the filesystem's Unlink function. 131 virtual int unlink(const char* path); 132 virtual int truncate(const char* path, off_t len); 133 virtual int lstat(const char* path, struct stat* buf); 134 virtual int rename(const char* path, const char* newpath); 135 // access() uses the Filesystem's Stat(). 136 virtual int access(const char* path, int amode); 137 virtual int readlink(const char* path, char* buf, size_t count); 138 virtual int utimens(const char* path, const struct timespec times[2]); 139 140 virtual int link(const char* oldpath, const char* newpath); 141 virtual int symlink(const char* oldpath, const char* newpath); 142 143 virtual void* mmap(void* addr, 144 size_t length, 145 int prot, 146 int flags, 147 int fd, 148 size_t offset); 149 virtual int munmap(void* addr, size_t length); 150 virtual int tcflush(int fd, int queue_selector); 151 virtual int tcgetattr(int fd, struct termios* termios_p); 152 virtual int tcsetattr(int fd, 153 int optional_actions, 154 const struct termios* termios_p); 155 156 virtual int kill(pid_t pid, int sig); 157 virtual int sigaction(int signum, 158 const struct sigaction* action, 159 struct sigaction* oaction); 160 161#ifdef PROVIDES_SOCKET_API 162 virtual int select(int nfds, 163 fd_set* readfds, 164 fd_set* writefds, 165 fd_set* exceptfds, 166 struct timeval* timeout); 167 168 virtual int poll(struct pollfd* fds, nfds_t nfds, int timeout); 169 170 // Socket support functions 171 virtual int accept(int fd, struct sockaddr* addr, socklen_t* len); 172 virtual int bind(int fd, const struct sockaddr* addr, socklen_t len); 173 virtual int connect(int fd, const struct sockaddr* addr, socklen_t len); 174 virtual struct hostent* gethostbyname(const char* name); 175 virtual void freeaddrinfo(struct addrinfo* res); 176 virtual int getaddrinfo(const char* node, 177 const char* service, 178 const struct addrinfo* hints, 179 struct addrinfo** res); 180 virtual int getnameinfo(const struct sockaddr *sa, 181 socklen_t salen, 182 char *host, 183 size_t hostlen, 184 char *serv, 185 size_t servlen, 186 int flags); 187 virtual int getpeername(int fd, struct sockaddr* addr, socklen_t* len); 188 virtual int getsockname(int fd, struct sockaddr* addr, socklen_t* len); 189 virtual int getsockopt(int fd, 190 int lvl, 191 int optname, 192 void* optval, 193 socklen_t* len); 194 virtual int listen(int fd, int backlog); 195 virtual ssize_t recv(int fd, void* buf, size_t len, int flags); 196 virtual ssize_t recvfrom(int fd, 197 void* buf, 198 size_t len, 199 int flags, 200 struct sockaddr* addr, 201 socklen_t* addrlen); 202 virtual ssize_t recvmsg(int fd, struct msghdr* msg, int flags); 203 virtual ssize_t send(int fd, const void* buf, size_t len, int flags); 204 virtual ssize_t sendto(int fd, 205 const void* buf, 206 size_t len, 207 int flags, 208 const struct sockaddr* addr, 209 socklen_t addrlen); 210 virtual ssize_t sendmsg(int fd, const struct msghdr* msg, int flags); 211 virtual int setsockopt(int fd, 212 int lvl, 213 int optname, 214 const void* optval, 215 socklen_t len); 216 virtual int shutdown(int fd, int how); 217 virtual int socket(int domain, int type, int protocol); 218 virtual int socketpair(int domain, int type, int protocol, int* sv); 219#endif // PROVIDES_SOCKET_API 220 221 protected: 222 Error MountInternal(const char* source, 223 const char* target, 224 const char* filesystemtype, 225 unsigned long mountflags, 226 const void* data, 227 bool create_fs_node, 228 ScopedFilesystem* out_filesystem); 229 230 Error CreateFsNode(const ScopedFilesystem& fs); 231 232 protected: 233 FsFactoryMap_t factories_; 234 sdk_util::ScopedRef<StreamFs> stream_fs_; 235 sdk_util::ScopedRef<DevFs> dev_fs_; 236 int dev_; 237 PepperInterface* ppapi_; 238 static KernelProxy* s_instance_; 239 struct sigaction sigwinch_handler_; 240 nacl_io_exit_callback_t exit_callback_; 241 void* exit_callback_user_data_; 242 nacl_io_mount_callback_t mount_callback_; 243 void* mount_callback_user_data_; 244#ifdef PROVIDES_SOCKET_API 245 HostResolver host_resolver_; 246#endif 247 248#ifdef PROVIDES_SOCKET_API 249 virtual int AcquireSocketHandle(int fd, ScopedKernelHandle* handle); 250#endif 251 252 ScopedEventEmitter signal_emitter_; 253 DISALLOW_COPY_AND_ASSIGN(KernelProxy); 254}; 255 256} // namespace nacl_io 257 258#endif // LIBRARIES_NACL_IO_KERNEL_PROXY_H_ 259