summaryrefslogtreecommitdiffstats
path: root/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
blob: e037110c9ead61a3765b40bbef34a1b1c715b43d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBRARIES_NACL_IO_KERNEL_PROXY_H_
#define LIBRARIES_NACL_IO_KERNEL_PROXY_H_

#include <map>
#include <string>

#include "nacl_io/event_emitter.h"
#include "nacl_io/host_resolver.h"
#include "nacl_io/kernel_object.h"
#include "nacl_io/mount_factory.h"
#include "nacl_io/mount_stream.h"
#include "nacl_io/ossignal.h"
#include "nacl_io/ossocket.h"
#include "nacl_io/ostypes.h"
#include "nacl_io/osutime.h"

struct fuse_operations;
struct timeval;

namespace nacl_io {

class PepperInterface;


// KernelProxy provide one-to-one mapping for libc kernel calls.  Calls to the
// proxy will result in IO access to the provided Mount and MountNode objects.
//
// NOTE: The KernelProxy does not directly take any kernel locks, all locking
// is done by the parent class KernelObject.  Instead, KernelProxy is
// responsible for taking the locks of the KernelHandle, and MountNode objects.
// For this reason, a KernelObject call should not be done while holding
// a handle or node lock.  In addition, to ensure locking order,
// a KernelHandle lock must never be taken after taking the associated
// MountNode's lock.
//
// NOTE: The KernelProxy is the only class that should be setting errno. All
// other classes should return Error (as defined by nacl_io/error.h).
class KernelProxy : protected KernelObject {
 public:
  typedef std::map<std::string, MountFactory*> MountFactoryMap_t;

  KernelProxy();
  virtual ~KernelProxy();

  // Takes ownership of |ppapi|.
  // |ppapi| may be NULL. If so, no mount that uses pepper calls can be mounted.
  virtual Error Init(PepperInterface* ppapi);

  // Register/Unregister a new mount type. See the documentation in nacl_io.h
  // for more info.
  bool RegisterMountType(const char* mount_type, fuse_operations* fuse_ops);
  bool UnregisterMountType(const char* mount_type);

  virtual int pipe(int pipefds[2]);

  // NaCl-only function to read resources specified in the NMF file.
  virtual int open_resource(const char* file);

  // KernelHandle and FD allocation and manipulation functions.
  virtual int open(const char* path, int open_flags);
  virtual int close(int fd);
  virtual int dup(int fd);
  virtual int dup2(int fd, int newfd);

  // Path related System calls handled by KernelProxy (not mount-specific)
  virtual int chdir(const char* path);
  virtual char* getcwd(char* buf, size_t size);
  virtual char* getwd(char* buf);
  virtual int mount(const char *source,
                    const char *target,
                    const char *filesystemtype,
                    unsigned long mountflags,
                    const void *data);
  virtual int umount(const char *path);

  // Stub system calls that don't do anything (yet), handled by KernelProxy.
  virtual int chown(const char* path, uid_t owner, gid_t group);
  virtual int fchown(int fd, uid_t owner, gid_t group);
  virtual int lchown(const char* path, uid_t owner, gid_t group);
  virtual int utime(const char* filename, const struct utimbuf* times);

  // System calls that take a path as an argument:
  // The kernel proxy will look for the Node associated to the path. To
  // find the node, the kernel proxy calls the corresponding mount's GetNode()
  // method. The corresponding  method will be called. If the node
  // cannot be found, errno is set and -1 is returned.
  virtual int chmod(const char *path, mode_t mode);
  virtual int mkdir(const char *path, mode_t mode);
  virtual int rmdir(const char *path);
  virtual int stat(const char *path, struct stat *buf);

  // System calls that take a file descriptor as an argument:
  // The kernel proxy will determine to which mount the file
  // descriptor's corresponding file handle belongs.  The
  // associated mount's function will be called.
  virtual ssize_t read(int fd, void *buf, size_t nbyte);
  virtual ssize_t write(int fd, const void *buf, size_t nbyte);

  virtual int fchmod(int fd, int prot);
  virtual int fcntl(int fd, int request, va_list args);
  virtual int fstat(int fd, struct stat *buf);
  virtual int getdents(int fd, void *buf, unsigned int count);
  virtual int fchdir(int fd);
  virtual int ftruncate(int fd, off_t length);
  virtual int fsync(int fd);
  virtual int fdatasync(int fd);
  virtual int isatty(int fd);
  virtual int ioctl(int fd, int request, va_list args);

