Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: libraries/nacl-mounts/base/KernelProxy.cc

Issue 10392070: Socket subsystem implementation (Closed) Base URL: http://naclports.googlecode.com/svn/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « libraries/nacl-mounts/base/KernelProxy.h ('k') | libraries/nacl-mounts/base/PthreadHelpers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <assert.h> 6 #include <assert.h>
7 #include <sys/time.h>
7 #include <list> 8 #include <list>
8 #include <utility> 9 #include <utility>
9 #include "../console/ConsoleMount.h" 10 #include "console/ConsoleMount.h"
Evgeniy Stepanov 2012/05/23 15:35:13 Why this one without ../, and the two below it wit
vissi 2012/05/25 11:08:50 Now without ..
10 #include "../dev/DevMount.h" 11 #include "../dev/DevMount.h"
12 #include "../net/SocketSubSystem.h"
11 #include "KernelProxy.h" 13 #include "KernelProxy.h"
12 #include "MountManager.h" 14 #include "MountManager.h"
15 #include "net/BaseSocketSubSystem.h"
16 #include <netinet/in.h>
17 #include "util/DebugPrint.h"
13 18
14 static pthread_once_t kp_once_ = PTHREAD_ONCE_INIT; 19 static pthread_once_t kp_once_ = PTHREAD_ONCE_INIT;
15 KernelProxy *KernelProxy::kp_instance_; 20 KernelProxy *KernelProxy::kp_instance_;
16 21
17 #ifndef MAXPATHLEN 22 #ifndef MAXPATHLEN
18 #define MAXPATHLEN 256 23 #define MAXPATHLEN 256
19 #endif 24 #endif
20 25
21 KernelProxy::KernelProxy() { 26 KernelProxy::KernelProxy() {
22 if (pthread_mutex_init(&kp_lock_, NULL)) assert(0); 27 if (pthread_mutex_init(&kp_lock_, NULL)) assert(0);
(...skipping 12 matching lines...) Expand all
35 ret = mm_.AddMount(console_mount, "/dev/fd"); 40 ret = mm_.AddMount(console_mount, "/dev/fd");
36 assert(ret == 0); 41 assert(ret == 0);
37 int fd = open("/dev/fd/0", O_CREAT | O_RDWR, 0); 42 int fd = open("/dev/fd/0", O_CREAT | O_RDWR, 0);
38 assert(fd == 0); 43 assert(fd == 0);
39 fd = open("/dev/fd/1", O_CREAT | O_RDWR, 0); 44 fd = open("/dev/fd/1", O_CREAT | O_RDWR, 0);
40 assert(fd == 1); 45 assert(fd == 1);
41 fd = open("/dev/fd/2", O_CREAT | O_RDWR, 0); 46 fd = open("/dev/fd/2", O_CREAT | O_RDWR, 0);
42 assert(fd == 2); 47 assert(fd == 2);
43 } 48 }
44 49
50 void KernelProxy::SetSS(BaseSocketSubSystem* bss) {
Evgeniy Stepanov 2012/05/23 15:35:13 A more descriptive setter name pls.
vissi 2012/05/25 11:08:50 Done.
51 ss = bss;
52 }
53
54 void KernelProxy::RemoveFileStream(int fd) {
55 this->close(fd);
56 }
57
58 int KernelProxy::AddFileStream(FileStream* stream) {
59 SimpleAutoLock lock(&kp_lock_);
60
61 // Setup file handle.
62 int handle_slot = open_files_.Alloc();
63 int fd = fds_.Alloc();
64 FileDescriptor* file = fds_.At(fd);
65 file->handle = handle_slot;
66 FileHandle* handle = open_files_.At(handle_slot);
67
68 // init should be safe because we have the kernel proxy lock
69 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
70
71 handle->mount = (Mount*) NULL;
72 handle->stream = (FileStream*) NULL;
73 handle->use_count = 1;
74
75 return fd;
76 }
77
45 KernelProxy *KernelProxy::KPInstance() { 78 KernelProxy *KernelProxy::KPInstance() {
46 pthread_once(&kp_once_, Instantiate); 79 pthread_once(&kp_once_, Instantiate);
47 return kp_instance_; 80 return kp_instance_;
48 } 81 }
49 82
50 void KernelProxy::Instantiate() { 83 void KernelProxy::Instantiate() {
51 assert(!kp_instance_); 84 assert(!kp_instance_);
52 kp_instance_ = new KernelProxy(); 85 kp_instance_ = new KernelProxy();
53 } 86 }
54 87
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 203 }
171 } 204 }
172 205
173 mount->Ref(st.st_ino); 206 mount->Ref(st.st_ino);
174 mount->Ref(); 207 mount->Ref();
175 // Setup file handle. 208 // Setup file handle.
176 int handle_slot = open_files_.Alloc(); 209 int handle_slot = open_files_.Alloc();
177 int fd = fds_.Alloc(); 210 int fd = fds_.Alloc();
178 FileDescriptor* file = fds_.At(fd); 211 FileDescriptor* file = fds_.At(fd);
179 file->handle = handle_slot; 212 file->handle = handle_slot;
180 FileHandle *handle = open_files_.At(handle_slot); 213 FileHandle* handle = open_files_.At(handle_slot);
181 214
182 // init should be safe because we have the kernel proxy lock 215 // init should be safe because we have the kernel proxy lock
183 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); 216 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
184 217
185 handle->mount = mount; 218 handle->mount = mount;
219 handle->stream = NULL;
186 handle->node = st.st_ino; 220 handle->node = st.st_ino;
187 handle->flags = flags; 221 handle->flags = flags;
188 handle->use_count = 1; 222 handle->use_count = 1;
189 223
190 if (flags & O_APPEND) { 224 if (flags & O_APPEND) {
191 handle->offset = st.st_size; 225 handle->offset = st.st_size;
192 } else { 226 } else {
193 handle->offset = 0; 227 handle->offset = 0;
194 } 228 }
195 229
196 return fd; 230 return fd;
197 } 231 }
198 232
233 ino_t KernelProxy::CreateSocket() {
234 SimpleAutoLock lock(&kp_lock_);
235 int handle_slot = open_files_.Alloc();
236 int fd = fds_.Alloc();
237 FileDescriptor* file = fds_.At(fd);
238 file->handle = handle_slot;
239 FileHandle *handle = open_files_.At(handle_slot);
240 handle->mount = NULL;
241 handle->stream = NULL;
242 handle->use_count = 1;
243 return fd;
244 }
245
246 struct hostent* KernelProxy::gethostbyname(const char* name) {
247 struct hostent *res = (struct hostent*) malloc(sizeof(struct hostent));
248 if (!res) return NULL;
249 res->h_addr_list = (char**) malloc(sizeof(char*) * 2);
250 if (!res->h_addr_list) return NULL;
251 res->h_addr_list[0] = (char*) malloc(sizeof(long int));
252 if (!res->h_addr_list[0]) return NULL;
253 *((long int*)res->h_addr_list[0]) = ss->gethostbyname(name);
254 res->h_addr_list[1] = NULL;
255 res->h_length = sizeof(long int);
256 return res;
257 }
258
199 int KernelProxy::open(const std::string& path, int flags, mode_t mode) { 259 int KernelProxy::open(const std::string& path, int flags, mode_t mode) {
200 if (path.empty()) { 260 if (path.empty()) {
201 errno = EINVAL; 261 errno = EINVAL;
202 return -1; 262 return -1;
203 } 263 }
204 264
205 Path p(path); 265 Path p(path);
206 if (path[0] != '/') { 266 if (path[0] != '/') {
207 p = Path(cwd_.FormulatePath() + "/" + path); 267 p = Path(cwd_.FormulatePath() + "/" + path);
208 } 268 }
(...skipping 19 matching lines...) Expand all
228 } 288 }
229 int h = file->handle; 289 int h = file->handle;
230 fds_.Free(fd); 290 fds_.Free(fd);
231 FileHandle *handle = open_files_.At(h); 291 FileHandle *handle = open_files_.At(h);
232 if (handle == NULL) { 292 if (handle == NULL) {
233 errno = EBADF; 293 errno = EBADF;
234 return -1; 294 return -1;
235 } 295 }
236 handle->use_count--; 296 handle->use_count--;
237 ino_t node = handle->node; 297 ino_t node = handle->node;
238 Mount *mount = handle->mount; 298 if (handle->mount) {
239 if (handle->use_count <= 0) { 299 Mount* mount = handle->mount;
240 open_files_.Free(h); 300 if (handle->use_count <= 0) {
241 mount->Unref(node); 301 open_files_.Free(h);
302 mount->Unref(node);
303 }
304 mount->Unref();
242 } 305 }
243 mount->Unref();
244 return 0; 306 return 0;
245 } 307 }
246 308
247 ssize_t KernelProxy::read(int fd, void *buf, size_t count) { 309 ssize_t KernelProxy::read(int fd, void *buf, size_t count) {
248 FileHandle *handle; 310 FileHandle *handle;
249 // check if fd is valid and handle exists 311 // check if fd is valid and handle exists
250 if (!(handle = GetFileHandle(fd))) { 312 if (!(handle = GetFileHandle(fd))) {
251 errno = EBADF; 313 errno = EBADF;
252 return -1; 314 return -1;
253 } 315 }
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 ((amode & X_OK) && !(mode & X_OK))) { 673 ((amode & X_OK) && !(mode & X_OK))) {
612 errno = EACCES; 674 errno = EACCES;
613 return -1; 675 return -1;
614 } 676 }
615 } 677 }
616 // By now we have checked access permissions for 678 // By now we have checked access permissions for
617 // each component of the path. 679 // each component of the path.
618 return 0; 680 return 0;
619 } 681 }
620 682
621 KernelProxy::FileHandle *KernelProxy::GetFileHandle(int fd) { 683 FileHandle* KernelProxy::GetFileHandle(int fd) {
622 SimpleAutoLock lock(&kp_lock_); 684 SimpleAutoLock lock(&kp_lock_);
623 FileDescriptor *file = fds_.At(fd); 685 FileDescriptor *file = fds_.At(fd);
624 if (!file) { 686 if (!file) {
625 return NULL; 687 return NULL;
626 } 688 }
627 return open_files_.At(file->handle); 689 return open_files_.At(file->handle);
628 } 690 }
629 691
630 int KernelProxy::mkdir(const std::string& path, mode_t mode) { 692 int KernelProxy::mkdir(const std::string& path, mode_t mode) {
631 if (path.empty()) { 693 if (path.empty()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 if (mm_.InMountRootPath(abs_path)) { 731 if (mm_.InMountRootPath(abs_path)) {
670 errno = EBUSY; 732 errno = EBUSY;
671 return -1; 733 return -1;
672 } 734 }
673 735
674 return mount->Rmdir(buf.st_ino); 736 return mount->Rmdir(buf.st_ino);
675 } 737 }
676 738
677 #ifdef __GLIBC__ 739 #ifdef __GLIBC__
678 int KernelProxy::socket(int domain, int type, int protocol) { 740 int KernelProxy::socket(int domain, int type, int protocol) {
679 errno = ENOSYS; 741 return ss->socket(domain, type, protocol);
680 fprintf(stderr, "socket has not been implemented!\n");
681 return -1;
682 } 742 }
683 743
684 int KernelProxy::accept(int sockfd, struct sockaddr *addr, 744 int KernelProxy::accept(int sockfd, struct sockaddr *addr,
685 socklen_t* addrlen) { 745 socklen_t* addrlen) {
686 errno = ENOSYS; 746 return ss->accept(GetFileHandle(sockfd), addr, addrlen);
687 fprintf(stderr, "accept has not been implemented!\n");
688 return -1;
689 } 747 }
690 748
691 int KernelProxy::bind(int sockfd, const struct sockaddr *addr, 749 int KernelProxy::bind(int sockfd, const struct sockaddr *addr,
692 socklen_t addrlen) { 750 socklen_t addrlen) {
693 errno = ENOSYS; 751 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
694 fprintf(stderr, "bind has not been implemented!\n"); 752 return ss->bind(GetFileHandle(sockfd), in_addr->sin_addr.s_addr,
695 return -1; 753 (unsigned short) ntohs(in_addr->sin_port));
696 } 754 }
697 755
698 int KernelProxy::listen(int sockfd, int backlog) { 756 int KernelProxy::listen(int sockfd, int backlog) {
699 errno = ENOSYS; 757 return ss->listen(GetFileHandle(sockfd), backlog);
700 fprintf(stderr, "listen has not been implemented!\n");
701 return -1;
702 } 758 }
703 759
704 int KernelProxy::connect(int sockfd, const struct sockaddr *addr, 760 int KernelProxy::connect(int sockfd, const struct sockaddr *addr,
705 socklen_t addrlen) { 761 socklen_t addrlen) {
706 errno = ENOSYS; 762 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
707 fprintf(stderr, "connect has not been implemented!\n"); 763 return ss->connect(GetFileHandle(sockfd), in_addr->sin_addr.s_addr,
708 return -1; 764 (unsigned short) ntohs(in_addr->sin_port));
709 } 765 }
710 766
711 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) { 767 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) {
712 errno = ENOSYS; 768 size_t nwr;
713 fprintf(stderr, "send has not been implemented!\n"); 769 ss->write(GetFileHandle(sockfd), (const char*)buf, len, &nwr);
714 return -1; 770 return nwr;
715 } 771 }
716 772
717 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) { 773 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) {
718 errno = ENOSYS; 774 errno = ENOSYS;
719 fprintf(stderr, "sendmsg has not been implemented!\n"); 775 fprintf(stderr, "sendmsg has not been implemented!\n");
720 return -1; 776 return -1;
721 } 777 }
722 778
723 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags, 779 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags,
724 const struct sockaddr *dest_addr, socklen_t addrlen) { 780 const struct sockaddr *dest_addr, socklen_t addrlen) {
725 errno = ENOSYS; 781 errno = ENOSYS;
726 fprintf(stderr, "sendto has not been implemented!\n"); 782 fprintf(stderr, "sendto has not been implemented!\n");
727 return -1; 783 return -1;
728 } 784 }
729 785
730 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) { 786 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) {
731 errno = ENOSYS; 787 size_t nread;
732 fprintf(stderr, "recv has not been implemented!\n"); 788 ss->read(GetFileHandle(sockfd), reinterpret_cast<char*>(buf), len, &nread);
733 return -1; 789 return nread;
734 } 790 }
735 791
736 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) { 792 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) {
737 errno = ENOSYS; 793 errno = ENOSYS;
738 fprintf(stderr, "recvmsg has not been implemented!\n"); 794 fprintf(stderr, "recvmsg has not been implemented!\n");
739 return -1; 795 return -1;
740 } 796 }
741 797
742 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags, 798 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags,
743 struct sockaddr *dest_addr, socklen_t* addrlen) { 799 struct sockaddr *dest_addr, socklen_t* addrlen) {
744 errno = ENOSYS; 800 errno = ENOSYS;
745 fprintf(stderr, "recvfrom has not been implemented!\n"); 801 fprintf(stderr, "recvfrom has not been implemented!\n");
746 return -1; 802 return -1;
747 } 803 }
748 804
749 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds, 805 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds,
750 fd_set* exceptfds, const struct timeval *timeout) { 806 fd_set* exceptfds, const struct timeval *timeout) {
751 errno = ENOSYS; 807 dbgprintf("int select() before mutex\n");
752 fprintf(stderr, "select has not been implemented!\n"); 808 Mutex::Lock lock(ss->mutex());
753 return -1; 809 dbgprintf("int select() after mutex\n");
810
811 timespec ts_abs;
812 if (timeout) {
813 timespec ts;
814 TIMEVAL_TO_TIMESPEC(timeout, &ts);
815 timeval tv_now;
816 gettimeofday(&tv_now, NULL);
817 int64_t current_time_us =
818 tv_now.tv_sec * kMicrosecondsPerSecond + tv_now.tv_usec;
819 int64_t wakeup_time_us =
820 current_time_us +
821 timeout->tv_sec * kMicrosecondsPerSecond + timeout->tv_usec;
822 ts_abs.tv_sec = wakeup_time_us / kMicrosecondsPerSecond;
823 ts_abs.tv_nsec =
824 (wakeup_time_us - ts_abs.tv_sec * kMicrosecondsPerSecond) *
825 kNanosecondsPerMicrosecond;
826 }
827
828 while (!(ss->IsReady(nfds, readfds, &FileStream::is_read_ready, false) ||
829 ss->IsReady(nfds, writefds, &FileStream::is_write_ready, false) ||
830 ss->IsReady(nfds, exceptfds, &FileStream::is_exception, false))) {
831 if (timeout) {
832 if (!timeout->tv_sec && !timeout->tv_usec)
833 break;
834
835 if (ss->cond().timedwait(ss->mutex(), &ts_abs)) {
836 if (errno == ETIMEDOUT)
837 break;
838 else
839 return -1;
840 }
841 } else {
842 ss->cond().wait(ss->mutex());
843 }
844 }
845
846 int nread = ss->IsReady(nfds, readfds, &FileStream::is_read_ready, true);
847 int nwrite = ss->IsReady(nfds, writefds, &FileStream::is_write_ready, true);
848 int nexcpt = ss->IsReady(nfds, exceptfds, &FileStream::is_exception, true);
849 if (nread < 0 || nwrite < 0 || nexcpt < 0) {
850 errno = EBADF;
851 return -1;
852 }
853 return nread + nwrite + nexcpt;
754 } 854 }
755 855
756 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds, 856 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds,
757 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) { 857 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) {
758 errno = ENOSYS; 858 errno = ENOSYS;
759 fprintf(stderr, "pselect has not been implemented!\n"); 859 fprintf(stderr, "pselect has not been implemented!\n");
760 return -1; 860 return -1;
761 } 861 }
762 862
763 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr, 863 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr,
(...skipping 18 matching lines...) Expand all
782 } 882 }
783 883
784 int KernelProxy::setsockopt(int sockfd, int level, int optname, 884 int KernelProxy::setsockopt(int sockfd, int level, int optname,
785 const void *optval, socklen_t optlen) { 885 const void *optval, socklen_t optlen) {
786 errno = ENOSYS; 886 errno = ENOSYS;
787 fprintf(stderr, "setsockopt has not been implemented!\n"); 887 fprintf(stderr, "setsockopt has not been implemented!\n");
788 return -1; 888 return -1;
789 } 889 }
790 890
791 int KernelProxy::shutdown(int sockfd, int how) { 891 int KernelProxy::shutdown(int sockfd, int how) {
792 errno = ENOSYS; 892 return close(sockfd);
793 fprintf(stderr, "shutdown has not been implemented!\n");
794 return -1;
795 } 893 }
796 894
797 int KernelProxy::epoll_create(int size) { 895 int KernelProxy::epoll_create(int size) {
798 errno = ENOSYS; 896 errno = ENOSYS;
799 fprintf(stderr, "epoll_create has not been implemented!\n"); 897 fprintf(stderr, "epoll_create has not been implemented!\n");
800 return -1; 898 return -1;
801 } 899 }
802 900
803 int KernelProxy::epoll_create1(int flags) { 901 int KernelProxy::epoll_create1(int flags) {
804 errno = ENOSYS; 902 errno = ENOSYS;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 939
842 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds, 940 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds,
843 const struct timespec *timeout, 941 const struct timespec *timeout,
844 const sigset_t *sigmask, size_t sigset_size) { 942 const sigset_t *sigmask, size_t sigset_size) {
845 errno = ENOSYS; 943 errno = ENOSYS;
846 fprintf(stderr, "ppoll has not been implemented!\n"); 944 fprintf(stderr, "ppoll has not been implemented!\n");
847 return -1; 945 return -1;
848 } 946 }
849 #endif 947 #endif
850 948
OLDNEW
« no previous file with comments | « libraries/nacl-mounts/base/KernelProxy.h ('k') | libraries/nacl-mounts/base/PthreadHelpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698