OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 #include "base/KernelProxy.h" | 6 #include "base/KernelProxy.h" |
7 #include <assert.h> | 7 #include <assert.h> |
8 #ifndef __GLIBC__ | 8 #ifndef __GLIBC__ |
9 #include <nacl-mounts/net/newlib_compat.h> | 9 #include <nacl-mounts/net/newlib_compat.h> |
10 #else | 10 #else |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 if (!(m_and_p.first)) { | 298 if (!(m_and_p.first)) { |
299 errno = ENOENT; | 299 errno = ENOENT; |
300 return -1; | 300 return -1; |
301 } | 301 } |
302 | 302 |
303 return OpenHandle(m_and_p.first, m_and_p.second, flags, mode); | 303 return OpenHandle(m_and_p.first, m_and_p.second, flags, mode); |
304 } | 304 } |
305 | 305 |
306 int KernelProxy::close(int fd) { | 306 int KernelProxy::close(int fd) { |
307 SimpleAutoLock lock(&kp_lock_); | 307 SimpleAutoLock lock(&kp_lock_); |
| 308 return Close(fd); |
| 309 } |
308 | 310 |
| 311 int KernelProxy::Close(int fd) { |
309 FileDescriptor* file = fds_.At(fd); | 312 FileDescriptor* file = fds_.At(fd); |
310 if (file == NULL) { | 313 if (file == NULL) { |
311 errno = EBADF; | 314 errno = EBADF; |
312 return -1; | 315 return -1; |
313 } | 316 } |
314 int h = file->handle; | 317 int h = file->handle; |
315 fds_.Free(fd); | 318 fds_.Free(fd); |
316 FileHandle* handle = open_files_.At(h); | 319 FileHandle* handle = open_files_.At(h); |
317 if (handle == NULL) { | 320 if (handle == NULL) { |
318 errno = EBADF; | 321 errno = EBADF; |
319 return -1; | 322 return -1; |
320 } | 323 } |
321 handle->use_count--; | 324 if (--handle->use_count <= 0) { |
322 ino_t node = handle->node; | 325 if (handle->mount) { |
323 if (handle->mount) { | 326 Mount* mount = handle->mount; |
324 Mount* mount = handle->mount; | 327 mount->Unref(handle->node); |
325 if (handle->use_count <= 0) { | 328 mount->Unref(); |
326 open_files_.Free(h); | 329 } else { |
327 mount->Unref(node); | 330 Socket* stream = handle->stream; |
| 331 socket_subsystem_->close(stream); |
328 } | 332 } |
329 mount->Unref(); | 333 open_files_.Free(h); |
330 } else { | |
331 Socket* stream = handle->stream; | |
332 socket_subsystem_->close(stream); | |
333 if (handle->use_count <= 0) { | |
334 open_files_.Free(h); | |
335 } | |
336 return 0; | |
337 } | 334 } |
338 return 0; | 335 return 0; |
339 } | 336 } |
340 | 337 |
341 ssize_t KernelProxy::read(int fd, void *buf, size_t count) { | 338 ssize_t KernelProxy::read(int fd, void *buf, size_t count) { |
342 FileHandle* handle; | 339 FileHandle* handle; |
343 // check if fd is valid and handle exists | 340 // check if fd is valid and handle exists |
344 if (!(handle = GetFileHandle(fd))) { | 341 if (!(handle = GetFileHandle(fd))) { |
345 errno = EBADF; | 342 errno = EBADF; |
346 return -1; | 343 return -1; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 int KernelProxy::isatty(int fd) { | 458 int KernelProxy::isatty(int fd) { |
462 FileHandle* handle; | 459 FileHandle* handle; |
463 | 460 |
464 if (!(handle = GetFileHandle(fd))) { | 461 if (!(handle = GetFileHandle(fd))) { |
465 errno = EBADF; | 462 errno = EBADF; |
466 return 0; | 463 return 0; |
467 } | 464 } |
468 return handle->mount->Isatty(handle->node); | 465 return handle->mount->Isatty(handle->node); |
469 } | 466 } |
470 | 467 |
471 int KernelProxy::dup2(int fd, int newfd) { | 468 int KernelProxy::dup2(int oldfd, int newfd) { |
472 SimpleAutoLock lock(&kp_lock_); | 469 SimpleAutoLock lock(&kp_lock_); |
473 int handle_slot = fds_.At(fd)->handle; | 470 |
474 if (fds_.AllocAt(fd) != fd) return -1; | 471 FileDescriptor* oldfile = fds_.At(oldfd); |
475 FileDescriptor* file = fds_.At(newfd); | 472 if (!oldfile) { |
476 file->handle = handle_slot; | 473 errno = EBADF; |
477 return 0; | 474 return -1; |
| 475 } |
| 476 |
| 477 // Do nothing if the file descriptors match. |
| 478 if (newfd == oldfd) |
| 479 return newfd; |
| 480 |
| 481 // close newfd if it exists. |
| 482 if (fds_.At(newfd)) |
| 483 Close(newfd); |
| 484 if (fds_.AllocAt(newfd) != newfd) assert(0); |
| 485 fds_.At(newfd)->handle = oldfile->handle; |
| 486 open_files_.At(oldfile->handle)->use_count++; |
| 487 return newfd; |
478 } | 488 } |
479 | 489 |
480 int KernelProxy::IsReady(int nfds, fd_set* fds, | 490 int KernelProxy::IsReady(int nfds, fd_set* fds, |
481 bool (Socket::*is_ready)(), bool apply) { | 491 bool (Socket::*is_ready)(), bool apply) { |
482 if (!fds) | 492 if (!fds) |
483 return 0; | 493 return 0; |
484 | 494 |
485 int nset = 0; | 495 int nset = 0; |
486 for (int i = 0; i < nfds; i++) { | 496 for (int i = 0; i < nfds; i++) { |
487 if (FD_ISSET(i, fds)) { | 497 if (FD_ISSET(i, fds)) { |
(...skipping 12 matching lines...) Expand all Loading... |
500 FD_CLR(i, fds); | 510 FD_CLR(i, fds); |
501 } | 511 } |
502 } | 512 } |
503 } | 513 } |
504 return nset; | 514 return nset; |
505 } | 515 } |
506 | 516 |
507 int KernelProxy::dup(int oldfd) { | 517 int KernelProxy::dup(int oldfd) { |
508 SimpleAutoLock lock(&kp_lock_); | 518 SimpleAutoLock lock(&kp_lock_); |
509 | 519 |
510 FileHandle* fh = GetFileHandle(oldfd); | 520 FileDescriptor* oldfile = fds_.At(oldfd); |
511 if (!fh) { | 521 if (!oldfile) { |
512 errno = EBADF; | 522 errno = EBADF; |
513 return -1; | 523 return -1; |
514 } | 524 } |
515 if (fh->mount == NULL) { | 525 |
516 Socket* stream = GetFileHandle(oldfd) > 0 | |
517 ? GetFileHandle(oldfd)->stream : NULL; | |
518 if (!stream) | |
519 return EBADF; | |
520 SimpleAutoLock lock(&kp_lock_); | |
521 int handle_slot = fds_.At(oldfd)->handle; | |
522 int newfd = fds_.Alloc(); | |
523 FileDescriptor* file = fds_.At(newfd); | |
524 file->handle = handle_slot; | |
525 return newfd; | |
526 } | |
527 FileDescriptor* oldfile = fds_.At(oldfd); | |
528 if (oldfile == NULL) { | |
529 errno = EBADF; | |
530 return -1; | |
531 } | |
532 int newfd = fds_.Alloc(); | 526 int newfd = fds_.Alloc(); |
533 FileDescriptor *newfile = fds_.At(newfd); | 527 fds_.At(newfd)->handle = oldfile->handle; |
534 int h = oldfile->handle; | 528 open_files_.At(oldfile->handle)->use_count++; |
535 newfile->handle = h; | |
536 FileHandle* handle = open_files_.At(h); | |
537 // init should be safe because we have the kernel proxy lock | |
538 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); | |
539 | |
540 if (handle == NULL) { | |
541 errno = EBADF; | |
542 return -1; | |
543 } | |
544 ++handle->use_count; | |
545 handle->mount->Ref(handle->node); | |
546 handle->mount->Ref(); | |
547 return newfd; | 529 return newfd; |
548 } | 530 } |
549 | 531 |
550 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { | 532 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { |
551 FileHandle* handle; | 533 FileHandle* handle; |
552 // check if fd is valid and handle exists | 534 // check if fd is valid and handle exists |
553 if (!(handle = GetFileHandle(fd))) { | 535 if (!(handle = GetFileHandle(fd))) { |
554 errno = EBADF; | 536 errno = EBADF; |
555 return -1; | 537 return -1; |
556 } | 538 } |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 return EBADF; | 1014 return EBADF; |
1033 return socket_subsystem_->shutdown(fh->stream, how); | 1015 return socket_subsystem_->shutdown(fh->stream, how); |
1034 } | 1016 } |
1035 | 1017 |
1036 int KernelProxy::socketpair(int domain, int type, int protocol, int sv[2]) { | 1018 int KernelProxy::socketpair(int domain, int type, int protocol, int sv[2]) { |
1037 errno = ENOSYS; | 1019 errno = ENOSYS; |
1038 fprintf(stderr, "socketpair has not been implemented!\n"); | 1020 fprintf(stderr, "socketpair has not been implemented!\n"); |
1039 return -1; | 1021 return -1; |
1040 } | 1022 } |
1041 | 1023 |
OLD | NEW |