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/host_resolver.h" 12 #include "nacl_io/kernel_object.h" 13 #include "nacl_io/mount_factory.h" 14 #include "nacl_io/ossocket.h" 15 #include "nacl_io/ostypes.h" 16 #include "nacl_io/osutime.h" 17 18 struct timeval; 19 20 namespace nacl_io { 21 22 class PepperInterface; 23 24 // KernelProxy provide one-to-one mapping for libc kernel calls. Calls to the 25 // proxy will result in IO access to the provided Mount and MountNode objects. 26 // 27 // NOTE: The KernelProxy does not directly take any kernel locks, all locking 28 // is done by the parent class KernelObject. Instead, KernelProxy is 29 // responsible for taking the locks of the KernelHandle, and MountNode objects. 30 // For this reason, a KernelObject call should not be done while holding 31 // a handle or node lock. In addition, to ensure locking order, 32 // a KernelHandle lock must never be taken after taking the associated 33 // MountNode's lock. 34 // 35 // NOTE: The KernelProxy is the only class that should be setting errno. All 36 // other classes should return Error (as defined by nacl_io/error.h). 37 class KernelProxy : protected KernelObject { 38 public: 39 typedef std::map<std::string, MountFactory*> MountFactoryMap_t; 40 41 KernelProxy(); 42 virtual ~KernelProxy(); 43 44 // Takes ownership of |ppapi|. 45 // |ppapi| may be NULL. If so, no mount that uses pepper calls can be mounted. 46 virtual void Init(PepperInterface* ppapi); 47 48 // NaCl-only function to read resources specified in the NMF file. 49 virtual int open_resource(const char* file); 50 51 // KernelHandle and FD allocation and manipulation functions. 52 virtual int open(const char* path, int oflag); 53 virtual int close(int fd); 54 virtual int dup(int fd); 55 virtual int dup2(int fd, int newfd); 56 57 // Path related System calls handled by KernelProxy (not mount-specific) 58 virtual int chdir(const char* path); 59 virtual char* getcwd(char* buf, size_t size); 60 virtual char* getwd(char* buf); 61 virtual int mount(const char *source, 62 const char *target, 63 const char *filesystemtype, 64 unsigned long mountflags, 65 const void *data); 66 virtual int umount(const char *path); 67 68 // Stub system calls that don't do anything (yet), handled by KernelProxy. 69 virtual int chown(const char* path, uid_t owner, gid_t group); 70 virtual int fchown(int fd, uid_t owner, gid_t group); 71 virtual int lchown(const char* path, uid_t owner, gid_t group); 72 virtual int utime(const char* filename, const struct utimbuf* times); 73 74 // System calls that take a path as an argument: 75 // The kernel proxy will look for the Node associated to the path. To 76 // find the node, the kernel proxy calls the corresponding mount's GetNode() 77 // method. The corresponding method will be called. If the node 78 // cannot be found, errno is set and -1 is returned. 79 virtual int chmod(const char *path, mode_t mode); 80 virtual int mkdir(const char *path, mode_t mode); 81 virtual int rmdir(const char *path); 82 virtual int stat(const char *path, struct stat *buf); 83 84 // System calls that take a file descriptor as an argument: 85 // The kernel proxy will determine to which mount the file 86 // descriptor's corresponding file handle belongs. The 87 // associated mount's function will be called. 88 virtual ssize_t read(int fd, void *buf, size_t nbyte); 89 virtual ssize_t write(int fd, const void *buf, size_t nbyte); 90 91 virtual int fchmod(int fd, int prot); 92 virtual int fstat(int fd, struct stat *buf); 93 virtual int getdents(int fd, void *buf, unsigned int count); 94 virtual int ftruncate(int fd, off_t length); 95 virtual int fsync(int fd); 96 virtual int isatty(int fd); 97 virtual int ioctl(int d, int request, char *argp); 98 99 // lseek() relies on the mount's Stat() to determine whether or not the 100 // file handle corresponding to fd is a directory 101 virtual off_t lseek(int fd, off_t offset, int whence); 102 103 // remove() uses the mount's GetNode() and Stat() to determine whether or 104 // not the path corresponds to a directory or a file. The mount's Rmdir() 105 // or Unlink() is called accordingly. 106 virtual int remove(const char* path); 107 // unlink() is a simple wrapper around the mount's Unlink function. 108 virtual int unlink(const char* path); 109 // access() uses the Mount's Stat(). 110 virtual int access(const char* path, int amode); 111 112 virtual int link(const char* oldpath, const char* newpath); 113 virtual int symlink(const char* oldpath, const char* newpath); 114 115 virtual void* mmap(void* addr, 116 size_t length, 117 int prot, 118 int flags, 119 int fd, 120 size_t offset); 121 virtual int munmap(void* addr, size_t length); 122 virtual int tcflush(int fd, int queue_selector); 123 virtual int tcgetattr(int fd, struct termios* termios_p); 124 virtual int tcsetattr(int fd, int optional_actions, 125 const struct termios *termios_p); 126 127 #ifdef PROVIDES_SOCKET_API 128 virtual int select(int nfds, fd_set* readfds, fd_set* writefds, 129 fd_set* exceptfds, struct timeval* timeout); 130 131 virtual int poll(struct pollfd *fds, nfds_t nfds, int timeout); 132 133 // Socket support functions 134 virtual int accept(int fd, struct sockaddr* addr, socklen_t* len); 135 virtual int bind(int fd, const struct sockaddr* addr, socklen_t len); 136 virtual int connect(int fd, const struct sockaddr* addr, socklen_t len); 137 virtual struct hostent* gethostbyname(const char* name); 138 virtual int getpeername(int fd, struct sockaddr* addr, socklen_t* len); 139 virtual int getsockname(int fd, struct sockaddr* addr, socklen_t* len); 140 virtual int getsockopt(int fd, 141 int lvl, 142 int optname, 143 void* optval, 144 socklen_t* len); 145 virtual int listen(int fd, int backlog); 146 virtual ssize_t recv(int fd, 147 void* buf, 148 size_t len, 149 int flags); 150 virtual ssize_t recvfrom(int fd, 151 void* buf, 152 size_t len, 153 int flags, 154 struct sockaddr* addr, 155 socklen_t* addrlen); 156 virtual ssize_t recvmsg(int fd, struct msghdr* msg, int flags); 157 virtual ssize_t send(int fd, const void* buf, size_t len, int flags); 158 virtual ssize_t sendto(int fd, 159 const void* buf, 160 size_t len, 161 int flags, 162 const struct sockaddr* addr, 163 socklen_t addrlen); 164 virtual ssize_t sendmsg(int fd, const struct msghdr* msg, int flags); 165 virtual int setsockopt(int fd, 166 int lvl, 167 int optname, 168 const void* optval, 169 socklen_t len); 170 virtual int shutdown(int fd, int how); 171 virtual int socket(int domain, int type, int protocol); 172 virtual int socketpair(int domain, int type, int protocol, int* sv); 173 #endif // PROVIDES_SOCKET_API 174 175 protected: 176 MountFactoryMap_t factories_; 177 int dev_; 178 PepperInterface* ppapi_; 179 static KernelProxy *s_instance_; 180 #ifdef PROVIDES_SOCKET_API 181 HostResolver host_resolver_; 182 #endif 183 184 #ifdef PROVIDES_SOCKET_API 185 virtual int AcquireSocketHandle(int fd, ScopedKernelHandle* handle); 186 #endif 187 188 DISALLOW_COPY_AND_ASSIGN(KernelProxy); 189 }; 190 191 } // namespace nacl_io 192 193 #endif // LIBRARIES_NACL_IO_KERNEL_PROXY_H_ 194