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