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

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

Powered by Google App Engine
This is Rietveld 408576698