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

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
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 "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/SocketSubSystem.h"
16 #include "net/BaseSocketSubSystem.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 ino_t KernelProxy::CreateSocket() {
Evgeniy Stepanov 2012/05/25 12:05:57 move into socket()
vissi 2012/05/25 13:07:09 Done.
254 SimpleAutoLock lock(&kp_lock_);
255 int handle_slot = open_files_.Alloc();
256 int fd = fds_.Alloc();
257 FileDescriptor* file = fds_.At(fd);
258 file->handle = handle_slot;
259 FileHandle* handle = open_files_.At(handle_slot);
260 handle->mount = NULL;
261 handle->stream = NULL;
Evgeniy Stepanov 2012/05/25 12:05:57 a comment somewhere that (NULL, NULL) means a gene
vissi 2012/05/25 13:07:09 Done.
262 handle->use_count = 1;
263 return fd;
264 }
265
266 struct hostent* KernelProxy::gethostbyname(const char* name) {
267 struct hostent *res = (struct hostent*) malloc(sizeof(struct hostent));
268 if (!res) return NULL;
269 res->h_addr_list = (char**) malloc(sizeof(char*) * 2);
270 if (!res->h_addr_list) return NULL;
271 res->h_addr_list[0] = (char*) malloc(sizeof(long int));
272 if (!res->h_addr_list[0]) return NULL;
273 *((long int*)res->h_addr_list[0]) = ss->gethostbyname(name);
274 res->h_addr_list[1] = NULL;
275 res->h_length = sizeof(long int);
276 return res;
277 }
278
199 int KernelProxy::open(const std::string& path, int flags, mode_t mode) { 279 int KernelProxy::open(const std::string& path, int flags, mode_t mode) {
200 if (path.empty()) { 280 if (path.empty()) {
201 errno = EINVAL; 281 errno = EINVAL;
202 return -1; 282 return -1;
203 } 283 }
204 284
205 Path p(path); 285 Path p(path);
206 if (path[0] != '/') { 286 if (path[0] != '/') {
207 p = Path(cwd_.FormulatePath() + "/" + path); 287 p = Path(cwd_.FormulatePath() + "/" + path);
208 } 288 }
(...skipping 12 matching lines...) Expand all
221 int KernelProxy::close(int fd) { 301 int KernelProxy::close(int fd) {
222 SimpleAutoLock lock(&kp_lock_); 302 SimpleAutoLock lock(&kp_lock_);
223 303
224 FileDescriptor* file = fds_.At(fd); 304 FileDescriptor* file = fds_.At(fd);
225 if (file == NULL) { 305 if (file == NULL) {
226 errno = EBADF; 306 errno = EBADF;
227 return -1; 307 return -1;
228 } 308 }
229 int h = file->handle; 309 int h = file->handle;
230 fds_.Free(fd); 310 fds_.Free(fd);
231 FileHandle *handle = open_files_.At(h); 311 FileHandle* handle = open_files_.At(h);
232 if (handle == NULL) { 312 if (handle == NULL) {
233 errno = EBADF; 313 errno = EBADF;
234 return -1; 314 return -1;
235 } 315 }
236 handle->use_count--; 316 handle->use_count--;
237 ino_t node = handle->node; 317 ino_t node = handle->node;
238 Mount *mount = handle->mount; 318 if (handle->mount) {
239 if (handle->use_count <= 0) { 319 Mount* mount = handle->mount;
240 open_files_.Free(h); 320 if (handle->use_count <= 0) {
241 mount->Unref(node); 321 open_files_.Free(h);
322 mount->Unref(node);
323 }
324 mount->Unref();
325 } else {
326 ss->close(handle->stream);
242 } 327 }
243 mount->Unref();
244 return 0; 328 return 0;
245 } 329 }
246 330
247 ssize_t KernelProxy::read(int fd, void *buf, size_t count) { 331 ssize_t KernelProxy::read(int fd, void *buf, size_t count) {
248 FileHandle *handle; 332 FileHandle* handle;
Evgeniy Stepanov 2012/05/25 12:05:57 TODO handle sockets in read and write
vissi 2012/05/25 13:07:09 Done.
249 // check if fd is valid and handle exists 333 // check if fd is valid and handle exists
250 if (!(handle = GetFileHandle(fd))) { 334 if (!(handle = GetFileHandle(fd))) {
251 errno = EBADF; 335 errno = EBADF;
252 return -1; 336 return -1;
253 } 337 }
254 338
255 SimpleAutoLock(&handle->lock); 339 SimpleAutoLock(&handle->lock);
256 340
257 // Check that this file handle can be read from. 341 // Check that this file handle can be read from.
258 if ((handle->flags & O_ACCMODE) == O_WRONLY || 342 if ((handle->flags & O_ACCMODE) == O_WRONLY ||
259 is_dir(handle->mount, handle->node)) { 343 is_dir(handle->mount, handle->node)) {
260 errno = EBADF; 344 errno = EBADF;
261 return -1; 345 return -1;
262 } 346 }
263 347
264 ssize_t n = handle->mount->Read(handle->node, handle->offset, buf, count); 348 ssize_t n = handle->mount->Read(handle->node, handle->offset, buf, count);
265 if (n > 0) { 349 if (n > 0) {
266 handle->offset += n; 350 handle->offset += n;
267 } 351 }
268 return n; 352 return n;
269 } 353 }
270 354
271 ssize_t KernelProxy::write(int fd, const void *buf, size_t count) { 355 ssize_t KernelProxy::write(int fd, const void *buf, size_t count) {
272 FileHandle *handle; 356 FileHandle* handle;
273 357
274 // check if fd is valid and handle exists 358 // check if fd is valid and handle exists
275 if (!(handle = GetFileHandle(fd))) { 359 if (!(handle = GetFileHandle(fd))) {
276 errno = EBADF; 360 errno = EBADF;
277 return -1; 361 return -1;
278 } 362 }
279 363
280 SimpleAutoLock(&handle->lock); 364 SimpleAutoLock(&handle->lock);
281 365
282 // Check that this file handle can be written to. 366 // Check that this file handle can be written to.
283 if ((handle->flags & O_ACCMODE) == O_RDONLY || 367 if ((handle->flags & O_ACCMODE) == O_RDONLY ||
284 is_dir(handle->mount, handle->node)) { 368 is_dir(handle->mount, handle->node)) {
285 errno = EBADF; 369 errno = EBADF;
286 return -1; 370 return -1;
287 } 371 }
288 372
289 ssize_t n = handle->mount->Write(handle->node, handle->offset, buf, count); 373 ssize_t n = handle->mount->Write(handle->node, handle->offset, buf, count);
290 374
291 if (n > 0) { 375 if (n > 0) {
292 handle->offset += n; 376 handle->offset += n;
293 } 377 }
294 return n; 378 return n;
295 } 379 }
296 380
297 int KernelProxy::fstat(int fd, struct stat *buf) { 381 int KernelProxy::fstat(int fd, struct stat *buf) {
298 FileHandle *handle; 382 FileHandle* handle;
299 383
300 // check if fd is valid and handle exists 384 // check if fd is valid and handle exists
301 if (!(handle = GetFileHandle(fd))) { 385 if (!(handle = GetFileHandle(fd))) {
302 errno = EBADF; 386 errno = EBADF;
303 return -1; 387 return -1;
304 } 388 }
305 SimpleAutoLock(&handle->lock); 389 SimpleAutoLock(&handle->lock);
306 return handle->mount->Stat(handle->node, buf); 390 return handle->mount->Stat(handle->node, buf);
307 } 391 }
308 392
309 int KernelProxy::ioctl(int fd, unsigned long request) { 393 int KernelProxy::ioctl(int fd, unsigned long request) {
310 errno = ENOSYS; 394 errno = ENOSYS;
311 fprintf(stderr, "ioctl has not been implemented!\n"); 395 fprintf(stderr, "ioctl has not been implemented!\n");
312 assert(0); 396 assert(0);
313 return -1; 397 return -1;
314 } 398 }
315 399
316 int KernelProxy::kill(pid_t pid, int sig) { 400 int KernelProxy::kill(pid_t pid, int sig) {
317 errno = ENOSYS; 401 errno = ENOSYS;
318 fprintf(stderr, "kill has not been implemented!\n"); 402 fprintf(stderr, "kill has not been implemented!\n");
319 assert(0); 403 assert(0);
320 return -1; 404 return -1;
321 } 405 }
322 406
323 int KernelProxy::getdents(int fd, void *buf, unsigned int count) { 407 int KernelProxy::getdents(int fd, void *buf, unsigned int count) {
324 FileHandle *handle; 408 FileHandle* handle;
325 409
326 // check if fd is valid and handle exists 410 // check if fd is valid and handle exists
327 if (!(handle = GetFileHandle(fd))) { 411 if (!(handle = GetFileHandle(fd))) {
328 errno = EBADF; 412 errno = EBADF;
329 return -1; 413 return -1;
330 } 414 }
331 415
332 SimpleAutoLock(&handle->lock); 416 SimpleAutoLock(&handle->lock);
333 417
334 int ret = handle->mount->Getdents(handle->node, handle->offset, 418 int ret = handle->mount->Getdents(handle->node, handle->offset,
335 (struct dirent*)buf, count); 419 (struct dirent*)buf, count);
336 420
337 if (ret != -1) { 421 if (ret != -1) {
338 // TODO(bradnelson): think of a better interface for Mount::Getdents. 422 // TODO(bradnelson): think of a better interface for Mount::Getdents.
339 // http://code.google.com/p/naclports/issues/detail?id=18 423 // http://code.google.com/p/naclports/issues/detail?id=18
340 handle->offset += ret / sizeof(struct dirent); 424 handle->offset += ret / sizeof(struct dirent);
341 } 425 }
342 return ret; 426 return ret;
343 } 427 }
344 428
345 int KernelProxy::fsync(int fd) { 429 int KernelProxy::fsync(int fd) {
346 FileHandle *handle; 430 FileHandle* handle;
347 431
348 if (!(handle = GetFileHandle(fd))) { 432 if (!(handle = GetFileHandle(fd))) {
349 errno = EBADF; 433 errno = EBADF;
350 return -1; 434 return -1;
351 } 435 }
352 SimpleAutoLock(&handle->lock); 436 SimpleAutoLock(&handle->lock);
353 return handle->mount->Fsync(handle->node); 437 return handle->mount->Fsync(handle->node);
354 } 438 }
355 439
356 int KernelProxy::isatty(int fd) { 440 int KernelProxy::isatty(int fd) {
357 FileHandle *handle; 441 FileHandle* handle;
358 442
359 if (!(handle = GetFileHandle(fd))) { 443 if (!(handle = GetFileHandle(fd))) {
360 errno = EBADF; 444 errno = EBADF;
361 return 0; 445 return 0;
362 } 446 }
363 SimpleAutoLock(&handle->lock);
364 return handle->mount->Isatty(handle->node); 447 return handle->mount->Isatty(handle->node);
365 } 448 }
366 449
450 int KernelProxy::dup2(int fd, int newfd) {
451 // TODO lock???
452 FileStream* stream = GetFileHandle(fd) > 0
453 ? GetFileHandle(fd)->stream : kBadFileStream;
454 if (!stream || stream == kBadFileStream)
455 return EBADF;
456
457 FileStream* new_stream = GetFileHandle(newfd) > 0
458 ? GetFileHandle(newfd)->stream : kBadFileStream;
459 if (stream == kBadFileStream) {
460 return EBADF;
461 } else if (!new_stream) {
462 new_stream->close();
Evgeniy Stepanov 2012/05/25 12:05:57 this will crash
vissi 2012/05/25 13:07:09 Removed
463 new_stream->release();
464 RemoveFileStream(newfd);
465 }
466
467 GetFileHandle(newfd)->stream
468 = stream->dup(newfd);
Evgeniy Stepanov 2012/05/25 12:05:57 no need to dup streams, new handle should hold a r
vissi 2012/05/25 13:07:09 Done.
469 if (!new_stream)
470 return EACCES;
471
472 AddFileStream(new_stream, newfd);
473 return 0;
474 }
475
476 int KernelProxy::IsReady(int nfds, fd_set* fds,
477 bool (FileStream::*is_ready)(), bool apply) {
478 if (!fds)
479 return 0;
480
481 int nset = 0;
482 for (int i = 0; i < nfds; i++) {
483 if (FD_ISSET(i, fds)) {
484 FileStream* stream = GetFileHandle(i) > 0 ?
485 GetFileHandle(i)->stream : kBadFileStream;
486 if (!stream)
487 return -1;
488 if ((stream->*is_ready)()) {
489 if (!apply)
490 return 1;
491 else
492 nset++;
493 } else {
494 if (apply)
495 FD_CLR(i, fds);
496 }
497 }
498 }
499 return nset;
500 }
501
367 int KernelProxy::dup(int oldfd) { 502 int KernelProxy::dup(int oldfd) {
368 SimpleAutoLock lock(&kp_lock_); 503 SimpleAutoLock lock(&kp_lock_);
369 504
505 FileHandle* fh = GetFileHandle(oldfd);
506 if (!fh) {
507 errno = EBADF;
508 return -1;
509 }
510 if (fh->mount == NULL) {
511 FileStream* stream = GetFileHandle(oldfd) > 0
512 ? GetFileHandle(oldfd)->stream : kBadFileStream;
513 if (!stream || stream == kBadFileStream)
514 return EBADF;
515 int new_fd = AddFileStream(NULL);
516 FileStream* new_stream = stream->dup(new_fd);
Evgeniy Stepanov 2012/05/25 12:05:57 dup does not create new stream or handle, just a n
vissi 2012/05/25 13:07:09 Done.
517 if (!new_stream) {
518 RemoveFileStream(new_fd);
519 return EACCES;
520 }
521 GetFileHandle(new_fd)->stream = new_stream;
522 return new_fd;
523 }
370 FileDescriptor* oldfile = fds_.At(oldfd); 524 FileDescriptor* oldfile = fds_.At(oldfd);
371 if (oldfile == NULL) { 525 if (oldfile == NULL) {
372 errno = EBADF; 526 errno = EBADF;
373 return -1; 527 return -1;
374 } 528 }
375 int newfd = fds_.Alloc(); 529 int newfd = fds_.Alloc();
376 FileDescriptor *newfile = fds_.At(newfd); 530 FileDescriptor *newfile = fds_.At(newfd);
377 int h = oldfile->handle; 531 int h = oldfile->handle;
378 newfile->handle = h; 532 newfile->handle = h;
379 FileHandle *handle = open_files_.At(h); 533 FileHandle* handle = open_files_.At(h);
380 // init should be safe because we have the kernel proxy lock 534 // init should be safe because we have the kernel proxy lock
381 if (pthread_mutex_init(&handle->lock, NULL)) assert(0); 535 if (pthread_mutex_init(&handle->lock, NULL)) assert(0);
382 536
383 if (handle == NULL) { 537 if (handle == NULL) {
384 errno = EBADF; 538 errno = EBADF;
385 return -1; 539 return -1;
386 } 540 }
387 ++handle->use_count; 541 ++handle->use_count;
388 handle->mount->Ref(handle->node); 542 handle->mount->Ref(handle->node);
389 handle->mount->Ref(); 543 handle->mount->Ref();
390 return newfd; 544 return newfd;
391 } 545 }
392 546
393 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 547 off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
394 FileHandle *handle; 548 FileHandle* handle;
395 // check if fd is valid and handle exists 549 // check if fd is valid and handle exists
396 if (!(handle = GetFileHandle(fd))) { 550 if (!(handle = GetFileHandle(fd))) {
397 errno = EBADF; 551 errno = EBADF;
398 return -1; 552 return -1;
399 } 553 }
400 554
401 SimpleAutoLock(&handle->lock); 555 SimpleAutoLock(&handle->lock);
402 556
403 off_t next; 557 off_t next;
404 ssize_t len; 558 ssize_t len;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 ((amode & X_OK) && !(mode & X_OK))) { 765 ((amode & X_OK) && !(mode & X_OK))) {
612 errno = EACCES; 766 errno = EACCES;
613 return -1; 767 return -1;
614 } 768 }
615 } 769 }
616 // By now we have checked access permissions for 770 // By now we have checked access permissions for
617 // each component of the path. 771 // each component of the path.
618 return 0; 772 return 0;
619 } 773 }
620 774
621 KernelProxy::FileHandle *KernelProxy::GetFileHandle(int fd) { 775 FileHandle* KernelProxy::GetFileHandle(int fd) {
622 SimpleAutoLock lock(&kp_lock_); 776 SimpleAutoLock lock(&kp_lock_);
623 FileDescriptor *file = fds_.At(fd); 777 FileDescriptor *file = fds_.At(fd);
624 if (!file) { 778 if (!file) {
625 return NULL; 779 return NULL;
626 } 780 }
627 return open_files_.At(file->handle); 781 return open_files_.At(file->handle);
628 } 782 }
629 783
630 int KernelProxy::mkdir(const std::string& path, mode_t mode) { 784 int KernelProxy::mkdir(const std::string& path, mode_t mode) {
631 if (path.empty()) { 785 if (path.empty()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 if (mm_.InMountRootPath(abs_path)) { 823 if (mm_.InMountRootPath(abs_path)) {
670 errno = EBUSY; 824 errno = EBUSY;
671 return -1; 825 return -1;
672 } 826 }
673 827
674 return mount->Rmdir(buf.st_ino); 828 return mount->Rmdir(buf.st_ino);
675 } 829 }
676 830
677 #ifdef __GLIBC__ 831 #ifdef __GLIBC__
678 int KernelProxy::socket(int domain, int type, int protocol) { 832 int KernelProxy::socket(int domain, int type, int protocol) {
679 errno = ENOSYS; 833 return CreateSocket();
680 fprintf(stderr, "socket has not been implemented!\n");
681 return -1;
682 } 834 }
683 835
684 int KernelProxy::accept(int sockfd, struct sockaddr *addr, 836 int KernelProxy::accept(int sockfd, struct sockaddr *addr,
685 socklen_t* addrlen) { 837 socklen_t* addrlen) {
686 errno = ENOSYS; 838 if (GetFileHandle(sockfd) == 0) return EBADF;
687 fprintf(stderr, "accept has not been implemented!\n"); 839 FileStream* ret = ss->accept(GetFileHandle(sockfd)->stream, addr, addrlen);
688 return -1; 840 if (!ret)
841 return AddFileStream(ret);
842 else
843 return -1;
689 } 844 }
690 845
691 int KernelProxy::bind(int sockfd, const struct sockaddr *addr, 846 int KernelProxy::bind(int sockfd, const struct sockaddr *addr,
692 socklen_t addrlen) { 847 socklen_t addrlen) {
693 errno = ENOSYS; 848 if (GetFileHandle(sockfd) == 0) return EBADF;
694 fprintf(stderr, "bind has not been implemented!\n"); 849 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
695 return -1; 850 return ss->bind(&(GetFileHandle(sockfd)->stream), in_addr->sin_addr.s_addr,
851 (unsigned short) ntohs(in_addr->sin_port));
696 } 852 }
697 853
698 int KernelProxy::listen(int sockfd, int backlog) { 854 int KernelProxy::listen(int sockfd, int backlog) {
699 errno = ENOSYS; 855 if (GetFileHandle(sockfd) == 0) return EBADF;
700 fprintf(stderr, "listen has not been implemented!\n"); 856 return ss->listen(GetFileHandle(sockfd)->stream, backlog);
701 return -1;
702 } 857 }
703 858
704 int KernelProxy::connect(int sockfd, const struct sockaddr *addr, 859 int KernelProxy::connect(int sockfd, const struct sockaddr *addr,
705 socklen_t addrlen) { 860 socklen_t addrlen) {
706 errno = ENOSYS; 861 if (GetFileHandle(sockfd) == 0) return EBADF;
707 fprintf(stderr, "connect has not been implemented!\n"); 862 struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
708 return -1; 863 return ss->connect(&(GetFileHandle(sockfd)->stream), in_addr->sin_addr.s_addr,
864 (unsigned short) ntohs(in_addr->sin_port));
709 } 865 }
710 866
711 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) { 867 int KernelProxy::send(int sockfd, const void *buf, size_t len, int flags) {
712 errno = ENOSYS; 868 size_t nwr;
713 fprintf(stderr, "send has not been implemented!\n"); 869 if (GetFileHandle(sockfd) == 0) return EBADF;
714 return -1; 870 ss->write(GetFileHandle(sockfd)->stream, (const char*)buf, len, &nwr);
871 return nwr;
715 } 872 }
716 873
717 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) { 874 int KernelProxy::sendmsg(int sockfd, const struct msghdr *msg, int flags) {
718 errno = ENOSYS; 875 errno = ENOSYS;
719 fprintf(stderr, "sendmsg has not been implemented!\n"); 876 fprintf(stderr, "sendmsg has not been implemented!\n");
720 return -1; 877 return -1;
721 } 878 }
722 879
723 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags, 880 int KernelProxy::sendto(int sockfd, const void *buf, size_t len, int flags,
724 const struct sockaddr *dest_addr, socklen_t addrlen) { 881 const struct sockaddr *dest_addr, socklen_t addrlen) {
725 errno = ENOSYS; 882 errno = ENOSYS;
726 fprintf(stderr, "sendto has not been implemented!\n"); 883 fprintf(stderr, "sendto has not been implemented!\n");
727 return -1; 884 return -1;
728 } 885 }
729 886
730 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) { 887 int KernelProxy::recv(int sockfd, void *buf, size_t len, int flags) {
731 errno = ENOSYS; 888 size_t nread;
732 fprintf(stderr, "recv has not been implemented!\n"); 889 if (GetFileHandle(sockfd) == 0) return EBADF;
733 return -1; 890 ss->read(GetFileHandle(sockfd)->stream,
891 reinterpret_cast<char*>(buf), len, &nread);
892 return nread;
734 } 893 }
735 894
736 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) { 895 int KernelProxy::recvmsg(int sockfd, struct msghdr *msg, int flags) {
737 errno = ENOSYS; 896 errno = ENOSYS;
738 fprintf(stderr, "recvmsg has not been implemented!\n"); 897 fprintf(stderr, "recvmsg has not been implemented!\n");
739 return -1; 898 return -1;
740 } 899 }
741 900
742 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags, 901 int KernelProxy::recvfrom(int sockfd, void *buf, size_t len, int flags,
743 struct sockaddr *dest_addr, socklen_t* addrlen) { 902 struct sockaddr *dest_addr, socklen_t* addrlen) {
744 errno = ENOSYS; 903 errno = ENOSYS;
745 fprintf(stderr, "recvfrom has not been implemented!\n"); 904 fprintf(stderr, "recvfrom has not been implemented!\n");
746 return -1; 905 return -1;
747 } 906 }
748 907
749 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds, 908 int KernelProxy::select(int nfds, fd_set *readfds, fd_set *writefds,
750 fd_set* exceptfds, const struct timeval *timeout) { 909 fd_set* exceptfds, const struct timeval *timeout) {
751 errno = ENOSYS; 910 dbgprintf("int select() before mutex\n");
752 fprintf(stderr, "select has not been implemented!\n"); 911 Mutex::Lock lock(ss->mutex());
753 return -1; 912 dbgprintf("int select() after mutex\n");
913
914 timespec ts_abs;
915 if (timeout) {
916 timespec ts;
917 TIMEVAL_TO_TIMESPEC(timeout, &ts);
918 timeval tv_now;
919 gettimeofday(&tv_now, NULL);
920 int64_t current_time_us =
921 tv_now.tv_sec * kMicrosecondsPerSecond + tv_now.tv_usec;
922 int64_t wakeup_time_us =
923 current_time_us +
924 timeout->tv_sec * kMicrosecondsPerSecond + timeout->tv_usec;
925 ts_abs.tv_sec = wakeup_time_us / kMicrosecondsPerSecond;
926 ts_abs.tv_nsec =
927 (wakeup_time_us - ts_abs.tv_sec * kMicrosecondsPerSecond) *
928 kNanosecondsPerMicrosecond;
929 }
930
931 while (!(IsReady(nfds, readfds, &FileStream::is_read_ready, false) ||
932 IsReady(nfds, writefds, &FileStream::is_write_ready, false) ||
933 IsReady(nfds, exceptfds, &FileStream::is_exception, false))) {
934 if (timeout) {
935 if (!timeout->tv_sec && !timeout->tv_usec)
936 break;
937
938 if (ss->cond().timedwait(ss->mutex(), &ts_abs)) {
939 if (errno == ETIMEDOUT)
940 break;
941 else
942 return -1;
943 }
944 } else {
945 ss->cond().wait(ss->mutex());
946 }
947 }
948
949 int nread = IsReady(nfds, readfds, &FileStream::is_read_ready, true);
950 int nwrite = IsReady(nfds, writefds, &FileStream::is_write_ready, true);
951 int nexcpt = IsReady(nfds, exceptfds, &FileStream::is_exception, true);
952 if (nread < 0 || nwrite < 0 || nexcpt < 0) {
953 errno = EBADF;
954 return -1;
955 }
956 return nread + nwrite + nexcpt;
754 } 957 }
755 958
756 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds, 959 int KernelProxy::pselect(int nfds, fd_set *readfds, fd_set *writefds,
757 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) { 960 fd_set* exceptfds, const struct timeval *timeout, void* sigmask) {
758 errno = ENOSYS; 961 errno = ENOSYS;
759 fprintf(stderr, "pselect has not been implemented!\n"); 962 fprintf(stderr, "pselect has not been implemented!\n");
760 return -1; 963 return -1;
761 } 964 }
762 965
763 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr, 966 int KernelProxy::getpeername(int sockfd, struct sockaddr *addr,
(...skipping 18 matching lines...) Expand all
782 } 985 }
783 986
784 int KernelProxy::setsockopt(int sockfd, int level, int optname, 987 int KernelProxy::setsockopt(int sockfd, int level, int optname,
785 const void *optval, socklen_t optlen) { 988 const void *optval, socklen_t optlen) {
786 errno = ENOSYS; 989 errno = ENOSYS;
787 fprintf(stderr, "setsockopt has not been implemented!\n"); 990 fprintf(stderr, "setsockopt has not been implemented!\n");
788 return -1; 991 return -1;
789 } 992 }
790 993
791 int KernelProxy::shutdown(int sockfd, int how) { 994 int KernelProxy::shutdown(int sockfd, int how) {
792 errno = ENOSYS; 995 if (GetFileHandle(sockfd) == 0) return EBADF;
793 fprintf(stderr, "shutdown has not been implemented!\n"); 996 return ss->shutdown(GetFileHandle(sockfd)->stream, how);
794 return -1;
795 } 997 }
796 998
797 int KernelProxy::epoll_create(int size) { 999 int KernelProxy::epoll_create(int size) {
798 errno = ENOSYS; 1000 errno = ENOSYS;
799 fprintf(stderr, "epoll_create has not been implemented!\n"); 1001 fprintf(stderr, "epoll_create has not been implemented!\n");
800 return -1; 1002 return -1;
801 } 1003 }
802 1004
803 int KernelProxy::epoll_create1(int flags) { 1005 int KernelProxy::epoll_create1(int flags) {
804 errno = ENOSYS; 1006 errno = ENOSYS;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 1043
842 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds, 1044 int KernelProxy::ppoll(struct pollfd *fds, nfds_t nfds,
843 const struct timespec *timeout, 1045 const struct timespec *timeout,
844 const sigset_t *sigmask, size_t sigset_size) { 1046 const sigset_t *sigmask, size_t sigset_size) {
845 errno = ENOSYS; 1047 errno = ENOSYS;
846 fprintf(stderr, "ppoll has not been implemented!\n"); 1048 fprintf(stderr, "ppoll has not been implemented!\n");
847 return -1; 1049 return -1;
848 } 1050 }
849 #endif 1051 #endif
850 1052
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698