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