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

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, 6 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
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 "base/KernelProxy.h"
6 #include <assert.h> 7 #include <assert.h>
8 #include <netinet/in.h>
9 #include <sys/time.h>
7 #include <list> 10 #include <list>
8 #include <utility> 11 #include <utility>
9 #include "../console/ConsoleMount.h" 12 #include "console/ConsoleMount.h"
10 #include "../dev/DevMount.h" 13 #include "dev/DevMount.h"
11 #include "KernelProxy.h"
12 #include "MountManager.h" 14 #include "MountManager.h"
15 #include "net/BaseSocketSubSystem.h"
16 #include "net/SocketSubSystem.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::SetSocketSubSystem(BaseSocketSubSystem* bss) {
51 ss = bss;
52 }
53
54 void KernelProxy::RemoveFileStream(int fd) {
55 this->close(fd);
56 }
57
58 int KernelProxy::AddFileStream(FileStream* stream, int fd) {
59 SimpleAutoLock lock(&kp_lock_);
60
61 // Setup file handle.
62 int handle_slot = open_files_.AllocAt(fd);
63 if (fds_.AllocAt(fd) != fd) return -1;
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
78 int KernelProxy::AddFileStream(FileStream* stream) {
79 SimpleAutoLock lock(&kp_lock_);
80
81 // Setup file handle.
82 int handle_slot = open_files_.Alloc();
83 int fd = fds_.Alloc();
84 FileDescriptor* file = fds_.At(fd);
85 file->handle = handle_slot;
86 FileHandle* handle = open_files_.At(handle_slot);
87
88 // init should be safe because we have the kernel proxy lock
89 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
90
91 handle->mount = (Mount*) NULL;
92 handle->stream = (FileStream*) NULL;
93 handle->use_count = 1;
94
95 return fd;
96 }
97
45 KernelProxy *KernelProxy::KPInstance() { 98 KernelProxy *KernelProxy::KPInstance() {
46 pthread_once(&kp_once_, Instantiate); 99 pthread_once(&kp_once_, Instantiate);
47 return kp_instance_; 100 return kp_instance_;
48 } 101 }
49 102
50 void KernelProxy::Instantiate() { 103 void KernelProxy::Instantiate() {
51 assert(!kp_instance_); 104 assert(!kp_instance_);
52 kp_instance_ = new KernelProxy(); 105 kp_instance_ = new KernelProxy();
53 } 106 }
54 107
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 223 }
171 } 224 }
172 225
173 mount->Ref(st.st_ino); 226 mount->Ref(st.st_ino);
174 mount->Ref(); 227 mount->Ref();
175 // Setup file handle. 228 // Setup file handle.
176 int handle_slot = open_files_.Alloc(); 229 int handle_slot = open_files_.Alloc();
177 int fd = fds_.Alloc(); 230 int fd = fds_.Alloc();
178 FileDescriptor* file = fds_.At(fd); 231 FileDescriptor* file = fds_.At(fd);
179 file->handle = handle_slot; 232 file->handle = handle_slot;
180 FileHandle *handle = open_files_.At(handle_slot); 233 FileHandle* handle = open_files_.At(handle_slot);
181 234
182 // init should be safe because we have the kernel proxy lock 235 // init should be safe because we have the kernel proxy lock
183 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); 236 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
184 237
185 handle->mount = mount; 238 handle->mount = mount;
239 handle->stream = NULL;
186 handle->node = st.st_ino; 240 handle->node = st.st_ino;
187 handle->flags = flags; 241 handle->flags = flags;
188 handle->use_count = 1; 242 handle->use_count = 1;
189 243
190 if (flags & O_APPEND) { 244 if (flags & O_APPEND) {
191 handle->offset = st.st_size; 245 handle->offset = st.st_size;
192 } else { 246 } else {
193 handle->offset = 0; 247 handle->offset = 0;
194 } 248 }
195 249
196 return fd; 250 return fd;
197 } 251 }
198 252
253 struct hostent* KernelProxy::gethostbyname(const char* name) {
254 struct hostent *res = (struct hostent*) malloc(sizeof(struct hostent));
255 if (!res) return NULL;
256 res->h_addr_list = (char**) malloc(sizeof(char*) * 2);
257 if (!res->h_addr_list) return NULL;
258 res->h_addr_list[0] = (char*) malloc(sizeof(long int));
259 if (!res->h_addr_list[0]) return NULL;
260 *((long int*)res->h_addr_list[0]) = ss->gethostbyname(name);
261 res->h_addr_list[1] = NULL;
262 res->h_length = sizeof(long int);
263 return res;
264 }
265
199 int KernelProxy::open(const std::string& path, int flags, mode_t mode) { 266 int KernelProxy::open(const std::string& path, int flags, mode_t mode) {
200 if (path.empty()) { 267 if (path.empty()) {
201 errno = EINVAL; 268 errno = EINVAL;
202 return -1; 269 return -1;
203 } 270 }
204 271
205 Path p(path); 272 Path p(path);
206 if (path[0] != '/') { 273 if (path[0] != '/') {
207 p = Path(cwd_.FormulatePath() + "/" + path); 274 p = Path(cwd_.FormulatePath() + "/" + path);
208 } 275 }
(...skipping 12 matching lines...) Expand all
221 int KernelProxy::close(int fd) { 288 int KernelProxy::close(int fd) {
222 SimpleAutoLock lock(&kp_lock_); 289 SimpleAutoLock lock(&kp_lock_);
223 290
224 FileDescriptor* file = fds_.At(fd); 291 FileDescriptor* file = fds_.At(fd);
225 if (file == NULL) { 292 if (file == NULL) {
226 errno = EBADF; 293 errno = EBADF;
227 return -1; 294 return -1;
228 } 295 }
229 int h = file->handle; 296 int h = file->handle;
230 fds_.Free(fd); 297 fds_.Free(fd);
231 FileHandle *handle = open_files_.At(h); 298 FileHandle* handle = open_files_.At(h);
232 if (handle == NULL) { 299 if (handle == NULL) {
233 errno = EBADF; 300 errno = EBADF;
234 return -1; 301 return -1;
235 } 302 }
236 handle->use_count--; 303 handle->use_count--;
237 ino_t node = handle->node; 304 ino_t node = handle->node;
238 Mount *mount = handle->mount; 305 if (handle->mount) {
239 if (handle->use_count <= 0) { 306 Mount* mount = handle->mount;
240 open_files_.Free(h); 307 if (handle->use_count <= 0) {
241 mount->Unref(node); 308 open_files_.Free(h);
309 mount->Unref(node);
310 }
311 mount->Unref();
312 } else {
313 ss->close(handle->stream);
242 } 314 }
243 mount->Unref();
244 return 0; 315 return 0;
245 } 316 }
246 317
247 ssize_t KernelProxy::read(int fd, void *buf, size_t count) { 318 ssize_t KernelProxy::read(int fd, void *buf, size_t count) {
248 FileHandle *handle; 319 FileHandle* handle;
249 // check if fd is valid and handle exists 320 // check if fd is valid and handle exists
250 if (!(handle = GetFileHandle(fd))) { 321 if (!(handle = GetFileHandle(fd))) {
251 errno = EBADF; 322 errno = EBADF;
252 return -1; 323 return -1;
253 } 324 }
254 325
255 SimpleAutoLock(&handle->lock); 326 SimpleAutoLock(&handle->lock);
256 327
257 // Check that this file handle can be read from. 328 if (handle->mount) {
258 if ((handle->flags & O_ACCMODE) == O_WRONLY || 329 // Check that this file handle can be read from.
259 is_dir(handle->mount, handle->node)) { 330 if ((handle->flags & O_ACCMODE) == O_WRONLY ||
331 is_dir(handle->mount, handle->node)) {
332 errno = EBADF;
333 return -1;
334 }
335
336 ssize_t n = handle->mount->Read(handle->node, handle->offset, buf, count);
337 if (n > 0) {
338 handle->offset += n;
339 }
340 return n;
341 } else if (handle->stream) {
342 // TODO(vissi): more elaborate implementation
343 return recv(fd, buf, count, 0);
344 } else {
260 errno = EBADF; 345 errno = EBADF;
261 return -1; 346 return -1;
262 } 347 }
263
264 ssize_t n = handle->mount->Read(handle->node, handle->offset, buf, count);
265 if (n > 0) {
266 handle->offset += n;
267 }
268 return n;
269 } 348 }
270 349
271 ssize_t KernelProxy::write(int fd, const void *buf, size_t count) { 350 ssize_t KernelProxy::write(int fd, const void *buf, size_t count) {
272 FileHandle *handle; 351 FileHandle* handle;
273 352
274 // check if fd is valid and handle exists 353 // check if fd is valid and handle exists
275 if (!(handle = GetFileHandle(fd))) { 354 if (!(handle = GetFileHandle(fd))) {
276 errno = EBADF; 355 errno = EBADF;
277 return -1; 356 return -1;
278 } 357 }
279 358
280 SimpleAutoLock(&handle->lock); 359 SimpleAutoLock(&handle->lock);
281 360
282 // Check that this file handle can be written to. 361 if (handle->mount) {
283 if ((handle->flags & O_ACCMODE) == O_RDONLY || 362 // Check that this file handle can be written to.
284 is_dir(handle->mount, handle->node)) { 363 if ((handle->flags & O_ACCMODE) == O_RDONLY ||
364 is_dir(handle->mount, handle->node)) {
365 errno = EBADF;
366 return -1;
367 }
368
369 ssize_t n = handle->mount->Write(handle->node, handle->offset, buf, count);
370
371 if (n > 0) {
372 handle->offset += n;
373 }
374 return n;
375 } else if (handle->stream) {
376 // TODO(vissi): more elaborate implementation
377 return send(fd, buf, count, 0);
378 } else {
285 errno = EBADF; 379 errno = EBADF;
286 return -1; 380 return -1;
287 } 381 }
288
289 ssize_t n = handle->mount->Write(handle->node, handle->offset, buf, count);
290
291 if (n > 0) {
292 handle->offset += n;
293 }
294 return n;
295 } 382 }
296 383
297 int KernelProxy::fstat(int fd, struct stat *buf) { 384 int KernelProxy::fstat(int fd, struct stat *buf) {
298 FileHandle *handle; 385 FileHandle* handle;
299 386
300 // check if fd is valid and handle exists 387 // check if fd is valid and handle exists
301 if (!(handle = GetFileHandle(fd))) { 388 if (!(handle = GetFileHandle(fd))) {
302 errno = EBADF; 389 errno = EBADF;
303 return -1; 390 return -1;
304 } 391 }
305 SimpleAutoLock(&handle->lock); 392 SimpleAutoLock(&handle->lock);
306 return handle->mount->Stat(handle->node, buf); 393 return handle->mount->Stat(handle->node, buf);
307 } 394 }
308 395
309 int KernelProxy::ioctl(int fd, unsigned long request) { 396 int KernelProxy::ioctl(int fd, unsigned long request) {
310 errno = ENOSYS; 397 errno = ENOSYS;
311 fprintf(stderr, "ioctl has not been implemented!\n"); 398 fprintf(stderr, "ioctl has not been implemented!\n");
312 assert(0); 399 assert(0);
313 return -1; 400 return -1;
314 } 401 }
315 402
316 int KernelProxy::kill(pid_t pid, int sig) { 403 int KernelProxy::kill(pid_t pid, int sig) {
317 errno = ENOSYS; 404 errno = ENOSYS;
318 fprintf(stderr, "kill has not been implemented!\n"); 405 fprintf(stderr, "kill has not been implemented!\n");
319 assert(0); 406 assert(0);
320 return -1; 407 return -1;
321 } 408 }
322 409
323 int KernelProxy::getdents(int fd, void *buf, unsigned int count) { 410 int KernelProxy::getdents(int fd, void *buf, unsigned int count) {
324 FileHandle *handle; 411 FileHandle* handle;
325 412
326 // check if fd is valid and handle exists 413 // check if fd is valid and handle exists
327 if (!(handle = GetFileHandle(fd))) { 414 if (!(handle = GetFileHandle(fd))) {
328 errno = EBADF; 415 errno = EBADF;
329 return -1; 416 return -1;
330 } 417 }
331 418
332 SimpleAutoLock(&handle->lock); 419 SimpleAutoLock(&handle->lock);
333 420
334 int ret = handle->mount->Getdents(handle->node, handle->offset, 421 int ret = handle->mount->Getdents(handle->node, handle->offset,
335 (struct dirent*)buf, count); 422 (struct dirent*)buf, count);
336 423
337 if (ret != -1) { 424 if (ret != -1) {
338 // TODO(bradnelson): think of a better interface for Mount::Getdents. 425 // TODO(bradnelson): think of a better interface for Mount::Getdents.
339 // http://code.google.com/p/naclports/issues/detail?id=18 426 // http://code.google.com/p/naclports/issues/detail?id=18
340 handle->offset += ret / sizeof(struct dirent); 427 handle->offset += ret / sizeof(struct dirent);
341 } 428 }
342 return ret; 429 return ret;
343 } 430 }
344 431
345 int KernelProxy::fsync(int fd) { 432 int KernelProxy::fsync(int fd) {
346 FileHandle *handle; 433 FileHandle* handle;
347 434
348 if (!(handle = GetFileHandle(fd))) { 435 if (!(handle = GetFileHandle(fd))) {
349 errno = EBADF; 436 errno = EBADF;
350 return -1; 437 return -1;
351 } 438 }
352 SimpleAutoLock(&handle->lock); 439 SimpleAutoLock(&handle->lock);
353 return handle->mount->Fsync(handle->node); 440 return handle->mount->Fsync(handle->node);
354 } 441 }
355 442
356 int KernelProxy::isatty(int fd) { 443 int KernelProxy::isatty(int fd) {
357 FileHandle *handle; 444 FileHandle* handle;
358 445
359 if (!(handle = GetFileHandle(fd))) { 446 if (!(handle = GetFileHandle(fd))) {
360 errno = EBADF; 447 errno = EBADF;
361 return 0; 448 return 0;
362 } 449 }
363 SimpleAutoLock(&handle->lock);
364 return handle->mount->Isatty(handle->node); 450 return handle->mount->Isatty(handle->node);
365 } 451 }
366 452
453 int KernelProxy::dup2(int fd, int newfd) {
454 FileStream* stream = GetFileHandle(fd) > 0
455 ? GetFileHandle(fd)->stream : NULL;
456 if (!stream)
457 return EBADF;
458
459 AddFileStream(stream, newfd);
460 return 0;
461 }
462
463 int KernelProxy::IsReady(int nfds, fd_set* fds,
464 bool (FileStream::*is_ready)(), bool apply) {
465 if (!fds)
466 return 0;
467
468 int nset = 0;
469 for (int i = 0; i < nfds; i++) {
470 if (FD_ISSET(i, fds)) {
471 FileStream* stream = GetFileHandle(i) > 0 ?
472 GetFileHandle(i)->stream : NULL;
473 if (!stream)
474 return -1;
475 if ((stream->*is_ready)()) {
476 if (!apply)
477 return 1;
478 else
479 nset++;
480 } else {
481 if (apply)
482 FD_CLR(i, fds);
483 }
484 }
485 }
486 return nset;
487 }
488
367 int KernelProxy::dup(int oldfd) { 489 int KernelProxy::dup(int oldfd) {
368 SimpleAutoLock lock(&kp_lock_); 490 SimpleAutoLock lock(&kp_lock_);
369 491
492 FileHandle* fh = GetFileHandle(oldfd);
493 if (!fh) {
494 errno = EBADF;
495 return -1;
496 }
497 if (fh->mount == NULL) {
498 FileStream* stream = GetFileHandle(oldfd) > 0
499 ? GetFileHandle(oldfd)->stream : NULL;
500 if (!stream)
501 return EBADF;
502 int new_fd = AddFileStream(stream);
503 return new_fd;
504 }
370 FileDescriptor* oldfile = fds_.At(oldfd); 505 FileDescriptor* oldfile = fds_.At(oldfd);
371 if (oldfile == NULL) { 506 if (oldfile == NULL) {
372 errno = EBADF; 507 errno = EBADF;
373 return -1; 508 return -1;
374 } 509 }
375 int newfd = fds_.Alloc(); 510 int newfd = fds_.Alloc();
376 FileDescriptor *newfile = fds_.At(newfd); 511 FileDescriptor *newfile = fds_.At(newfd);
377 int h = oldfile->handle; 512 int h = oldfile->handle;
378 newfile->handle = h; 513 newfile->handle = h;
379 FileHandle *handle = open_files_.At(h); 514 FileHandle* handle = open_files_.At(h);
380 // init should be safe because we have the kernel proxy lock 515 // init should be safe because we have the kernel proxy lock
381 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); 516 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
382 517
383 if (handle == NULL) { 518 if (handle == NULL) {
384 errno = EBADF; 519 errno = EBADF;
385 return -1; 520 return -1;
386 } 521 }
387 ++handle->use_count; 522 ++handle->use_count;
388 handle->mount->Ref(handle->node); 523 handle->mount->Ref(handle->node);
389 handle->mount->Ref(); 524 handle->mount->Ref();
390 return newfd; 525 return newfd;
391 } 526 }
392 527
393 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 528 off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
394 FileHandle *handle; 529 FileHandle* handle;
395 // check if fd is valid and handle exists 530 // check if fd is valid and handle exists
396 if (!(handle = GetFileHandle(fd))) { 531 if (!(handle = GetFileHandle(fd))) {
397 errno = EBADF; 532 errno = EBADF;
398 return -1; 533 return -1;
399 } 534 }
400 535
401 SimpleAutoLock(&handle->lock); 536 SimpleAutoLock(&handle->lock);
402 537
403 off_t next; 538 off_t next;
404 ssize_t len; 539 ssize_t len;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 ((amode & X_OK) && !(mode & X_OK))) { 746 ((amode & X_OK) && !(mode & X_OK))) {
612 errno = EACCES; 747 errno = EACCES;
613 return -1; 748 return -1;
614 } 749 }
615 } 750 }
616 // By now we have checked access permissions for 751 // By now we have checked access permissions for
617 // each component of the path. 752 // each component of the path.
618 return 0; 753 return 0;
619 } 754 }
620 755
621 KernelProxy::FileHandle *KernelProxy::GetFileHandle(int fd) { 756 KernelProxy::FileHandle* KernelProxy::GetFileHandle(int fd) {
622 SimpleAutoLock lock(&kp_lock_); 757 SimpleAutoLock lock(&kp_lock_);
623 FileDescriptor *file = fds_.At(fd); 758 FileDescriptor *file = fds_.At(fd);
624 if (!file) { 759 if (!file) {
625 return NULL; 760 return NULL;
626 } 761 }
627 return open_files_.At(file->handle); 762 return open_files_.At(file->handle);
628 } 763 }
629 764
630 int KernelProxy::mkdir(const std::string& path, mode_t mode) { 765 int KernelProxy::mkdir(const std::string& path, mode_t mode) {
631 if (path.empty()) { 766 if (path.empty()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 if (mm_.InMountRootPath(abs_path)) { 804 if (mm_.InMountRootPath(abs_path)) {
670 errno = EBUSY; 805 errno = EBUSY;
671 return -1; 806 return -1;
672 } 807 }
673 808
674 return mount->Rmdir(buf.st_ino); 809 return mount->Rmdir(buf.st_ino);
675 } 810 }
676 811
677 #ifdef __GLIBC__ 812 #ifdef __GLIBC__
678 int KernelProxy::socket(int domain, int type, int protocol) { 813 int KernelProxy::socket(int domain, int type, int protocol) {
679 errno = ENOSYS; 814 SimpleAutoLock lock(&kp_lock_);
680 fprintf(stderr, "socket has not been implemented!\n"); 815 int handle_slot = open_files_.Alloc();
681 return -1; 816 int fd = fds_.Alloc();
817 FileDescriptor* file = fds_.At(fd);
818 file->handle = handle_slot;
819 FileHandle* handle = open_files_.At(handle_slot);
820 // this means it is a socket (not a mount handle) and it's implementation
821 // determined by handle->stream type is defined later
822 handle->mount = NULL;
823 handle->stream = NULL;
824 handle->use_count = 1;
825 return fd;
682 } 826 }
683 827
684 int KernelProxy::accept(int sockfd, struct sockaddr *addr, 828 int KernelProxy::accept(int sockfd, struct sockaddr *addr,
685 socklen_t* addrlen) { 829 socklen_t* addrlen) {
686 errno = ENOSYS; 830 if (GetFileHandle(sockfd) == 0) return EBADF;
687 fprintf(stderr, "accept has not been implemented!\n"); 831 FileStream* ret = ss->accept(GetFileHandle(sockfd)->stream, addr, addrlen);
688 return -1; 832 if (!ret)
833 return AddFileStream(ret);
834 else
835 return -1;
689 } 836 }
690 837
691 int KernelProxy::bind(int sockfd, const struct sockaddr *addr, 838 int KernelProxy::bind(int sockfd, const struct sockaddr *addr,
692 socklen_t addrlen) { 839 socklen_t addrlen) {
693 errno = ENOSYS; 840 if (GetFileHandle(sockfd) == 0) return EBADF;
694 fprintf(stderr, "bind has not been implemented!\n"); 841 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
695 return -1; 842 return ss->bind(&(GetFileHandle(sockfd)->stream), in_addr->sin_addr.s_addr,
843 (unsigned short) ntohs(in_addr->sin_port));
696 } 844 }
697 845
698 int KernelProxy::listen(int sockfd, int backlog) { 846 int KernelProxy::listen(int sockfd, int backlog) {
699 errno = ENOSYS; 847 if (GetFileHandle(sockfd) == 0) return EBADF;
700 fprintf(stderr, "listen has not been implemented!\n"); 848 return ss->listen(GetFileHandle(sockfd)->stream, backlog);
701 return -1;
702 } 849 }
703 850
704 int KernelProxy::connect(int sockfd, const struct sockaddr *addr, 851 int KernelProxy::connect(int sockfd, const struct sockaddr *addr,
705 socklen_t addrlen) { 852 socklen_t addrlen) {
706 errno = ENOSYS; 853 if (GetFileHandle(sockfd) == 0) return EBADF;
707 fprintf(stderr, "connect has not been implemented!\n"); 854 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
708 return -1; 855 return ss->connect(&(GetFileHandle(sockfd)->stream), in_addr->sin_addr.s_addr,
856 (unsigned short) ntohs(in_addr->sin_port));
709 } 857 }
710 858
711 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) { 859 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) {
712 errno = ENOSYS; 860 size_t nwr;
713 fprintf(stderr, "send has not been implemented!\n"); 861 if (GetFileHandle(sockfd) == 0) return EBADF;
714 return -1; 862 ss->write(GetFileHandle(sockfd)->stream, (const char*)buf, len, &nwr);
863 return nwr;
715 } 864 }
716 865
717 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) { 866 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) {
718 errno = ENOSYS; 867 errno = ENOSYS;
719 fprintf(stderr, "sendmsg has not been implemented!\n"); 868 fprintf(stderr, "sendmsg has not been implemented!\n");
720 return -1; 869 return -1;
721 } 870 }
722 871
723 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags, 872 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags,
724 const struct sockaddr *dest_addr, socklen_t addrlen) { 873 const struct sockaddr *dest_addr, socklen_t addrlen) {
725 errno = ENOSYS; 874 errno = ENOSYS;
726 fprintf(stderr, "sendto has not been implemented!\n"); 875 fprintf(stderr, "sendto has not been implemented!\n");
727 return -1; 876 return -1;
728 } 877 }
729 878
730 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) { 879 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) {
731 errno = ENOSYS; 880 size_t nread;
732 fprintf(stderr, "recv has not been implemented!\n"); 881 if (GetFileHandle(sockfd) == 0) return EBADF;
733 return -1; 882 ss->read(GetFileHandle(sockfd)->stream,
883 reinterpret_cast<char*>(buf), len, &nread);
884 return nread;
734 } 885 }
735 886
736 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) { 887 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) {
737 errno = ENOSYS; 888 errno = ENOSYS;
738 fprintf(stderr, "recvmsg has not been implemented!\n"); 889 fprintf(stderr, "recvmsg has not been implemented!\n");
739 return -1; 890 return -1;
740 } 891 }
741 892
742 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags, 893 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags,
743 struct sockaddr *dest_addr, socklen_t* addrlen) { 894 struct sockaddr *dest_addr, socklen_t* addrlen) {
744 errno = ENOSYS; 895 errno = ENOSYS;
745 fprintf(stderr, "recvfrom has not been implemented!\n"); 896 fprintf(stderr, "recvfrom has not been implemented!\n");
746 return -1; 897 return -1;
747 } 898 }
748 899
749 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds, 900 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds,
750 fd_set* exceptfds, const struct timeval *timeout) { 901 fd_set* exceptfds, const struct timeval *timeout) {
751 errno = ENOSYS; 902 Mutex::Lock lock(mutex());
752 fprintf(stderr, "select has not been implemented!\n"); 903
753 return -1; 904 timespec ts_abs;
905 if (timeout) {
906 timespec ts;
907 TIMEVAL_TO_TIMESPEC(timeout, &ts);
908 timeval tv_now;
909 gettimeofday(&tv_now, NULL);
910 int64_t current_time_us =
911 tv_now.tv_sec * kMicrosecondsPerSecond + tv_now.tv_usec;
912 int64_t wakeup_time_us =
913 current_time_us +
914 timeout->tv_sec * kMicrosecondsPerSecond + timeout->tv_usec;
915 ts_abs.tv_sec = wakeup_time_us / kMicrosecondsPerSecond;
916 ts_abs.tv_nsec =
917 (wakeup_time_us - ts_abs.tv_sec * kMicrosecondsPerSecond) *
918 kNanosecondsPerMicrosecond;
919 }
920
921 while (!(IsReady(nfds, readfds, &FileStream::is_read_ready, false) ||
922 IsReady(nfds, writefds, &FileStream::is_write_ready, false) ||
923 IsReady(nfds, exceptfds, &FileStream::is_exception, false))) {
924 if (timeout) {
925 if (!timeout->tv_sec && !timeout->tv_usec)
926 break;
927
928 if (cond().timedwait(mutex(), &ts_abs)) {
929 if (errno == ETIMEDOUT)
930 break;
931 else
932 return -1;
933 }
934 } else {
935 cond().wait(mutex());
936 }
937 }
938
939 int nread = IsReady(nfds, readfds, &FileStream::is_read_ready, true);
940 int nwrite = IsReady(nfds, writefds, &FileStream::is_write_ready, true);
941 int nexcpt = IsReady(nfds, exceptfds, &FileStream::is_exception, true);
942 if (nread < 0 || nwrite < 0 || nexcpt < 0) {
943 errno = EBADF;
944 return -1;
945 }
946 return nread + nwrite + nexcpt;
754 } 947 }
755 948
756 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds, 949 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds,
757 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) { 950 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) {
758 errno = ENOSYS; 951 errno = ENOSYS;
759 fprintf(stderr, "pselect has not been implemented!\n"); 952 fprintf(stderr, "pselect has not been implemented!\n");
760 return -1; 953 return -1;
761 } 954 }
762 955
763 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr, 956 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr,
(...skipping 18 matching lines...) Expand all
782 } 975 }
783 976
784 int KernelProxy::setsockopt(int sockfd, int level, int optname, 977 int KernelProxy::setsockopt(int sockfd, int level, int optname,
785 const void *optval, socklen_t optlen) { 978 const void *optval, socklen_t optlen) {
786 errno = ENOSYS; 979 errno = ENOSYS;
787 fprintf(stderr, "setsockopt has not been implemented!\n"); 980 fprintf(stderr, "setsockopt has not been implemented!\n");
788 return -1; 981 return -1;
789 } 982 }
790 983
791 int KernelProxy::shutdown(int sockfd, int how) { 984 int KernelProxy::shutdown(int sockfd, int how) {
792 errno = ENOSYS; 985 if (GetFileHandle(sockfd) == 0) return EBADF;
793 fprintf(stderr, "shutdown has not been implemented!\n"); 986 return ss->shutdown(GetFileHandle(sockfd)->stream, how);
794 return -1;
795 } 987 }
796 988
797 int KernelProxy::epoll_create(int size) { 989 int KernelProxy::epoll_create(int size) {
798 errno = ENOSYS; 990 errno = ENOSYS;
799 fprintf(stderr, "epoll_create has not been implemented!\n"); 991 fprintf(stderr, "epoll_create has not been implemented!\n");
800 return -1; 992 return -1;
801 } 993 }
802 994
803 int KernelProxy::epoll_create1(int flags) { 995 int KernelProxy::epoll_create1(int flags) {
804 errno = ENOSYS; 996 errno = ENOSYS;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 1033
842 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds, 1034 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds,
843 const struct timespec *timeout, 1035 const struct timespec *timeout,
844 const sigset_t *sigmask, size_t sigset_size) { 1036 const sigset_t *sigmask, size_t sigset_size) {
845 errno = ENOSYS; 1037 errno = ENOSYS;
846 fprintf(stderr, "ppoll has not been implemented!\n"); 1038 fprintf(stderr, "ppoll has not been implemented!\n");
847 return -1; 1039 return -1;
848 } 1040 }
849 #endif 1041 #endif
850 1042
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698