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