• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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