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 23 struct fuse_operations; 24 struct timeval; 25 26 namespace nacl_io { 27 28 class 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). 43 class 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 bool RegisterExitHandler(nacl_io_exit_handler_t exit_handler, 60 void* user_data); 61 62 virtual int pipe(int pipefds[2]); 63 64 // NaCl-only function to read resources specified in the NMF file. 65 virtual int open_resource(const char* file); 66 67 // KernelHandle and FD allocation and manipulation functions. 68 virtual int open(const char* path, int open_flags); 69 virtual int close(int fd); 70 virtual int dup(int fd); 71 virtual int dup2(int fd, int newfd); 72 73 virtual void exit(int status); 74 75 // Path related System calls handled by KernelProxy (not filesystem-specific) 76 virtual int chdir(const char* path); 77 virtual char* getcwd(char* buf, size_t size); 78 virtual char* getwd(char* buf); 79 virtual int mount(const char* source, 80 const char* target, 81 const char* filesystemtype, 82 unsigned long mountflags, 83 const void* data); 84 virtual int umount(const char* path); 85 86 // Stub system calls that don't do anything (yet), handled by KernelProxy. 87 virtual int chown(const char* path, uid_t owner, gid_t group); 88 virtual int fchown(int fd, uid_t owner, gid_t group); 89 virtual int lchown(const char* path, uid_t owner, gid_t group); 90 virtual int utime(const char* filename, const struct utimbuf* times); 91 92 // System calls that take a path as an argument: The kernel proxy will look 93 // for the Node associated to the path. To find the node, the kernel proxy 94 // calls the corresponding filesystem's GetNode() method. The corresponding 95 // method will be called. If the node cannot be found, errno is set and -1 is 96 // returned. 97 virtual int chmod(const char* path, mode_t mode); 98 virtual int mkdir(const char* path, mode_t mode); 99 virtual int rmdir(const char* path); 100 virtual int stat(const char* path, struct stat* buf); 101 102 // System calls that take a file descriptor as an argument: 103 // The kernel proxy will determine to which filesystem the file 104 // descriptor's corresponding file handle belongs. The 105 // associated filesystem's function will be called. 106 virtual ssize_t read(int fd, void* buf, size_t nbyte); 107 virtual ssize_t write(int fd, const void* buf, size_t nbyte); 108 109 virtual int fchmod(int fd, int prot); 110 virtual int fcntl(int fd, int request, va_list args); 111 virtual int fstat(int fd, struct stat* buf); 112 virtual int getdents(int fd, void* buf, unsigned int count); 113 virtual int fchdir(int fd); 114 virtual int ftruncate(int fd, off_t length); 115 virtual int fsync(int fd); 116 virtual int fdatasync(int fd); 117 virtual int isatty(int fd); 118 virtual int ioctl(int fd, int request, va_list args); 119 120 // lseek() relies on the filesystem's Stat() to determine whether or not the 121 // file handle corresponding to fd is a directory 122 virtual off_t lseek(int fd, off_t offset, int whence); 123 124 // remove() uses the filesystem's GetNode() and Stat() to determine whether 125 // or not the path corresponds to a directory or a file. The filesystem's 126 // Rmdir() or Unlink() is called accordingly. 127 virtual int remove(const char* path); 128 // unlink() is a simple wrapper around the filesystem's Unlink function. 129 virtual int unlink(const char* path); 130 virtual int truncate(const char* path, off_t len); 131 virtual int lstat(const char* path, struct stat* buf); 132 virtual int rename(const char* path, const char* newpath); 133 // access() uses the Filesystem's Stat(). 134 virtual int access(const char* path, int amode); 135 virtual int readlink(const char* path, char* buf, size_t count); 136 virtual int utimes(const char* filename, const struct timeval times[2]); 137 138 virtual int link(const char* oldpath, const char* newpath); 139 virtual int symlink(const char* oldpath, const char* newpath); 140 141 virtual void* mmap(void* addr, 142 size_t length, 143 int prot, 144 int flags, 145 int fd, 146 size_t offset); 147 virtual int munmap(void* addr, size_t length); 148 virtual int tcflush(int fd, int queue_selector); 149 virtual int tcgetattr(int fd, struct termios* termios_p); 150 virtual int tcsetattr(int fd, 151 int optional_actions, 152 const struct termios* termios_p); 153 154 virtual int kill(pid_t pid, int sig); 155 virtual int sigaction(int signum, 156 const struct sigaction* action, 157 struct sigaction* oaction); 158 159 #ifdef PROVIDES_SOCKET_API 160 virtual int select(int nfds, 161 fd_set* readfds, 162 fd_set* writefds, 163 fd_set* exceptfds, 164 struct timeval* timeout); 165 166 virtual int poll(struct pollfd* fds, nfds_t nfds, int timeout); 167 168 // Socket support functions 169 virtual int accept(int fd, struct sockaddr* addr, socklen_t* len); 170 virtual int bind(int fd, const struct sockaddr* addr, socklen_t len); 171 virtual int connect(int fd, const struct sockaddr* addr, socklen_t len); 172 virtual struct hostent* gethostbyname(const char* name); 173 virtual void freeaddrinfo(struct addrinfo* res); 174 virtual int getaddrinfo(const char* node, 175 const char* service, 176 const struct addrinfo* hints, 177 struct addrinfo** res); 178 virtual int getpeername(int fd, struct sockaddr* addr, socklen_t* len); 179 virtual int getsockname(int fd, struct sockaddr* addr, socklen_t* len); 180 virtual int getsockopt(int fd, 181 int lvl, 182 int optname, 183 void* optval, 184 socklen_t* len); 185 virtual int listen(int fd, int backlog); 186 virtual ssize_t recv(int fd, void* buf, size_t len, int flags); 187 virtual ssize_t recvfrom(int fd, 188 void* buf, 189 size_t len, 190 int flags, 191 struct sockaddr* addr, 192 socklen_t* addrlen); 193 virtual ssize_t recvmsg(int fd, struct msghdr* msg, int flags); 194 virtual ssize_t send(int fd, const void* buf, size_t len, int flags); 195 virtual ssize_t sendto(int fd, 196 const void* buf, 197 size_t len, 198 int flags, 199 const struct sockaddr* addr, 200 socklen_t addrlen); 201 virtual ssize_t sendmsg(int fd, const struct msghdr* msg, int flags); 202 virtual int setsockopt(int fd, 203 int lvl, 204 int optname, 205 const void* optval, 206 socklen_t len); 207 virtual int shutdown(int fd, int how); 208 virtual int socket(int domain, int type, int protocol); 209 virtual int socketpair(int domain, int type, int protocol, int* sv); 210 #endif // PROVIDES_SOCKET_API 211 212 protected: 213 Error MountInternal(const char* source, 214 const char* target, 215 const char* filesystemtype, 216 unsigned long mountflags, 217 const void* data, 218 bool create_fs_node, 219 ScopedFilesystem* out_filesystem); 220 221 Error CreateFsNode(const ScopedFilesystem& fs); 222 223 protected: 224 FsFactoryMap_t factories_; 225 sdk_util::ScopedRef<StreamFs> stream_fs_; 226 sdk_util::ScopedRef<DevFs> dev_fs_; 227 int dev_; 228 PepperInterface* ppapi_; 229 static KernelProxy* s_instance_; 230 struct sigaction sigwinch_handler_; 231 nacl_io_exit_handler_t exit_handler_; 232 void* exit_handler_user_data_; 233 #ifdef PROVIDES_SOCKET_API 234 HostResolver host_resolver_; 235 #endif 236 237 #ifdef PROVIDES_SOCKET_API 238 virtual int AcquireSocketHandle(int fd, ScopedKernelHandle* handle); 239 #endif 240 241 ScopedEventEmitter signal_emitter_; 242 DISALLOW_COPY_AND_ASSIGN(KernelProxy); 243 }; 244 245 } // namespace nacl_io 246 247 #endif // LIBRARIES_NACL_IO_KERNEL_PROXY_H_ 248