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

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

Powered by Google App Engine
This is Rietveld 408576698