kernel_proxy.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_proxy.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <assert.h> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <errno.h> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <fcntl.h> 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <limits.h> 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <poll.h> 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <pthread.h> 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdio.h> 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string.h> 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sys/time.h> 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <unistd.h> 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <iterator> 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/host_resolver.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_handle.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_wrap_real.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_dev.h" 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_html5fs.h" 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_http.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_mem.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node.h" 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_pipe.h" 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_tcp.h" 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_udp.h" 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_passthrough.h" 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_stream.h" 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/osmman.h" 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/ossocket.h" 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/osstat.h" 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/path.h" 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/pepper_interface.h" 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/typed_mount_factory.h" 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/auto_lock.h" 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/ref_object.h" 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/string_util.h" 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef MAXPATHLEN 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define MAXPATHLEN 256 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace nacl_io { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sigwinch_handler_(SIG_IGN), 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch signal_emitter_(new EventEmitter) { 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() { 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Clean up the MountFactories. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (MountFactoryMap_t::iterator i = factories_.begin(); 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch i != factories_.end(); 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ++i) { 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete i->second; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delete ppapi_; 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochError KernelProxy::Init(PepperInterface* ppapi) { 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Error rtn = 0; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ppapi_ = ppapi; 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dev_ = 1; 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["memfs"] = new TypedMountFactory<MountMem>; 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["dev"] = new TypedMountFactory<MountDev>; 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>; 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["httpfs"] = new TypedMountFactory<MountHttp>; 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>; 79 80 int result; 81 result = mount("", "/", "passthroughfs", 0, NULL); 82 if (result != 0) { 83 assert(false); 84 rtn = errno; 85 } 86 87 result = mount("", "/dev", "dev", 0, NULL); 88 if (result != 0) { 89 assert(false); 90 rtn = errno; 91 } 92 93 // Open the first three in order to get STDIN, STDOUT, STDERR 94 int fd; 95 fd = open("/dev/stdin", O_RDONLY); 96 assert(fd == 0); 97 if (fd < 0) 98 rtn = errno; 99 100 fd = open("/dev/stdout", O_WRONLY); 101 assert(fd == 1); 102 if (fd < 0) 103 rtn = errno; 104 105 fd = open("/dev/stderr", O_WRONLY); 106 assert(fd == 2); 107 if (fd < 0) 108 rtn = errno; 109 110#ifdef PROVIDES_SOCKET_API 111 host_resolver_.Init(ppapi_); 112#endif 113 114 StringMap_t args; 115 stream_mount_.reset(new MountStream()); 116 result = stream_mount_->Init(0, args, ppapi); 117 if (result != 0) { 118 assert(false); 119 rtn = result; 120 } 121 122 return rtn; 123} 124 125int KernelProxy::open_resource(const char* path) { 126 ScopedMount mnt; 127 Path rel; 128 129 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 130 if (error) { 131 errno = error; 132 return -1; 133 } 134 135 ScopedMountNode node; 136 error = mnt->OpenResource(rel, &node); 137 if (error) { 138 // OpenResource failed, try Open(). 139 error = mnt->Open(rel, O_RDONLY, &node); 140 if (error) { 141 errno = error; 142 return -1; 143 } 144 } 145 146 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 147 error = handle->Init(O_RDONLY); 148 if (error) { 149 errno = error; 150 return -1; 151 } 152 153 return AllocateFD(handle); 154} 155 156int KernelProxy::open(const char* path, int open_flags) { 157 ScopedMount mnt; 158 ScopedMountNode node; 159 160 Error error = AcquireMountAndNode(path, open_flags, &mnt, &node); 161 if (error) { 162 errno = error; 163 return -1; 164 } 165 166 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 167 error = handle->Init(open_flags); 168 if (error) { 169 errno = error; 170 return -1; 171 } 172 173 return AllocateFD(handle); 174} 175 176int KernelProxy::pipe(int pipefds[2]) { 177 MountNodePipe* pipe = new MountNodePipe(stream_mount_.get()); 178 ScopedMountNode node(pipe); 179 180 if (pipe->Init(S_IREAD | S_IWRITE) == 0) { 181 ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); 182 ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); 183 184 // Should never fail, but... 185 if (handle0->Init(S_IREAD) || handle1->Init(S_IWRITE)) { 186 errno = EACCES; 187 return -1; 188 } 189 190 pipefds[0] = AllocateFD(handle0); 191 pipefds[1] = AllocateFD(handle1); 192 return 0; 193 } 194 195 errno = ENOSYS; 196 return -1; 197} 198 199int KernelProxy::close(int fd) { 200 ScopedKernelHandle handle; 201 Error error = AcquireHandle(fd, &handle); 202 if (error) { 203 errno = error; 204 return -1; 205 } 206 207 // Remove the FD from the process open file descriptor map 208 FreeFD(fd); 209 return 0; 210} 211 212int KernelProxy::dup(int oldfd) { 213 ScopedKernelHandle handle; 214 Error error = AcquireHandle(oldfd, &handle); 215 if (error) { 216 errno = error; 217 return -1; 218 } 219 220 return AllocateFD(handle); 221} 222 223int KernelProxy::dup2(int oldfd, int newfd) { 224 // If it's the same file handle, just return 225 if (oldfd == newfd) 226 return newfd; 227 228 ScopedKernelHandle old_handle; 229 Error error = AcquireHandle(oldfd, &old_handle); 230 if (error) { 231 errno = error; 232 return -1; 233 } 234 235 FreeAndReassignFD(newfd, old_handle); 236 return newfd; 237} 238 239int KernelProxy::chdir(const char* path) { 240 Error error = SetCWD(path); 241 if (error) { 242 errno = error; 243 return -1; 244 } 245 return 0; 246} 247 248char* KernelProxy::getcwd(char* buf, size_t size) { 249 std::string cwd = GetCWD(); 250 251 if (size <= 0) { 252 errno = EINVAL; 253 return NULL; 254 } 255 256 // If size is 0, allocate as much as we need. 257 if (size == 0) { 258 size = cwd.size() + 1; 259 } 260 261 // Verify the buffer is large enough 262 if (size <= cwd.size()) { 263 errno = ERANGE; 264 return NULL; 265 } 266 267 // Allocate the buffer if needed 268 if (buf == NULL) { 269 buf = static_cast<char*>(malloc(size)); 270 } 271 272 strcpy(buf, cwd.c_str()); 273 return buf; 274} 275 276char* KernelProxy::getwd(char* buf) { 277 if (NULL == buf) { 278 errno = EFAULT; 279 return NULL; 280 } 281 return getcwd(buf, MAXPATHLEN); 282} 283 284int KernelProxy::chmod(const char* path, mode_t mode) { 285 int fd = KernelProxy::open(path, O_RDONLY); 286 if (-1 == fd) 287 return -1; 288 289 int result = fchmod(fd, mode); 290 close(fd); 291 return result; 292} 293 294int KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 295 return 0; 296} 297 298int KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 299 return 0; 300} 301 302int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 303 return 0; 304} 305 306int KernelProxy::utime(const char* filename, const struct utimbuf* times) { 307 return 0; 308} 309 310int KernelProxy::mkdir(const char* path, mode_t mode) { 311 ScopedMount mnt; 312 Path rel; 313 314 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 315 if (error) { 316 errno = error; 317 return -1; 318 } 319 320 error = mnt->Mkdir(rel, mode); 321 if (error) { 322 errno = error; 323 return -1; 324 } 325 326 return 0; 327} 328 329int KernelProxy::rmdir(const char* path) { 330 ScopedMount mnt; 331 Path rel; 332 333 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 334 if (error) { 335 errno = error; 336 return -1; 337 } 338 339 error = mnt->Rmdir(rel); 340 if (error) { 341 errno = error; 342 return -1; 343 } 344 345 return 0; 346} 347 348int KernelProxy::stat(const char* path, struct stat* buf) { 349 int fd = open(path, O_RDONLY); 350 if (-1 == fd) 351 return -1; 352 353 int result = fstat(fd, buf); 354 close(fd); 355 return result; 356} 357 358 359int KernelProxy::mount(const char* source, 360 const char* target, 361 const char* filesystemtype, 362 unsigned long mountflags, 363 const void* data) { 364 std::string abs_path = GetAbsParts(target).Join(); 365 366 // Find a factory of that type 367 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); 368 if (factory == factories_.end()) { 369 errno = ENODEV; 370 return -1; 371 } 372 373 // Create a map of settings 374 StringMap_t smap; 375 smap["SOURCE"] = source; 376 smap["TARGET"] = abs_path; 377 378 if (data) { 379 std::vector<std::string> elements; 380 sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 381 382 for (std::vector<std::string>::const_iterator it = elements.begin(); 383 it != elements.end(); ++it) { 384 size_t location = it->find('='); 385 if (location != std::string::npos) { 386 std::string key = it->substr(0, location); 387 std::string val = it->substr(location + 1); 388 smap[key] = val; 389 } else { 390 smap[*it] = "TRUE"; 391 } 392 } 393 } 394 395 ScopedMount mnt; 396 Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt); 397 if (error) { 398 errno = error; 399 return -1; 400 } 401 402 error = AttachMountAtPath(mnt, abs_path); 403 if (error) { 404 errno = error; 405 return -1; 406 } 407 408 return 0; 409} 410 411int KernelProxy::umount(const char* path) { 412 Error error = DetachMountAtPath(path); 413 if (error) { 414 errno = error; 415 return -1; 416 } 417 return 0; 418} 419 420ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 421 ScopedKernelHandle handle; 422 Error error = AcquireHandle(fd, &handle); 423 if (error) { 424 errno = error; 425 return -1; 426 } 427 428 int cnt = 0; 429 error = handle->Read(buf, nbytes, &cnt); 430 if (error) { 431 errno = error; 432 return -1; 433 } 434 435 return cnt; 436} 437 438ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 439 ScopedKernelHandle handle; 440 Error error = AcquireHandle(fd, &handle); 441 if (error) { 442 errno = error; 443 return -1; 444 } 445 446 int cnt = 0; 447 error = handle->Write(buf, nbytes, &cnt); 448 if (error) { 449 errno = error; 450 return -1; 451 } 452 453 return cnt; 454} 455 456int KernelProxy::fstat(int fd, struct stat* buf) { 457 ScopedKernelHandle handle; 458 Error error = AcquireHandle(fd, &handle); 459 if (error) { 460 errno = error; 461 return -1; 462 } 463 464 error = handle->node()->GetStat(buf); 465 if (error) { 466 errno = error; 467 return -1; 468 } 469 470 return 0; 471} 472 473int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 474 ScopedKernelHandle handle; 475 Error error = AcquireHandle(fd, &handle); 476 if (error) { 477 errno = error; 478 return -1; 479 } 480 481 int cnt = 0; 482 error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 483 if (error) 484 errno = error; 485 486 return cnt; 487} 488 489int KernelProxy::fchdir(int fd) { 490 errno = ENOSYS; 491 return -1; 492} 493 494int KernelProxy::ftruncate(int fd, off_t length) { 495 ScopedKernelHandle handle; 496 Error error = AcquireHandle(fd, &handle); 497 if (error) { 498 errno = error; 499 return -1; 500 } 501 502 error = handle->node()->FTruncate(length); 503 if (error) { 504 errno = error; 505 return -1; 506 } 507 508 return 0; 509} 510 511int KernelProxy::fsync(int fd) { 512 ScopedKernelHandle handle; 513 Error error = AcquireHandle(fd, &handle); 514 if (error) { 515 errno = error; 516 return -1; 517 } 518 519 error = handle->node()->FSync(); 520 if (error) { 521 errno = error; 522 return -1; 523 } 524 525 return 0; 526} 527 528int KernelProxy::fdatasync(int fd) { 529 errno = ENOSYS; 530 return -1; 531} 532 533int KernelProxy::isatty(int fd) { 534 ScopedKernelHandle handle; 535 Error error = AcquireHandle(fd, &handle); 536 if (error) { 537 errno = error; 538 return -1; 539 } 540 541 error = handle->node()->IsaTTY(); 542 if (error) { 543 errno = error; 544 return -1; 545 } 546 547 return 0; 548} 549 550int KernelProxy::ioctl(int fd, int request, va_list args) { 551 ScopedKernelHandle handle; 552 Error error = AcquireHandle(fd, &handle); 553 if (error) { 554 errno = error; 555 return -1; 556 } 557 558 error = handle->node()->VIoctl(request, args); 559 if (error) { 560 errno = error; 561 return -1; 562 } 563 564 return 0; 565} 566 567off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 568 ScopedKernelHandle handle; 569 Error error = AcquireHandle(fd, &handle); 570 if (error) { 571 errno = error; 572 return -1; 573 } 574 575 off_t new_offset; 576 error = handle->Seek(offset, whence, &new_offset); 577 if (error) { 578 errno = error; 579 return -1; 580 } 581 582 return new_offset; 583} 584 585int KernelProxy::unlink(const char* path) { 586 ScopedMount mnt; 587 Path rel; 588 589 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 590 if (error) { 591 errno = error; 592 return -1; 593 } 594 595 error = mnt->Unlink(rel); 596 if (error) { 597 errno = error; 598 return -1; 599 } 600 601 return 0; 602} 603 604int KernelProxy::truncate(const char* path, off_t len) { 605 errno = ENOSYS; 606 return -1; 607} 608 609int KernelProxy::lstat(const char* path, struct stat* buf) { 610 errno = ENOSYS; 611 return -1; 612} 613 614int KernelProxy::rename(const char* path, const char* newpath) { 615 errno = ENOSYS; 616 return -1; 617} 618 619int KernelProxy::remove(const char* path) { 620 ScopedMount mnt; 621 Path rel; 622 623 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 624 if (error) { 625 errno = error; 626 return -1; 627 } 628 629 error = mnt->Remove(rel); 630 if (error) { 631 errno = error; 632 return -1; 633 } 634 635 return 0; 636} 637 638// TODO(noelallen): Needs implementation. 639int KernelProxy::fchmod(int fd, int mode) { 640 ScopedKernelHandle handle; 641 Error error = AcquireHandle(fd, &handle); 642 if (error) { 643 errno = error; 644 return -1; 645 } 646 647 return 0; 648} 649 650int KernelProxy::fcntl(int fd, int request, va_list args) { 651 ScopedKernelHandle handle; 652 Error error = AcquireHandle(fd, &handle); 653 if (error) { 654 errno = error; 655 return -1; 656 } 657 658 int rtn = 0; 659 error = handle->VFcntl(request, &rtn, args); 660 if (error) { 661 errno = error; 662 return -1; 663 } 664 665 return rtn; 666} 667 668int KernelProxy::access(const char* path, int amode) { 669 ScopedMount mnt; 670 Path rel; 671 672 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 673 if (error) { 674 errno = error; 675 return -1; 676 } 677 678 error = mnt->Access(rel, amode); 679 if (error) { 680 errno = error; 681 return -1; 682 } 683 return 0; 684} 685 686int KernelProxy::readlink(const char *path, char *buf, size_t count) { 687 errno = EINVAL; 688 return -1; 689} 690 691int KernelProxy::utimes(const char *filename, const struct timeval times[2]) { 692 errno = EINVAL; 693 return -1; 694} 695 696// TODO(noelallen): Needs implementation. 697int KernelProxy::link(const char* oldpath, const char* newpath) { 698 errno = EINVAL; 699 return -1; 700} 701 702int KernelProxy::symlink(const char* oldpath, const char* newpath) { 703 errno = EINVAL; 704 return -1; 705} 706 707void* KernelProxy::mmap(void* addr, 708 size_t length, 709 int prot, 710 int flags, 711 int fd, 712 size_t offset) { 713 // We shouldn't be getting anonymous mmaps here. 714 assert((flags & MAP_ANONYMOUS) == 0); 715 assert(fd != -1); 716 717 ScopedKernelHandle handle; 718 Error error = AcquireHandle(fd, &handle); 719 if (error) { 720 errno = error; 721 return MAP_FAILED; 722 } 723 724 void* new_addr; 725 error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 726 if (error) { 727 errno = error; 728 return MAP_FAILED; 729 } 730 731 return new_addr; 732} 733 734int KernelProxy::munmap(void* addr, size_t length) { 735 // NOTE: The comment below is from a previous discarded implementation that 736 // tracks mmap'd regions. For simplicity, we no longer do this; because we 737 // "snapshot" the contents of the file in mmap(), and don't support 738 // write-back or updating the mapped region when the file is written, holding 739 // on to the KernelHandle is pointless. 740 // 741 // If we ever do, these threading issues should be considered. 742 743 // 744 // WARNING: this function may be called by free(). 745 // 746 // There is a potential deadlock scenario: 747 // Thread 1: open() -> takes lock1 -> free() -> takes lock2 748 // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 749 // 750 // Note that open() above could be any function that takes a lock that is 751 // shared with munmap (this includes munmap!) 752 // 753 // To prevent this, we avoid taking locks in munmap() that are used by other 754 // nacl_io functions that may call free. Specifically, we only take the 755 // mmap_lock, which is only shared with mmap() above. There is still a 756 // possibility of deadlock if mmap() or munmap() calls free(), so this is not 757 // allowed. 758 // 759 // Unfortunately, munmap still needs to acquire other locks; see the call to 760 // ReleaseHandle below which takes the process lock. This is safe as long as 761 // this is never executed from free() -- we can be reasonably sure this is 762 // true, because malloc only makes anonymous mmap() requests, and should only 763 // be munmapping those allocations. We never add to mmap_info_list_ for 764 // anonymous maps, so the unmap_list should always be empty when called from 765 // free(). 766 return 0; 767} 768 769int KernelProxy::tcflush(int fd, int queue_selector) { 770 ScopedKernelHandle handle; 771 Error error = AcquireHandle(fd, &handle); 772 if (error) { 773 errno = error; 774 return -1; 775 } 776 777 error = handle->node()->Tcflush(queue_selector); 778 if (error) { 779 errno = error; 780 return -1; 781 } 782 783 return 0; 784} 785 786int KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 787 ScopedKernelHandle handle; 788 Error error = AcquireHandle(fd, &handle); 789 if (error) { 790 errno = error; 791 return -1; 792 } 793 794 error = handle->node()->Tcgetattr(termios_p); 795 if (error) { 796 errno = error; 797 return -1; 798 } 799 800 return 0; 801} 802 803int KernelProxy::tcsetattr(int fd, int optional_actions, 804 const struct termios *termios_p) { 805 ScopedKernelHandle handle; 806 Error error = AcquireHandle(fd, &handle); 807 if (error) { 808 errno = error; 809 return -1; 810 } 811 812 error = handle->node()->Tcsetattr(optional_actions, termios_p); 813 if (error) { 814 errno = error; 815 return -1; 816 } 817 818 return 0; 819} 820 821int KernelProxy::kill(pid_t pid, int sig) { 822 // Currently we don't even pretend that other processes exist 823 // so we can only send a signal to outselves. For kill(2) 824 // pid 0 means the current process group and -1 means all the 825 // processes we have permission to send signals to. 826 if (pid != getpid() && pid != -1 && pid != 0) { 827 errno = ESRCH; 828 return -1; 829 } 830 831 // Raise an event so that select/poll get interrupted. 832 AUTO_LOCK(signal_emitter_->GetLock()) 833 signal_emitter_->RaiseEvents_Locked(POLLERR); 834 switch (sig) { 835 case SIGWINCH: 836 if (sigwinch_handler_ != SIG_IGN) 837 sigwinch_handler_(SIGWINCH); 838 break; 839 840 case SIGUSR1: 841 case SIGUSR2: 842 break; 843 844 default: 845 errno = EINVAL; 846 return -1; 847 } 848 return 0; 849} 850 851sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { 852 switch (signum) { 853 // Handled signals. 854 case SIGWINCH: { 855 sighandler_t old_value = sigwinch_handler_; 856 if (handler == SIG_DFL) 857 handler = SIG_IGN; 858 sigwinch_handler_ = handler; 859 return old_value; 860 } 861 862 // Known signals 863 case SIGHUP: 864 case SIGINT: 865 case SIGKILL: 866 case SIGPIPE: 867 case SIGPOLL: 868 case SIGPROF: 869 case SIGTERM: 870 case SIGCHLD: 871 case SIGURG: 872 case SIGFPE: 873 case SIGILL: 874 case SIGQUIT: 875 case SIGSEGV: 876 case SIGTRAP: 877 if (handler == SIG_DFL) 878 return SIG_DFL; 879 break; 880 } 881 882 errno = EINVAL; 883 return SIG_ERR; 884} 885 886#ifdef PROVIDES_SOCKET_API 887 888int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 889 fd_set* exceptfds, struct timeval* timeout) { 890 fd_set ignore; 891 std::vector<pollfd> pollfds; 892 893 // Simplify logic, by using an IGNORE set for any undefined set 894 FD_ZERO(&ignore); 895 if (NULL == readfds) 896 readfds = &ignore; 897 if (NULL == writefds) 898 writefds = &ignore; 899 if (NULL == exceptfds) 900 exceptfds = &ignore; 901 902 for (int fd = 0; fd < nfds; fd++) { 903 int events = 0; 904 if (FD_ISSET(fd, readfds)) 905 events |= POLLIN; 906 907 if (FD_ISSET(fd, writefds)) 908 events |= POLLOUT; 909 910 if (FD_ISSET(fd, exceptfds)) 911 events |= POLLERR | POLLHUP; 912 913 if (events) { 914 pollfd info; 915 info.fd = fd; 916 info.events = events; 917 pollfds.push_back(info); 918 } 919 } 920 921 FD_ZERO(readfds); 922 FD_ZERO(writefds); 923 FD_ZERO(exceptfds); 924 925 // NULL timeout signals wait forever. 926 int ms_timeout = -1; 927 if (timeout != NULL) { 928 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 929 930 // If the timeout is invalid or too long (larger than signed 32 bit). 931 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 932 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || 933 (ms < 0) || (ms >= INT_MAX)) { 934 errno = EINVAL; 935 return -1; 936 } 937 938 ms_timeout = static_cast<int>(ms); 939 } 940 941 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 942 if (result == -1) 943 return -1; 944 945 int event_cnt = 0; 946 for (size_t index = 0; index < pollfds.size(); index++) { 947 pollfd* info = &pollfds[index]; 948 if (info->revents & POLLIN) { 949 FD_SET(info->fd, readfds); 950 event_cnt++; 951 } 952 if (info->revents & POLLOUT) { 953 FD_SET(info->fd, writefds); 954 event_cnt++; 955 } 956 if (info->revents & (POLLHUP | POLLERR)) { 957 FD_SET(info->fd, exceptfds); 958 event_cnt++; 959 } 960 } 961 962 return event_cnt; 963} 964 965struct PollInfo { 966 PollInfo() : index(-1) {}; 967 968 std::vector<struct pollfd*> fds; 969 int index; 970}; 971 972typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 973 974int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 975 EventPollMap_t event_map; 976 977 std::vector<EventRequest> requests; 978 size_t event_cnt = 0; 979 980 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 981 ScopedKernelHandle handle; 982 struct pollfd* fd_info = &fds[index]; 983 Error err = AcquireHandle(fd_info->fd, &handle); 984 985 fd_info->revents = 0; 986 987 // If the node isn't open, or somehow invalid, mark it so. 988 if (err != 0) { 989 fd_info->revents = POLLNVAL; 990 event_cnt++; 991 continue; 992 } 993 994 // If it's already signaled, then just capture the event 995 ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 996 int events = POLLIN | POLLOUT; 997 if (emitter) 998 events = emitter->GetEventStatus(); 999 1000 if (events & fd_info->events) { 1001 fd_info->revents = events & fd_info->events; 1002 event_cnt++; 1003 continue; 1004 } 1005 1006 if (NULL == emitter) { 1007 fd_info->revents = POLLNVAL; 1008 event_cnt++; 1009 continue; 1010 } 1011 1012 // Otherwise try to track it. 1013 PollInfo* info = &event_map[emitter.get()]; 1014 if (info->index == -1) { 1015 EventRequest request; 1016 request.emitter = emitter; 1017 request.filter = fd_info->events; 1018 request.events = 0; 1019 1020 info->index = requests.size(); 1021 requests.push_back(request); 1022 } 1023 info->fds.push_back(fd_info); 1024 requests[info->index].filter |= fd_info->events; 1025 } 1026 1027 // If nothing is signaled, then we must wait on the event map 1028 if (0 == event_cnt) { 1029 EventListenerPoll wait; 1030 Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 1031 if ((err != 0) && (err != ETIMEDOUT)) { 1032 errno = err; 1033 return -1; 1034 } 1035 1036 for (size_t rindex = 0; rindex < requests.size(); rindex++) { 1037 EventRequest* request = &requests[rindex]; 1038 if (request->events) { 1039 PollInfo* poll_info = &event_map[request->emitter.get()]; 1040 for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 1041 struct pollfd* fd_info = poll_info->fds[findex]; 1042 uint32_t events = fd_info->events & request->events; 1043 if (events) { 1044 fd_info->revents = events; 1045 event_cnt++; 1046 } 1047 } 1048 } 1049 } 1050 } 1051 1052 return event_cnt; 1053} 1054 1055 1056// Socket Functions 1057int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1058 if (NULL == addr || NULL == len) { 1059 errno = EFAULT; 1060 return -1; 1061 } 1062 1063 ScopedKernelHandle handle; 1064 Error error = AcquireHandle(fd, &handle); 1065 if (error) { 1066 errno = error; 1067 return -1; 1068 } 1069 1070 PP_Resource new_sock = 0; 1071 error = handle->Accept(&new_sock, addr, len); 1072 if (error != 0) { 1073 errno = error; 1074 return -1; 1075 } 1076 1077 MountNodeSocket* sock = new MountNodeTCP(stream_mount_.get(), new_sock); 1078 1079 // The MountNodeSocket now holds a reference to the new socket 1080 // so we release ours. 1081 ppapi_->ReleaseResource(new_sock); 1082 error = sock->Init(S_IREAD | S_IWRITE); 1083 if (error != 0) { 1084 errno = error; 1085 return -1; 1086 } 1087 1088 ScopedMountNode node(sock); 1089 ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node)); 1090 return AllocateFD(new_handle); 1091} 1092 1093int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1094 if (NULL == addr) { 1095 errno = EFAULT; 1096 return -1; 1097 } 1098 1099 ScopedKernelHandle handle; 1100 if (AcquireSocketHandle(fd, &handle) == -1) 1101 return -1; 1102 1103 Error err = handle->socket_node()->Bind(addr, len); 1104 if (err != 0) { 1105 errno = err; 1106 return -1; 1107 } 1108 1109 return 0; 1110} 1111 1112int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1113 if (NULL == addr) { 1114 errno = EFAULT; 1115 return -1; 1116 } 1117 1118 ScopedKernelHandle handle; 1119 Error error = AcquireHandle(fd, &handle); 1120 if (error) { 1121 errno = error; 1122 return -1; 1123 } 1124 1125 error = handle->Connect(addr, len); 1126 if (error != 0) { 1127 errno = error; 1128 return -1; 1129 } 1130 1131 return 0; 1132} 1133 1134struct hostent* KernelProxy::gethostbyname(const char* name) { 1135 return host_resolver_.gethostbyname(name); 1136} 1137 1138int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1139 if (NULL == addr || NULL == len) { 1140 errno = EFAULT; 1141 return -1; 1142 } 1143 1144 ScopedKernelHandle handle; 1145 if (AcquireSocketHandle(fd, &handle) == -1) 1146 return -1; 1147 1148 Error err = handle->socket_node()->GetPeerName(addr, len); 1149 if (err != 0) { 1150 errno = err; 1151 return -1; 1152 } 1153 1154 return 0; 1155} 1156 1157int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1158 if (NULL == addr || NULL == len) { 1159 errno = EFAULT; 1160 return -1; 1161 } 1162 1163 ScopedKernelHandle handle; 1164 if (AcquireSocketHandle(fd, &handle) == -1) 1165 return -1; 1166 1167 Error err = handle->socket_node()->GetSockName(addr, len); 1168 if (err != 0) { 1169 errno = err; 1170 return -1; 1171 } 1172 1173 return 0; 1174} 1175 1176int KernelProxy::getsockopt(int fd, 1177 int lvl, 1178 int optname, 1179 void* optval, 1180 socklen_t* len) { 1181 if (NULL == optval || NULL == len) { 1182 errno = EFAULT; 1183 return -1; 1184 } 1185 1186 ScopedKernelHandle handle; 1187 if (AcquireSocketHandle(fd, &handle) == -1) 1188 return -1; 1189 1190 Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len); 1191 if (err != 0) { 1192 errno = err; 1193 return -1; 1194 } 1195 1196 return 0; 1197} 1198 1199int KernelProxy::listen(int fd, int backlog) { 1200 ScopedKernelHandle handle; 1201 if (AcquireSocketHandle(fd, &handle) == -1) 1202 return -1; 1203 1204 Error err = handle->socket_node()->Listen(backlog); 1205 if (err != 0) { 1206 errno = err; 1207 return -1; 1208 } 1209 1210 return 0; 1211} 1212 1213ssize_t KernelProxy::recv(int fd, 1214 void* buf, 1215 size_t len, 1216 int flags) { 1217 if (NULL == buf) { 1218 errno = EFAULT; 1219 return -1; 1220 } 1221 1222 ScopedKernelHandle handle; 1223 Error error = AcquireHandle(fd, &handle); 1224 if (error) { 1225 errno = error; 1226 return -1; 1227 } 1228 1229 int out_len = 0; 1230 error = handle->Recv(buf, len, flags, &out_len); 1231 if (error != 0) { 1232 errno = error; 1233 return -1; 1234 } 1235 1236 return static_cast<ssize_t>(out_len); 1237} 1238 1239ssize_t KernelProxy::recvfrom(int fd, 1240 void* buf, 1241 size_t len, 1242 int flags, 1243 struct sockaddr* addr, 1244 socklen_t* addrlen) { 1245 // According to the manpage, recvfrom with a null addr is identical to recv. 1246 if (NULL == addr) { 1247 return recv(fd, buf, len, flags); 1248 } 1249 1250 if (NULL == buf || NULL == addrlen) { 1251 errno = EFAULT; 1252 return -1; 1253 } 1254 1255 ScopedKernelHandle handle; 1256 Error error = AcquireHandle(fd, &handle); 1257 if (error) { 1258 errno = error; 1259 return -1; 1260 } 1261 1262 int out_len = 0; 1263 error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); 1264 if (error != 0) { 1265 errno = error; 1266 return -1; 1267 } 1268 1269 return static_cast<ssize_t>(out_len); 1270} 1271 1272ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1273 if (NULL == msg ) { 1274 errno = EFAULT; 1275 return -1; 1276 } 1277 1278 ScopedKernelHandle handle; 1279 if (AcquireSocketHandle(fd, &handle) == -1) 1280 return -1; 1281 1282 errno = EOPNOTSUPP; 1283 return -1; 1284} 1285 1286ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1287 if (NULL == buf) { 1288 errno = EFAULT; 1289 return -1; 1290 } 1291 1292 ScopedKernelHandle handle; 1293 Error error = AcquireHandle(fd, &handle); 1294 if (error) { 1295 errno = error; 1296 return -1; 1297 } 1298 1299 int out_len = 0; 1300 error = handle->Send(buf, len, flags, &out_len); 1301 if (error != 0) { 1302 errno = error; 1303 return -1; 1304 } 1305 1306 return static_cast<ssize_t>(out_len); 1307} 1308 1309ssize_t KernelProxy::sendto(int fd, 1310 const void* buf, 1311 size_t len, 1312 int flags, 1313 const struct sockaddr* addr, 1314 socklen_t addrlen) { 1315 // According to the manpage, sendto with a null addr is identical to send. 1316 if (NULL == addr) { 1317 return send(fd, buf, len, flags); 1318 } 1319 1320 if (NULL == buf) { 1321 errno = EFAULT; 1322 return -1; 1323 } 1324 1325 ScopedKernelHandle handle; 1326 Error error = AcquireHandle(fd, &handle); 1327 if (error) { 1328 errno = error; 1329 return -1; 1330 } 1331 1332 int out_len = 0; 1333 error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len); 1334 if (error != 0) { 1335 errno = error; 1336 return -1; 1337 } 1338 1339 return static_cast<ssize_t>(out_len); 1340} 1341 1342ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1343 if (NULL == msg) { 1344 errno = EFAULT; 1345 return -1; 1346 } 1347 1348 ScopedKernelHandle handle; 1349 if (AcquireSocketHandle(fd, &handle) == -1) 1350 return -1; 1351 1352 errno = EOPNOTSUPP; 1353 return -1; 1354} 1355 1356int KernelProxy::setsockopt(int fd, 1357 int lvl, 1358 int optname, 1359 const void* optval, 1360 socklen_t len) { 1361 if (NULL == optval) { 1362 errno = EFAULT; 1363 return -1; 1364 } 1365 1366 ScopedKernelHandle handle; 1367 if (AcquireSocketHandle(fd, &handle) == -1) 1368 return -1; 1369 1370 Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len); 1371 if (err != 0) { 1372 errno = err; 1373 return -1; 1374 } 1375 1376 return 0; 1377} 1378 1379int KernelProxy::shutdown(int fd, int how) { 1380 ScopedKernelHandle handle; 1381 if (AcquireSocketHandle(fd, &handle) == -1) 1382 return -1; 1383 1384 Error err = handle->socket_node()->Shutdown(how); 1385 if (err != 0) { 1386 errno = err; 1387 return -1; 1388 } 1389 1390 return 0; 1391} 1392 1393int KernelProxy::socket(int domain, int type, int protocol) { 1394 if (AF_INET != domain && AF_INET6 != domain) { 1395 errno = EAFNOSUPPORT; 1396 return -1; 1397 } 1398 1399 MountNodeSocket* sock = NULL; 1400 switch (type) { 1401 case SOCK_DGRAM: 1402 sock = new MountNodeUDP(stream_mount_.get()); 1403 break; 1404 1405 case SOCK_STREAM: 1406 sock = new MountNodeTCP(stream_mount_.get()); 1407 break; 1408 1409 default: 1410 errno = EPROTONOSUPPORT; 1411 return -1; 1412 } 1413 1414 ScopedMountNode node(sock); 1415 Error rtn = sock->Init(S_IREAD | S_IWRITE); 1416 if (rtn != 0) { 1417 errno = rtn; 1418 return -1; 1419 } 1420 1421 ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); 1422 return AllocateFD(handle); 1423} 1424 1425int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1426 if (NULL == sv) { 1427 errno = EFAULT; 1428 return -1; 1429 } 1430 1431 // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1432 // socket pairs. Thus, this function always fails. 1433 if (AF_UNIX != domain) { 1434 errno = EPROTONOSUPPORT; 1435 return -1; 1436 } 1437 1438 if (AF_INET != domain && AF_INET6 != domain) { 1439 errno = EAFNOSUPPORT; 1440 return -1; 1441 } 1442 1443 // We cannot reach this point. 1444 errno = ENOSYS; 1445 return -1; 1446} 1447 1448int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1449 Error error = AcquireHandle(fd, handle); 1450 1451 if (error) { 1452 errno = error; 1453 return -1; 1454 } 1455 1456 if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1457 errno = ENOTSOCK; 1458 return -1; 1459 } 1460 1461 return 0; 1462} 1463 1464#endif // PROVIDES_SOCKET_API 1465 1466} // namespace_nacl_io 1467