| 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 17 matching lines...) Expand all Loading... |
| 28 #define MAXPATHLEN 256 | 28 #define MAXPATHLEN 256 |
| 29 #endif | 29 #endif |
| 30 | 30 |
| 31 static const int64_t kMicrosecondsPerSecond = 1000 * 1000; | 31 static const int64_t kMicrosecondsPerSecond = 1000 * 1000; |
| 32 static const int64_t kNanosecondsPerMicrosecond = 1000; | 32 static const int64_t kNanosecondsPerMicrosecond = 1000; |
| 33 | 33 |
| 34 KernelProxy::KernelProxy() { | 34 KernelProxy::KernelProxy() { |
| 35 if (pthread_mutex_init(&kp_lock_, NULL)) assert(0); | 35 if (pthread_mutex_init(&kp_lock_, NULL)) assert(0); |
| 36 cwd_ = Path("/"); | 36 cwd_ = Path("/"); |
| 37 mm_.Init(); | 37 mm_.Init(); |
| 38 | |
| 39 // Setup file descriptors 0, 1, and 2 for STDIN, STDOUT, and STDERR | 38 // Setup file descriptors 0, 1, and 2 for STDIN, STDOUT, and STDERR |
| 40 int ret = mkdir("/dev", 0777); | 39 int ret = mkdir("/dev", 0777); |
| 41 assert(ret == 0); | 40 assert(ret == 0); |
| 42 DevMount* dev_mount = new DevMount(); | 41 DevMount* dev_mount = new DevMount(); |
| 43 ret = mm_.AddMount(dev_mount, "/dev"); | 42 ret = mm_.AddMount(dev_mount, "/dev"); |
| 44 assert(ret == 0); | 43 assert(ret == 0); |
| 45 ret = mkdir("/dev/fd", 0777); | 44 ret = mkdir("/dev/fd", 0777); |
| 46 assert(ret == 0); | 45 assert(ret == 0); |
| 47 ConsoleMount *console_mount = new ConsoleMount(); | 46 ConsoleMount *console_mount = new ConsoleMount(); |
| 48 ret = mm_.AddMount(console_mount, "/dev/fd"); | 47 ret = mm_.AddMount(console_mount, "/dev/fd"); |
| 49 assert(ret == 0); | 48 assert(ret == 0); |
| 50 int fd = open("/dev/fd/0", O_CREAT | O_RDWR, 0); | 49 int fd = open("/dev/fd/0", O_CREAT | O_RDWR, 0); |
| 51 assert(fd == 0); | 50 assert(fd == 0); |
| 52 fd = open("/dev/fd/1", O_CREAT | O_RDWR, 0); | 51 fd = open("/dev/fd/1", O_CREAT | O_RDWR, 0); |
| 53 assert(fd == 1); | 52 assert(fd == 1); |
| 54 fd = open("/dev/fd/2", O_CREAT | O_RDWR, 0); | 53 fd = open("/dev/fd/2", O_CREAT | O_RDWR, 0); |
| 55 assert(fd == 2); | 54 assert(fd == 2); |
| 55 socket_subsystem_ = NULL; |
| 56 } | 56 } |
| 57 | 57 |
| 58 void KernelProxy::SetSocketSubSystem(BaseSocketSubSystem* bss) { | 58 void KernelProxy::SetSocketSubSystem(BaseSocketSubSystem* bss) { |
| 59 socket_subsystem_ = bss; | 59 socket_subsystem_ = bss; |
| 60 } | 60 } |
| 61 | 61 |
| 62 void KernelProxy::RemoveSocket(int fd) { | 62 void KernelProxy::RemoveSocket(int fd) { |
| 63 this->close(fd); | 63 this->close(fd); |
| 64 } | 64 } |
| 65 | 65 |
| 66 int KernelProxy::AddSocket(Socket* stream) { | 66 int KernelProxy::AddSocket(Socket* stream) { |
| 67 SimpleAutoLock lock(&kp_lock_); | 67 SimpleAutoLock lock(&kp_lock_); |
| 68 | 68 |
| 69 // Setup file handle. | 69 // Setup file handle. |
| 70 int handle_slot = open_files_.Alloc(); | 70 int handle_slot = open_files_.Alloc(); |
| 71 int fd = fds_.Alloc(); | 71 int fd = fds_.Alloc(); |
| 72 FileDescriptor* file = fds_.At(fd); | 72 FileDescriptor* file = fds_.At(fd); |
| 73 file->handle = handle_slot; | 73 file->handle = handle_slot; |
| 74 FileHandle* handle = open_files_.At(handle_slot); | 74 FileHandle* handle = open_files_.At(handle_slot); |
| 75 | 75 |
| 76 // init should be safe because we have the kernel proxy lock | 76 // init should be safe because we have the kernel proxy lock |
| 77 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); | 77 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); |
| 78 | 78 |
| 79 handle->mount = reinterpret_cast<Mount*>(NULL); | 79 handle->mount = reinterpret_cast<Mount*>(NULL); |
| 80 handle->stream = reinterpret_cast<Socket*>(NULL); | 80 handle->stream = stream; |
| 81 handle->use_count = 1; | 81 handle->use_count = 1; |
| 82 | 82 |
| 83 return fd; | 83 return fd; |
| 84 } | 84 } |
| 85 | 85 |
| 86 KernelProxy *KernelProxy::KPInstance() { | 86 KernelProxy *KernelProxy::KPInstance() { |
| 87 pthread_once(&kp_once_, Instantiate); | 87 pthread_once(&kp_once_, Instantiate); |
| 88 return kp_instance_; | 88 return kp_instance_; |
| 89 } | 89 } |
| 90 | 90 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 | 421 |
| 422 int KernelProxy::kill(pid_t pid, int sig) { | 422 int KernelProxy::kill(pid_t pid, int sig) { |
| 423 errno = ENOSYS; | 423 errno = ENOSYS; |
| 424 fprintf(stderr, "kill has not been implemented!\n"); | 424 fprintf(stderr, "kill has not been implemented!\n"); |
| 425 assert(0); | 425 assert(0); |
| 426 return -1; | 426 return -1; |
| 427 } | 427 } |
| 428 | 428 |
| 429 int KernelProxy::getdents(int fd, void *buf, unsigned int count) { | 429 int KernelProxy::getdents(int fd, void *buf, unsigned int count) { |
| 430 FileHandle* handle; | 430 FileHandle* handle; |
| 431 | |
| 432 // check if fd is valid and handle exists | 431 // check if fd is valid and handle exists |
| 433 if (!(handle = GetFileHandle(fd))) { | 432 if (!(handle = GetFileHandle(fd))) { |
| 434 errno = EBADF; | 433 errno = EBADF; |
| 435 return -1; | 434 return -1; |
| 436 } | 435 } |
| 437 | 436 |
| 438 SimpleAutoLock(&handle->lock); | 437 SimpleAutoLock(&handle->lock); |
| 439 | 438 |
| 440 int ret = handle->mount->Getdents(handle->node, handle->offset, | 439 int ret = handle->mount->Getdents(handle->node, handle->offset, |
| 441 (struct dirent*)buf, count); | 440 (struct dirent*)buf, count); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 } | 478 } |
| 480 | 479 |
| 481 int KernelProxy::IsReady(int nfds, fd_set* fds, | 480 int KernelProxy::IsReady(int nfds, fd_set* fds, |
| 482 bool (Socket::*is_ready)(), bool apply) { | 481 bool (Socket::*is_ready)(), bool apply) { |
| 483 if (!fds) | 482 if (!fds) |
| 484 return 0; | 483 return 0; |
| 485 | 484 |
| 486 int nset = 0; | 485 int nset = 0; |
| 487 for (int i = 0; i < nfds; i++) { | 486 for (int i = 0; i < nfds; i++) { |
| 488 if (FD_ISSET(i, fds)) { | 487 if (FD_ISSET(i, fds)) { |
| 489 Socket* stream = GetFileHandle(i) > 0 ? | 488 FileHandle* h = GetFileHandle(i); |
| 490 GetFileHandle(i)->stream : NULL; | 489 if (h == NULL) { |
| 491 if (!stream) | |
| 492 return -1; | 490 return -1; |
| 493 if ((stream->*is_ready)()) { | 491 } |
| 492 Socket* stream = h->stream; |
| 493 if (stream && (stream->*is_ready)()) { |
| 494 if (!apply) | 494 if (!apply) |
| 495 return 1; | 495 return 1; |
| 496 else | 496 else |
| 497 nset++; | 497 nset++; |
| 498 } else { | 498 } else { |
| 499 if (apply) | 499 if (apply) |
| 500 FD_CLR(i, fds); | 500 FD_CLR(i, fds); |
| 501 } | 501 } |
| 502 } | 502 } |
| 503 } | 503 } |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 handle->mount = NULL; | 843 handle->mount = NULL; |
| 844 handle->stream = NULL; | 844 handle->stream = NULL; |
| 845 handle->use_count = 1; | 845 handle->use_count = 1; |
| 846 return fd; | 846 return fd; |
| 847 } | 847 } |
| 848 | 848 |
| 849 int KernelProxy::accept(int sockfd, struct sockaddr *addr, | 849 int KernelProxy::accept(int sockfd, struct sockaddr *addr, |
| 850 socklen_t* addrlen) { | 850 socklen_t* addrlen) { |
| 851 if (GetFileHandle(sockfd) == 0) | 851 if (GetFileHandle(sockfd) == 0) |
| 852 return EBADF; | 852 return EBADF; |
| 853 Socket* ret = socket_subsystem_->accept(GetFileHandle(sockfd)->stream, | 853 Socket* ret = socket_subsystem_->accept( |
| 854 GetFileHandle(sockfd)->stream, |
| 854 addr, addrlen); | 855 addr, addrlen); |
| 855 if (ret) | 856 if (ret) { |
| 857 ret->GetAddress(addr); |
| 856 return AddSocket(ret); | 858 return AddSocket(ret); |
| 857 else | 859 } else { |
| 858 return -1; | 860 return -1; |
| 861 } |
| 859 } | 862 } |
| 860 | 863 |
| 861 int KernelProxy::bind(int sockfd, const struct sockaddr *addr, | 864 int KernelProxy::bind(int sockfd, const struct sockaddr *addr, |
| 862 socklen_t addrlen) { | 865 socklen_t addrlen) { |
| 863 if (GetFileHandle(sockfd) == 0) | 866 if (GetFileHandle(sockfd) == 0) |
| 864 return EBADF; | 867 return EBADF; |
| 865 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr; | 868 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr; |
| 866 return socket_subsystem_->bind(&(GetFileHandle(sockfd)->stream), | 869 return socket_subsystem_->bind(&(GetFileHandle(sockfd)->stream), |
| 867 addr, addrlen); | 870 addr, addrlen); |
| 868 } | 871 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 | 962 |
| 960 while (!(IsReady(nfds, readfds, &Socket::is_read_ready, false) || | 963 while (!(IsReady(nfds, readfds, &Socket::is_read_ready, false) || |
| 961 IsReady(nfds, writefds, &Socket::is_write_ready, false) || | 964 IsReady(nfds, writefds, &Socket::is_write_ready, false) || |
| 962 IsReady(nfds, exceptfds, &Socket::is_exception, false))) { | 965 IsReady(nfds, exceptfds, &Socket::is_exception, false))) { |
| 963 SimpleAutoLock lock(select_mutex().get()); | 966 SimpleAutoLock lock(select_mutex().get()); |
| 964 if (timeout) { | 967 if (timeout) { |
| 965 if (!timeout->tv_sec && !timeout->tv_usec) | 968 if (!timeout->tv_sec && !timeout->tv_usec) |
| 966 break; | 969 break; |
| 967 | 970 |
| 968 if (select_cond().timedwait(select_mutex(), &ts_abs)) { | 971 if (select_cond().timedwait(select_mutex(), &ts_abs)) { |
| 969 if (errno == ETIMEDOUT) | 972 if (errno == ETIMEDOUT) { |
| 970 break; | 973 break; |
| 971 else | 974 } else { |
| 975 dbgprintf("select: timedwait error %d\n", errno); |
| 972 return -1; | 976 return -1; |
| 977 } |
| 973 } | 978 } |
| 974 } else { | 979 } else { |
| 975 select_cond().wait(select_mutex()); | 980 select_cond().wait(select_mutex()); |
| 976 } | 981 } |
| 977 } | 982 } |
| 978 | 983 |
| 979 int nread = IsReady(nfds, readfds, &Socket::is_read_ready, true); | 984 int nread = IsReady(nfds, readfds, &Socket::is_read_ready, true); |
| 980 int nwrite = IsReady(nfds, writefds, &Socket::is_write_ready, true); | 985 int nwrite = IsReady(nfds, writefds, &Socket::is_write_ready, true); |
| 981 int nexcpt = IsReady(nfds, exceptfds, &Socket::is_exception, true); | 986 int nexcpt = IsReady(nfds, exceptfds, &Socket::is_exception, true); |
| 982 if (nread < 0 || nwrite < 0 || nexcpt < 0) { | 987 if (nread < 0 || nwrite < 0 || nexcpt < 0) { |
| 983 errno = EBADF; | 988 errno = EBADF; |
| 989 dbgprintf("select: EBADF problem %d\n", errno); |
| 984 return -1; | 990 return -1; |
| 985 } | 991 } |
| 986 return nread + nwrite + nexcpt; | 992 return nread + nwrite + nexcpt; |
| 987 } | 993 } |
| 988 | 994 |
| 989 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds, | 995 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds, |
| 990 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) { | 996 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) { |
| 991 errno = ENOSYS; | 997 errno = ENOSYS; |
| 992 fprintf(stderr, "pselect has not been implemented!\n"); | 998 fprintf(stderr, "pselect has not been implemented!\n"); |
| 993 return -1; | 999 return -1; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1009 | 1015 |
| 1010 int KernelProxy::getsockopt(int sockfd, int level, int optname, void *optval, | 1016 int KernelProxy::getsockopt(int sockfd, int level, int optname, void *optval, |
| 1011 socklen_t* optlen) { | 1017 socklen_t* optlen) { |
| 1012 errno = ENOSYS; | 1018 errno = ENOSYS; |
| 1013 fprintf(stderr, "getsockopt has not been implemented!\n"); | 1019 fprintf(stderr, "getsockopt has not been implemented!\n"); |
| 1014 return -1; | 1020 return -1; |
| 1015 } | 1021 } |
| 1016 | 1022 |
| 1017 int KernelProxy::setsockopt(int sockfd, int level, int optname, | 1023 int KernelProxy::setsockopt(int sockfd, int level, int optname, |
| 1018 const void *optval, socklen_t optlen) { | 1024 const void *optval, socklen_t optlen) { |
| 1019 errno = ENOSYS; | 1025 return socket_subsystem_->setsockopt(GetFileHandle(sockfd)->stream, level, |
| 1020 fprintf(stderr, "setsockopt has not been implemented!\n"); | 1026 optname, optval, optlen); |
| 1021 return -1; | |
| 1022 } | 1027 } |
| 1023 | 1028 |
| 1024 int KernelProxy::shutdown(int sockfd, int how) { | 1029 int KernelProxy::shutdown(int sockfd, int how) { |
| 1025 FileHandle* fh = GetFileHandle(sockfd); | 1030 FileHandle* fh = GetFileHandle(sockfd); |
| 1026 if (fh == 0) | 1031 if (fh == 0) |
| 1027 return EBADF; | 1032 return EBADF; |
| 1028 return socket_subsystem_->shutdown(fh->stream, how); | 1033 return socket_subsystem_->shutdown(fh->stream, how); |
| 1029 } | 1034 } |
| 1030 | 1035 |
| 1031 int KernelProxy::socketpair(int domain, int type, int protocol, int sv[2]) { | 1036 int KernelProxy::socketpair(int domain, int type, int protocol, int sv[2]) { |
| 1032 errno = ENOSYS; | 1037 errno = ENOSYS; |
| 1033 fprintf(stderr, "socketpair has not been implemented!\n"); | 1038 fprintf(stderr, "socketpair has not been implemented!\n"); |
| 1034 return -1; | 1039 return -1; |
| 1035 } | 1040 } |
| 1036 | 1041 |
| OLD | NEW |