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 <errno.h>
      6 
      7 #include "nacl_io/kernel_intercept.h"
      8 #include "nacl_io/kernel_proxy.h"
      9 #include "nacl_io/kernel_wrap.h"
     10 #include "nacl_io/osmman.h"
     11 #include "nacl_io/ossocket.h"
     12 #include "nacl_io/pepper_interface.h"
     13 #include "nacl_io/pepper_interface.h"
     14 #include "nacl_io/real_pepper_interface.h"
     15 
     16 using namespace nacl_io;
     17 
     18 #define ON_NOSYS_RETURN(x)    \
     19   if (!ki_is_initialized()) { \
     20     errno = ENOSYS;           \
     21     return x;                 \
     22   }
     23 
     24 static KernelProxy* s_kp;
     25 
     26 void ki_init(void* kp) {
     27   ki_init_ppapi(kp, 0, NULL);
     28 }
     29 
     30 void ki_init_ppapi(void* kp,
     31                    PP_Instance instance,
     32                    PPB_GetInterface get_browser_interface) {
     33   kernel_wrap_init();
     34 
     35   if (kp == NULL) kp = new KernelProxy();
     36   s_kp = static_cast<KernelProxy*>(kp);
     37 
     38   PepperInterface* ppapi = NULL;
     39   if (instance && get_browser_interface)
     40     ppapi = new RealPepperInterface(instance, get_browser_interface);
     41 
     42   s_kp->Init(ppapi);
     43 }
     44 
     45 int ki_is_initialized() {
     46   return s_kp != NULL;
     47 }
     48 
     49 void ki_uninit() {
     50   kernel_wrap_uninit();
     51   s_kp = NULL;
     52 }
     53 
     54 
     55 int ki_chdir(const char* path) {
     56   ON_NOSYS_RETURN(-1);
     57   return s_kp->chdir(path);
     58 }
     59 
     60 char* ki_getcwd(char* buf, size_t size) {
     61   // gtest uses getcwd in a static initializer. If we haven't initialized the
     62   // kernel-intercept yet, just return ".".
     63   if (!ki_is_initialized()) {
     64     if (size < 2) {
     65       errno = ERANGE;
     66       return NULL;
     67     }
     68     buf[0] = '.';
     69     buf[1] = 0;
     70     return buf;
     71   }
     72   return s_kp->getcwd(buf, size);
     73 }
     74 
     75 char* ki_getwd(char* buf) {
     76   ON_NOSYS_RETURN(NULL);
     77   return s_kp->getwd(buf);
     78 }
     79 
     80 int ki_dup(int oldfd) {
     81   ON_NOSYS_RETURN(-1);
     82   return s_kp->dup(oldfd);
     83 }
     84 
     85 int ki_dup2(int oldfd, int newfd) {
     86   ON_NOSYS_RETURN(-1);
     87   return s_kp->dup2(oldfd, newfd);
     88 }
     89 
     90 int ki_chmod(const char *path, mode_t mode) {
     91   ON_NOSYS_RETURN(-1);
     92   return s_kp->chmod(path, mode);
     93 }
     94 
     95 int ki_stat(const char *path, struct stat *buf) {
     96   ON_NOSYS_RETURN(-1);
     97   return s_kp->stat(path, buf);
     98 }
     99 
    100 int ki_mkdir(const char *path, mode_t mode) {
    101   ON_NOSYS_RETURN(-1);
    102   return s_kp->mkdir(path, mode);
    103 }
    104 
    105 int ki_rmdir(const char *path) {
    106   ON_NOSYS_RETURN(-1);
    107   return s_kp->rmdir(path);
    108 }
    109 
    110 int ki_mount(const char *source, const char *target, const char *filesystemtype,
    111              unsigned long mountflags, const void *data) {
    112   ON_NOSYS_RETURN(-1);
    113   return s_kp->mount(source, target, filesystemtype, mountflags, data);
    114 }
    115 
    116 int ki_umount(const char *path) {
    117   ON_NOSYS_RETURN(-1);
    118   return s_kp->umount(path);
    119 }
    120 
    121 int ki_open(const char *path, int oflag) {
    122   ON_NOSYS_RETURN(-1);
    123   return s_kp->open(path, oflag);
    124 }
    125 
    126 ssize_t ki_read(int fd, void *buf, size_t nbyte) {
    127   ON_NOSYS_RETURN(-1);
    128   return s_kp->read(fd, buf, nbyte);
    129 }
    130 
    131 ssize_t ki_write(int fd, const void *buf, size_t nbyte) {
    132   ON_NOSYS_RETURN(-1);
    133   return s_kp->write(fd, buf, nbyte);
    134 }
    135 
    136 int ki_fstat(int fd, struct stat *buf){
    137   ON_NOSYS_RETURN(-1);
    138   return s_kp->fstat(fd, buf);
    139 }
    140 
    141 int ki_getdents(int fd, void *buf, unsigned int count) {
    142   ON_NOSYS_RETURN(-1);
    143   return s_kp->getdents(fd, buf, count);
    144 }
    145 
    146 int ki_ftruncate(int fd, off_t length) {
    147   ON_NOSYS_RETURN(-1);
    148   return s_kp->ftruncate(fd, length);
    149 }
    150 
    151 int ki_fsync(int fd) {
    152   ON_NOSYS_RETURN(-1);
    153   return s_kp->fsync(fd);
    154 }
    155 
    156 int ki_isatty(int fd) {
    157   ON_NOSYS_RETURN(0);
    158   return s_kp->isatty(fd);
    159 }
    160 
    161 int ki_close(int fd) {
    162   ON_NOSYS_RETURN(-1);
    163   return s_kp->close(fd);
    164 }
    165 
    166 off_t ki_lseek(int fd, off_t offset, int whence) {
    167   ON_NOSYS_RETURN(-1);
    168   return s_kp->lseek(fd, offset, whence);
    169 }
    170 
    171 int ki_remove(const char* path) {
    172   ON_NOSYS_RETURN(-1);
    173   return s_kp->remove(path);
    174 }
    175 
    176 int ki_unlink(const char* path) {
    177   ON_NOSYS_RETURN(-1);
    178   return s_kp->unlink(path);
    179 }
    180 
    181 int ki_access(const char* path, int amode) {
    182   ON_NOSYS_RETURN(-1);
    183   return s_kp->access(path, amode);
    184 }
    185 
    186 int ki_link(const char* oldpath, const char* newpath) {
    187   ON_NOSYS_RETURN(-1);
    188   return s_kp->link(oldpath, newpath);
    189 }
    190 
    191 int ki_symlink(const char* oldpath, const char* newpath) {
    192   ON_NOSYS_RETURN(-1);
    193   return s_kp->symlink(oldpath, newpath);
    194 }
    195 
    196 void* ki_mmap(void* addr, size_t length, int prot, int flags, int fd,
    197               off_t offset) {
    198   ON_NOSYS_RETURN(MAP_FAILED);
    199   return s_kp->mmap(addr, length, prot, flags, fd, offset);
    200 }
    201 
    202 int ki_munmap(void* addr, size_t length) {
    203   ON_NOSYS_RETURN(-1);
    204   return s_kp->munmap(addr, length);
    205 }
    206 
    207 int ki_open_resource(const char* file) {
    208   ON_NOSYS_RETURN(-1);  return s_kp->open_resource(file);
    209 }
    210 
    211 int ki_ioctl(int d, int request, char* argp) {
    212   ON_NOSYS_RETURN(-1);
    213   return s_kp->ioctl(d, request, argp);
    214 }
    215 
    216 int ki_chown(const char* path, uid_t owner, gid_t group) {
    217   ON_NOSYS_RETURN(-1);
    218   return s_kp->chown(path, owner, group);
    219 }
    220 
    221 int ki_fchown(int fd, uid_t owner, gid_t group) {
    222   ON_NOSYS_RETURN(-1);
    223   return s_kp->fchown(fd, owner, group);
    224 }
    225 
    226 int ki_lchown(const char* path, uid_t owner, gid_t group) {
    227   ON_NOSYS_RETURN(-1);
    228   return s_kp->lchown(path, owner, group);
    229 }
    230 
    231 int ki_utime(const char* filename, const struct utimbuf* times) {
    232   ON_NOSYS_RETURN(-1);
    233   return s_kp->utime(filename, times);
    234 }
    235 
    236 int ki_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
    237   return s_kp->poll(fds, nfds, timeout);
    238 }
    239 
    240 int ki_select(int nfds, fd_set* readfds, fd_set* writefds,
    241               fd_set* exceptfds, struct timeval* timeout) {
    242   return s_kp->select(nfds, readfds, writefds, exceptfds, timeout);
    243 }
    244 
    245 int ki_tcflush(int fd, int queue_selector) {
    246   ON_NOSYS_RETURN(-1);
    247   return s_kp->tcflush(fd, queue_selector);
    248 }
    249 
    250 int ki_tcgetattr(int fd, struct termios* termios_p) {
    251   ON_NOSYS_RETURN(-1);
    252   return s_kp->tcgetattr(fd, termios_p);
    253 }
    254 
    255 int ki_tcsetattr(int fd, int optional_actions,
    256                  const struct termios *termios_p) {
    257   ON_NOSYS_RETURN(-1);
    258   return s_kp->tcsetattr(fd, optional_actions, termios_p);
    259 }
    260 
    261 #ifdef PROVIDES_SOCKET_API
    262 // Socket Functions
    263 int ki_accept(int fd, struct sockaddr* addr, socklen_t* len) {
    264   return s_kp->accept(fd, addr, len);
    265 }
    266 
    267 int ki_bind(int fd, const struct sockaddr* addr, socklen_t len) {
    268   return s_kp->bind(fd, addr, len);
    269 }
    270 
    271 int ki_connect(int fd, const struct sockaddr* addr, socklen_t len) {
    272   return s_kp->connect(fd, addr, len);
    273 }
    274 
    275 struct hostent* ki_gethostbyname(const char* name) {
    276   return s_kp->gethostbyname(name);
    277 }
    278 
    279 int ki_getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
    280   return s_kp->getpeername(fd, addr, len);
    281 }
    282 
    283 int ki_getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
    284   return s_kp->getsockname(fd, addr, len);
    285 }
    286 int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
    287   return s_kp->getsockopt(fd, lvl, optname, optval, len);
    288 }
    289 
    290 int ki_listen(int fd, int backlog) {
    291   return s_kp->listen(fd, backlog);
    292 }
    293 
    294 ssize_t ki_recv(int fd, void* buf, size_t len, int flags) {
    295   return s_kp->recv(fd, buf, len, flags);
    296 }
    297 
    298 ssize_t ki_recvfrom(int fd, void* buf, size_t len, int flags,
    299                  struct sockaddr* addr, socklen_t* addrlen) {
    300   return s_kp->recvfrom(fd, buf, len, flags, addr, addrlen);
    301 }
    302 
    303 ssize_t ki_recvmsg(int fd, struct msghdr* msg, int flags) {
    304   return s_kp->recvmsg(fd, msg, flags);
    305 }
    306 
    307 ssize_t ki_send(int fd, const void* buf, size_t len, int flags) {
    308   return s_kp->send(fd, buf, len, flags);
    309 }
    310 
    311 ssize_t ki_sendto(int fd, const void* buf, size_t len, int flags,
    312                const struct sockaddr* addr, socklen_t addrlen) {
    313   return s_kp->sendto(fd, buf, len, flags, addr, addrlen);
    314 }
    315 
    316 ssize_t ki_sendmsg(int fd, const struct msghdr* msg, int flags) {
    317   return s_kp->sendmsg(fd, msg, flags);
    318 }
    319 
    320 int ki_setsockopt(int fd, int lvl, int optname, const void* optval,
    321                   socklen_t len) {
    322   return s_kp->setsockopt(fd, lvl, optname, optval, len);
    323 }
    324 
    325 int ki_shutdown(int fd, int how) {
    326   return s_kp->shutdown(fd, how);
    327 }
    328 
    329 int ki_socket(int domain, int type, int protocol) {
    330   return s_kp->socket(domain, type, protocol);
    331 }
    332 
    333 int ki_socketpair(int domain, int type, int protocol, int* sv) {
    334   return s_kp->socketpair(domain, type, protocol, sv);
    335 }
    336 #endif  // PROVIDES_SOCKET_API
    337