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