kernel_intercept.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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#include "nacl_io/kernel_intercept.h"
6
7#include <errno.h>
8
9#include "nacl_io/kernel_proxy.h"
10#include "nacl_io/kernel_wrap.h"
11#include "nacl_io/osmman.h"
12#include "nacl_io/ossocket.h"
13#include "nacl_io/pepper_interface.h"
14#include "nacl_io/pepper_interface.h"
15#include "nacl_io/real_pepper_interface.h"
16
17using namespace nacl_io;
18
19#define ON_NOSYS_RETURN(x)    \
20  if (!ki_is_initialized()) { \
21    errno = ENOSYS;           \
22    return x;                 \
23  }
24
25static KernelProxy* s_kp;
26static bool s_kp_owned;
27
28void ki_init(void* kp) {
29  ki_init_ppapi(kp, 0, NULL);
30}
31
32void ki_init_ppapi(void* kp,
33                   PP_Instance instance,
34                   PPB_GetInterface get_browser_interface) {
35  kernel_wrap_init();
36
37  if (kp == NULL) {
38    s_kp = new KernelProxy();
39    s_kp_owned = true;
40  } else {
41    s_kp = static_cast<KernelProxy*>(kp);
42    s_kp_owned = false;
43  }
44
45
46  PepperInterface* ppapi = NULL;
47  if (instance && get_browser_interface)
48    ppapi = new RealPepperInterface(instance, get_browser_interface);
49
50  s_kp->Init(ppapi);
51}
52
53int ki_is_initialized() {
54  return s_kp != NULL;
55}
56
57void ki_uninit() {
58  kernel_wrap_uninit();
59  if (s_kp_owned)
60    delete s_kp;
61  s_kp = NULL;
62}
63
64int ki_chdir(const char* path) {
65  ON_NOSYS_RETURN(-1);
66  return s_kp->chdir(path);
67}
68
69char* ki_getcwd(char* buf, size_t size) {
70  // gtest uses getcwd in a static initializer. If we haven't initialized the
71  // kernel-intercept yet, just return ".".
72  if (!ki_is_initialized()) {
73    if (size < 2) {
74      errno = ERANGE;
75      return NULL;
76    }
77    buf[0] = '.';
78    buf[1] = 0;
79    return buf;
80  }
81  return s_kp->getcwd(buf, size);
82}
83
84char* ki_getwd(char* buf) {
85  ON_NOSYS_RETURN(NULL);
86  return s_kp->getwd(buf);
87}
88
89int ki_dup(int oldfd) {
90  ON_NOSYS_RETURN(-1);
91  return s_kp->dup(oldfd);
92}
93
94int ki_dup2(int oldfd, int newfd) {
95  ON_NOSYS_RETURN(-1);
96  return s_kp->dup2(oldfd, newfd);
97}
98
99int ki_chmod(const char *path, mode_t mode) {
100  ON_NOSYS_RETURN(-1);
101  return s_kp->chmod(path, mode);
102}
103
104int ki_fchdir(int fd) {
105  ON_NOSYS_RETURN(-1);
106  return s_kp->fchdir(fd);
107}
108
109int ki_fchmod(int fd, mode_t mode) {
110  ON_NOSYS_RETURN(-1);
111  return s_kp->fchmod(fd, mode);
112}
113
114int ki_stat(const char *path, struct stat *buf) {
115  ON_NOSYS_RETURN(-1);
116  return s_kp->stat(path, buf);
117}
118
119int ki_mkdir(const char *path, mode_t mode) {
120  ON_NOSYS_RETURN(-1);
121  return s_kp->mkdir(path, mode);
122}
123
124int ki_rmdir(const char *path) {
125  ON_NOSYS_RETURN(-1);
126  return s_kp->rmdir(path);
127}
128
129int ki_mount(const char *source, const char *target, const char *filesystemtype,
130             unsigned long mountflags, const void *data) {
131  ON_NOSYS_RETURN(-1);
132  return s_kp->mount(source, target, filesystemtype, mountflags, data);
133}
134
135int ki_umount(const char *path) {
136  ON_NOSYS_RETURN(-1);
137  return s_kp->umount(path);
138}
139
140int ki_open(const char *path, int oflag) {
141  ON_NOSYS_RETURN(-1);
142  return s_kp->open(path, oflag);
143}
144
145int ki_pipe(int pipefds[2]) {
146  ON_NOSYS_RETURN(-1);
147  return s_kp->pipe(pipefds);
148}
149
150ssize_t ki_read(int fd, void *buf, size_t nbyte) {
151  ON_NOSYS_RETURN(-1);
152  return s_kp->read(fd, buf, nbyte);
153}
154
155ssize_t ki_write(int fd, const void *buf, size_t nbyte) {
156  ON_NOSYS_RETURN(-1);
157  return s_kp->write(fd, buf, nbyte);
158}
159
160int ki_fstat(int fd, struct stat *buf){
161  ON_NOSYS_RETURN(-1);
162  return s_kp->fstat(fd, buf);
163}
164
165int ki_getdents(int fd, void *buf, unsigned int count) {
166  ON_NOSYS_RETURN(-1);
167  return s_kp->getdents(fd, buf, count);
168}
169
170int ki_ftruncate(int fd, off_t length) {
171  ON_NOSYS_RETURN(-1);
172  return s_kp->ftruncate(fd, length);
173}
174
175int ki_fsync(int fd) {
176  ON_NOSYS_RETURN(-1);
177  return s_kp->fsync(fd);
178}
179
180int ki_fdatasync(int fd) {
181  ON_NOSYS_RETURN(-1);
182  return s_kp->fdatasync(fd);
183}
184
185int ki_isatty(int fd) {
186  ON_NOSYS_RETURN(0);
187  return s_kp->isatty(fd);
188}
189
190int ki_close(int fd) {
191  ON_NOSYS_RETURN(-1);
192  return s_kp->close(fd);
193}
194
195off_t ki_lseek(int fd, off_t offset, int whence) {
196  ON_NOSYS_RETURN(-1);
197  return s_kp->lseek(fd, offset, whence);
198}
199
200int ki_remove(const char* path) {
201  ON_NOSYS_RETURN(-1);
202  return s_kp->remove(path);
203}
204
205int ki_unlink(const char* path) {
206  ON_NOSYS_RETURN(-1);
207  return s_kp->unlink(path);
208}
209
210int ki_truncate(const char* path, off_t length) {
211  ON_NOSYS_RETURN(-1);
212  return s_kp->truncate(path, length);
213}
214
215int ki_lstat(const char* path, struct stat* buf) {
216  ON_NOSYS_RETURN(-1);
217  return s_kp->lstat(path, buf);
218}
219
220int ki_link(const char* oldpath, const char* newpath) {
221  ON_NOSYS_RETURN(-1);
222  return s_kp->link(oldpath, newpath);
223}
224
225int ki_rename(const char* path, const char* newpath) {
226  ON_NOSYS_RETURN(-1);
227  return s_kp->rename(path, newpath);
228}
229
230int ki_symlink(const char* oldpath, const char* newpath) {
231  ON_NOSYS_RETURN(-1);
232  return s_kp->symlink(oldpath, newpath);
233}
234
235int ki_access(const char* path, int amode) {
236  ON_NOSYS_RETURN(-1);
237  return s_kp->access(path, amode);
238}
239
240int ki_readlink(const char *path, char *buf, size_t count) {
241  ON_NOSYS_RETURN(-1);
242  return s_kp->readlink(path, buf, count);
243}
244
245int ki_utimes(const char *path, const struct timeval times[2]) {
246  ON_NOSYS_RETURN(-1);
247  return s_kp->utimes(path, times);
248}
249
250void* ki_mmap(void* addr, size_t length, int prot, int flags, int fd,
251              off_t offset) {
252  ON_NOSYS_RETURN(MAP_FAILED);
253  return s_kp->mmap(addr, length, prot, flags, fd, offset);
254}
255
256int ki_munmap(void* addr, size_t length) {
257  ON_NOSYS_RETURN(-1);
258  return s_kp->munmap(addr, length);
259}
260
261int ki_open_resource(const char* file) {
262  ON_NOSYS_RETURN(-1);  return s_kp->open_resource(file);
263}
264
265int ki_fcntl(int d, int request, va_list args) {
266  ON_NOSYS_RETURN(-1);
267  return s_kp->fcntl(d, request, args);
268}
269
270int ki_ioctl(int d, int request, va_list args) {
271  ON_NOSYS_RETURN(-1);
272  return s_kp->ioctl(d, request, args);
273}
274
275int ki_chown(const char* path, uid_t owner, gid_t group) {
276  ON_NOSYS_RETURN(-1);
277  return s_kp->chown(path, owner, group);
278}
279
280int ki_fchown(int fd, uid_t owner, gid_t group) {
281  ON_NOSYS_RETURN(-1);
282  return s_kp->fchown(fd, owner, group);
283}
284
285int ki_lchown(const char* path, uid_t owner, gid_t group) {
286  ON_NOSYS_RETURN(-1);
287  return s_kp->lchown(path, owner, group);
288}
289
290int ki_utime(const char* filename, const struct utimbuf* times) {
291  ON_NOSYS_RETURN(-1);
292  return s_kp->utime(filename, times);
293}
294
295int ki_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
296  return s_kp->poll(fds, nfds, timeout);
297}
298
299int ki_select(int nfds, fd_set* readfds, fd_set* writefds,
300              fd_set* exceptfds, struct timeval* timeout) {
301  return s_kp->select(nfds, readfds, writefds, exceptfds, timeout);
302}
303
304int ki_tcflush(int fd, int queue_selector) {
305  ON_NOSYS_RETURN(-1);
306  return s_kp->tcflush(fd, queue_selector);
307}
308
309int ki_tcgetattr(int fd, struct termios* termios_p) {
310  ON_NOSYS_RETURN(-1);
311  return s_kp->tcgetattr(fd, termios_p);
312}
313
314int ki_tcsetattr(int fd, int optional_actions,
315                 const struct termios *termios_p) {
316  ON_NOSYS_RETURN(-1);
317  return s_kp->tcsetattr(fd, optional_actions, termios_p);
318}
319
320int ki_kill(pid_t pid, int sig) {
321  ON_NOSYS_RETURN(-1);
322  return s_kp->kill(pid, sig);
323}
324
325int ki_killpg(pid_t pid, int sig) {
326  errno = ENOSYS;
327  return -1;
328}
329
330int ki_sigaction(int, const struct sigaction*, struct sigaction*) {
331  errno = ENOSYS;
332  return -1;
333}
334
335int ki_sigpause(int sigmask) {
336  errno = ENOSYS;
337  return -1;
338}
339
340int ki_sigpending(sigset_t* set) {
341  errno = ENOSYS;
342  return -1;
343}
344
345int ki_sigsuspend(const sigset_t* set) {
346  errno = ENOSYS;
347  return -1;
348}
349
350sighandler_t ki_signal(int signum, sighandler_t handler) {
351  ON_NOSYS_RETURN(SIG_ERR);
352  return s_kp->sigset(signum, handler);
353}
354
355sighandler_t ki_sigset(int signum, sighandler_t handler) {
356  ON_NOSYS_RETURN(SIG_ERR);
357  return s_kp->sigset(signum, handler);
358}
359
360#ifdef PROVIDES_SOCKET_API
361// Socket Functions
362int ki_accept(int fd, struct sockaddr* addr, socklen_t* len) {
363  return s_kp->accept(fd, addr, len);
364}
365
366int ki_bind(int fd, const struct sockaddr* addr, socklen_t len) {
367  return s_kp->bind(fd, addr, len);
368}
369
370int ki_connect(int fd, const struct sockaddr* addr, socklen_t len) {
371  return s_kp->connect(fd, addr, len);
372}
373
374struct hostent* ki_gethostbyname(const char* name) {
375  return s_kp->gethostbyname(name);
376}
377
378int ki_getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
379  return s_kp->getpeername(fd, addr, len);
380}
381
382int ki_getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
383  return s_kp->getsockname(fd, addr, len);
384}
385
386int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
387  return s_kp->getsockopt(fd, lvl, optname, optval, len);
388}
389
390int ki_listen(int fd, int backlog) {
391  return s_kp->listen(fd, backlog);
392}
393
394ssize_t ki_recv(int fd, void* buf, size_t len, int flags) {
395  return s_kp->recv(fd, buf, len, flags);
396}
397
398ssize_t ki_recvfrom(int fd, void* buf, size_t len, int flags,
399                 struct sockaddr* addr, socklen_t* addrlen) {
400  return s_kp->recvfrom(fd, buf, len, flags, addr, addrlen);
401}
402
403ssize_t ki_recvmsg(int fd, struct msghdr* msg, int flags) {
404  return s_kp->recvmsg(fd, msg, flags);
405}
406
407ssize_t ki_send(int fd, const void* buf, size_t len, int flags) {
408  return s_kp->send(fd, buf, len, flags);
409}
410
411ssize_t ki_sendto(int fd, const void* buf, size_t len, int flags,
412               const struct sockaddr* addr, socklen_t addrlen) {
413  return s_kp->sendto(fd, buf, len, flags, addr, addrlen);
414}
415
416ssize_t ki_sendmsg(int fd, const struct msghdr* msg, int flags) {
417  return s_kp->sendmsg(fd, msg, flags);
418}
419
420int ki_setsockopt(int fd, int lvl, int optname, const void* optval,
421                  socklen_t len) {
422  return s_kp->setsockopt(fd, lvl, optname, optval, len);
423}
424
425int ki_shutdown(int fd, int how) {
426  return s_kp->shutdown(fd, how);
427}
428
429int ki_socket(int domain, int type, int protocol) {
430  return s_kp->socket(domain, type, protocol);
431}
432
433int ki_socketpair(int domain, int type, int protocol, int* sv) {
434  return s_kp->socketpair(domain, type, protocol, sv);
435}
436#endif  // PROVIDES_SOCKET_API
437