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