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

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

Powered by Google App Engine
This is Rietveld 408576698