  // lseek() relies on the mount's Stat() to determine whether or not the
  // file handle corresponding to fd is a directory
  virtual off_t lseek(int fd, off_t offset, int whence);

  // remove() uses the mount's GetNode() and Stat() to determine whether or
  // not the path corresponds to a directory or a file.  The mount's Rmdir()
  // or Unlink() is called accordingly.
  virtual int remove(const char* path);
  // unlink() is a simple wrapper around the mount's Unlink function.
  virtual int unlink(const char* path);
  virtual int truncate(const char* path, off_t len);
  virtual int lstat(const char* path, struct stat* buf);
  virtual int rename(const char* path, const char* newpath);
  // access() uses the Mount's Stat().
  virtual int access(const char* path, int amode);
  virtual int readlink(const char *path, char *buf, size_t count);
  virtual int utimes(const char *filename, const struct timeval times[2]);

  virtual int link(const char* oldpath, const char* newpath);
  virtual int symlink(const char* oldpath, const char* newpath);

  virtual void* mmap(void* addr,
                     size_t length,
                     int prot,
                     int flags,
                     int fd,
                     size_t offset);
  virtual int munmap(void* addr, size_t length);
  virtual int tcflush(int fd, int queue_selector);
  virtual int tcgetattr(int fd, struct termios* termios_p);
  virtual int tcsetattr(int fd, int optional_actions,
                           const struct termios *termios_p);

  virtual int kill(pid_t pid, int sig);
  virtual int sigaction(int signum, const struct sigaction* action,
                        struct sigaction* oaction);

#ifdef PROVIDES_SOCKET_API
  virtual int select(int nfds, fd_set* readfds, fd_set* writefds,
                    fd_set* exceptfds, struct timeval* timeout);

  virtual int poll(struct pollfd *fds, nfds_t nfds, int timeout);

  // Socket support functions
  virtual int accept(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int bind(int fd, const struct sockaddr* addr, socklen_t len);
  virtual int connect(int fd, const struct sockaddr* addr, socklen_t len);
  virtual struct hostent* gethostbyname(const char* name);
  virtual int getpeername(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int getsockname(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int getsockopt(int fd,
                         int lvl,
                         int optname,
                         void* optval,
                         socklen_t* len);
  virtual int listen(int fd, int backlog);
  virtual ssize_t recv(int fd,
                       void* buf,
                       size_t len,
                       int flags);
  virtual ssize_t recvfrom(int fd,
                           void* buf,
                           size_t len,
                           int flags,
                           struct sockaddr* addr,
                           socklen_t* addrlen);
  virtual ssize_t recvmsg(int fd, struct msghdr* msg, int flags);
  virtual ssize_t send(int fd, const void* buf, size_t len, int flags);
  virtual ssize_t sendto(int fd,
                         const void* buf,
                         size_t len,
                         int flags,
                         const struct sockaddr* addr,
                         socklen_t addrlen);
  virtual ssize_t sendmsg(int fd, const struct msghdr* msg, int flags);
  virtual int setsockopt(int fd,
                         int lvl,
                         int optname,
                         const void* optval,
                         socklen_t len);
  virtual int shutdown(int fd, int how);
  virtual int socket(int domain, int type, int protocol);
  virtual int socketpair(int domain, int type, int protocol, int* sv);
#endif  // PROVIDES_SOCKET_API

 protected:
  MountFactoryMap_t factories_;
  sdk_util::ScopedRef<MountStream> stream_mount_;
  int dev_;
  PepperInterface* ppapi_;
  static KernelProxy *s_instance_;
  struct sigaction sigwinch_handler_;
#ifdef PROVIDES_SOCKET_API
  HostResolver host_resolver_;
#endif

#ifdef PROVIDES_SOCKET_API
  virtual int AcquireSocketHandle(int fd, ScopedKernelHandle* handle);
#endif

  ScopedEventEmitter signal_emitter_;
  DISALLOW_COPY_AND_ASSIGN(KernelProxy);
};

}  // namespace nacl_io

#endif  // LIBRARIES_NACL_IO_KERNEL_PROXY_H_