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

Side by Side Diff: src/d8-posix.cc

Issue 15793007: Cutover v8 to use new style callbacks internally (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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
« no previous file with comments | « src/d8.cc ('k') | src/extensions/externalize-string-extension.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 static const unsigned kMaxArgs = 1000; 231 static const unsigned kMaxArgs = 1000;
232 char** arg_array() { return exec_args_; } 232 char** arg_array() { return exec_args_; }
233 char* arg0() { return exec_args_[0]; } 233 char* arg0() { return exec_args_[0]; }
234 234
235 private: 235 private:
236 char* exec_args_[kMaxArgs + 1]; 236 char* exec_args_[kMaxArgs + 1];
237 }; 237 };
238 238
239 239
240 // Gets the optional timeouts from the arguments to the system() call. 240 // Gets the optional timeouts from the arguments to the system() call.
241 static bool GetTimeouts(const Arguments& args, 241 static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args,
242 int* read_timeout, 242 int* read_timeout,
243 int* total_timeout) { 243 int* total_timeout) {
244 if (args.Length() > 3) { 244 if (args.Length() > 3) {
245 if (args[3]->IsNumber()) { 245 if (args[3]->IsNumber()) {
246 *total_timeout = args[3]->Int32Value(); 246 *total_timeout = args[3]->Int32Value();
247 } else { 247 } else {
248 ThrowException(String::New("system: Argument 4 must be a number")); 248 ThrowException(String::New("system: Argument 4 must be a number"));
249 return false; 249 return false;
250 } 250 }
251 } 251 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 return false; 441 return false;
442 } 442 }
443 443
444 #endif // No waitid call. 444 #endif // No waitid call.
445 445
446 return true; 446 return true;
447 } 447 }
448 448
449 449
450 // Implementation of the system() function (see d8.h for details). 450 // Implementation of the system() function (see d8.h for details).
451 Handle<Value> Shell::System(const Arguments& args) { 451 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) {
452 HandleScope scope(args.GetIsolate()); 452 HandleScope scope(args.GetIsolate());
453 int read_timeout = -1; 453 int read_timeout = -1;
454 int total_timeout = -1; 454 int total_timeout = -1;
455 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return v8::Undefined(); 455 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return;
456 Handle<Array> command_args; 456 Handle<Array> command_args;
457 if (args.Length() > 1) { 457 if (args.Length() > 1) {
458 if (!args[1]->IsArray()) { 458 if (!args[1]->IsArray()) {
459 return ThrowException(String::New("system: Argument 2 must be an array")); 459 ThrowException(String::New("system: Argument 2 must be an array"));
460 return;
460 } 461 }
461 command_args = Handle<Array>::Cast(args[1]); 462 command_args = Handle<Array>::Cast(args[1]);
462 } else { 463 } else {
463 command_args = Array::New(0); 464 command_args = Array::New(0);
464 } 465 }
465 if (command_args->Length() > ExecArgs::kMaxArgs) { 466 if (command_args->Length() > ExecArgs::kMaxArgs) {
466 return ThrowException(String::New("Too many arguments to system()")); 467 ThrowException(String::New("Too many arguments to system()"));
468 return;
467 } 469 }
468 if (args.Length() < 1) { 470 if (args.Length() < 1) {
469 return ThrowException(String::New("Too few arguments to system()")); 471 ThrowException(String::New("Too few arguments to system()"));
472 return;
470 } 473 }
471 474
472 struct timeval start_time; 475 struct timeval start_time;
473 gettimeofday(&start_time, NULL); 476 gettimeofday(&start_time, NULL);
474 477
475 ExecArgs exec_args; 478 ExecArgs exec_args;
476 if (!exec_args.Init(args[0], command_args)) { 479 if (!exec_args.Init(args[0], command_args)) {
477 return v8::Undefined(); 480 return;
478 } 481 }
479 int exec_error_fds[2]; 482 int exec_error_fds[2];
480 int stdout_fds[2]; 483 int stdout_fds[2];
481 484
482 if (pipe(exec_error_fds) != 0) { 485 if (pipe(exec_error_fds) != 0) {
483 return ThrowException(String::New("pipe syscall failed.")); 486 ThrowException(String::New("pipe syscall failed."));
487 return;
484 } 488 }
485 if (pipe(stdout_fds) != 0) { 489 if (pipe(stdout_fds) != 0) {
486 return ThrowException(String::New("pipe syscall failed.")); 490 ThrowException(String::New("pipe syscall failed."));
491 return;
487 } 492 }
488 493
489 pid_t pid = fork(); 494 pid_t pid = fork();
490 if (pid == 0) { // Child process. 495 if (pid == 0) { // Child process.
491 ExecSubprocess(exec_error_fds, stdout_fds, exec_args); 496 ExecSubprocess(exec_error_fds, stdout_fds, exec_args);
492 exit(1); 497 exit(1);
493 } 498 }
494 499
495 // Parent process. Ensure that we clean up if we exit this function early. 500 // Parent process. Ensure that we clean up if we exit this function early.
496 ZombieProtector child_waiter(pid); 501 ZombieProtector child_waiter(pid);
497 close(exec_error_fds[kWriteFD]); 502 close(exec_error_fds[kWriteFD]);
498 close(stdout_fds[kWriteFD]); 503 close(stdout_fds[kWriteFD]);
499 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]); 504 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
500 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]); 505 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
501 506
502 if (!ChildLaunchedOK(exec_error_fds)) return v8::Undefined(); 507 if (!ChildLaunchedOK(exec_error_fds)) return;
503 508
504 Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD], 509 Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD],
505 start_time, 510 start_time,
506 read_timeout, 511 read_timeout,
507 total_timeout); 512 total_timeout);
508 if (accumulator->IsUndefined()) { 513 if (accumulator->IsUndefined()) {
509 kill(pid, SIGINT); // On timeout, kill the subprocess. 514 kill(pid, SIGINT); // On timeout, kill the subprocess.
510 return accumulator; 515 args.GetReturnValue().Set(accumulator);
516 return;
511 } 517 }
512 518
513 if (!WaitForChild(pid, 519 if (!WaitForChild(pid,
514 child_waiter, 520 child_waiter,
515 start_time, 521 start_time,
516 read_timeout, 522 read_timeout,
517 total_timeout)) { 523 total_timeout)) {
518 return v8::Undefined(); 524 return;
519 } 525 }
520 526
521 return scope.Close(accumulator); 527 args.GetReturnValue().Set(accumulator);
522 } 528 }
523 529
524 530
525 Handle<Value> Shell::ChangeDirectory(const Arguments& args) { 531 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
526 if (args.Length() != 1) { 532 if (args.Length() != 1) {
527 const char* message = "chdir() takes one argument"; 533 const char* message = "chdir() takes one argument";
528 return ThrowException(String::New(message)); 534 ThrowException(String::New(message));
535 return;
529 } 536 }
530 String::Utf8Value directory(args[0]); 537 String::Utf8Value directory(args[0]);
531 if (*directory == NULL) { 538 if (*directory == NULL) {
532 const char* message = "os.chdir(): String conversion of argument failed."; 539 const char* message = "os.chdir(): String conversion of argument failed.";
533 return ThrowException(String::New(message)); 540 ThrowException(String::New(message));
541 return;
534 } 542 }
535 if (chdir(*directory) != 0) { 543 if (chdir(*directory) != 0) {
536 return ThrowException(String::New(strerror(errno))); 544 ThrowException(String::New(strerror(errno)));
545 return;
537 } 546 }
538 return v8::Undefined();
539 } 547 }
540 548
541 549
542 Handle<Value> Shell::SetUMask(const Arguments& args) { 550 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
543 if (args.Length() != 1) { 551 if (args.Length() != 1) {
544 const char* message = "umask() takes one argument"; 552 const char* message = "umask() takes one argument";
545 return ThrowException(String::New(message)); 553 ThrowException(String::New(message));
554 return;
546 } 555 }
547 if (args[0]->IsNumber()) { 556 if (args[0]->IsNumber()) {
548 mode_t mask = args[0]->Int32Value(); 557 mode_t mask = args[0]->Int32Value();
549 int previous = umask(mask); 558 int previous = umask(mask);
550 return Number::New(previous); 559 args.GetReturnValue().Set(previous);
560 return;
551 } else { 561 } else {
552 const char* message = "umask() argument must be numeric"; 562 const char* message = "umask() argument must be numeric";
553 return ThrowException(String::New(message)); 563 ThrowException(String::New(message));
564 return;
554 } 565 }
555 } 566 }
556 567
557 568
558 static bool CheckItsADirectory(char* directory) { 569 static bool CheckItsADirectory(char* directory) {
559 struct stat stat_buf; 570 struct stat stat_buf;
560 int stat_result = stat(directory, &stat_buf); 571 int stat_result = stat(directory, &stat_buf);
561 if (stat_result != 0) { 572 if (stat_result != 0) {
562 ThrowException(String::New(strerror(errno))); 573 ThrowException(String::New(strerror(errno)));
563 return false; 574 return false;
(...skipping 27 matching lines...) Expand all
591 } 602 }
592 ThrowException(String::New(strerror(errno))); 603 ThrowException(String::New(strerror(errno)));
593 return false; 604 return false;
594 } else { 605 } else {
595 ThrowException(String::New(strerror(errno))); 606 ThrowException(String::New(strerror(errno)));
596 return false; 607 return false;
597 } 608 }
598 } 609 }
599 610
600 611
601 Handle<Value> Shell::MakeDirectory(const Arguments& args) { 612 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
602 mode_t mask = 0777; 613 mode_t mask = 0777;
603 if (args.Length() == 2) { 614 if (args.Length() == 2) {
604 if (args[1]->IsNumber()) { 615 if (args[1]->IsNumber()) {
605 mask = args[1]->Int32Value(); 616 mask = args[1]->Int32Value();
606 } else { 617 } else {
607 const char* message = "mkdirp() second argument must be numeric"; 618 const char* message = "mkdirp() second argument must be numeric";
608 return ThrowException(String::New(message)); 619 ThrowException(String::New(message));
620 return;
609 } 621 }
610 } else if (args.Length() != 1) { 622 } else if (args.Length() != 1) {
611 const char* message = "mkdirp() takes one or two arguments"; 623 const char* message = "mkdirp() takes one or two arguments";
612 return ThrowException(String::New(message)); 624 ThrowException(String::New(message));
625 return;
613 } 626 }
614 String::Utf8Value directory(args[0]); 627 String::Utf8Value directory(args[0]);
615 if (*directory == NULL) { 628 if (*directory == NULL) {
616 const char* message = "os.mkdirp(): String conversion of argument failed."; 629 const char* message = "os.mkdirp(): String conversion of argument failed.";
617 return ThrowException(String::New(message)); 630 ThrowException(String::New(message));
631 return;
618 } 632 }
619 mkdirp(*directory, mask); 633 mkdirp(*directory, mask);
620 return v8::Undefined();
621 } 634 }
622 635
623 636
624 Handle<Value> Shell::RemoveDirectory(const Arguments& args) { 637 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
625 if (args.Length() != 1) { 638 if (args.Length() != 1) {
626 const char* message = "rmdir() takes one or two arguments"; 639 const char* message = "rmdir() takes one or two arguments";
627 return ThrowException(String::New(message)); 640 ThrowException(String::New(message));
641 return;
628 } 642 }
629 String::Utf8Value directory(args[0]); 643 String::Utf8Value directory(args[0]);
630 if (*directory == NULL) { 644 if (*directory == NULL) {
631 const char* message = "os.rmdir(): String conversion of argument failed."; 645 const char* message = "os.rmdir(): String conversion of argument failed.";
632 return ThrowException(String::New(message)); 646 ThrowException(String::New(message));
647 return;
633 } 648 }
634 rmdir(*directory); 649 rmdir(*directory);
635 return v8::Undefined();
636 } 650 }
637 651
638 652
639 Handle<Value> Shell::SetEnvironment(const Arguments& args) { 653 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
640 if (args.Length() != 2) { 654 if (args.Length() != 2) {
641 const char* message = "setenv() takes two arguments"; 655 const char* message = "setenv() takes two arguments";
642 return ThrowException(String::New(message)); 656 ThrowException(String::New(message));
657 return;
643 } 658 }
644 String::Utf8Value var(args[0]); 659 String::Utf8Value var(args[0]);
645 String::Utf8Value value(args[1]); 660 String::Utf8Value value(args[1]);
646 if (*var == NULL) { 661 if (*var == NULL) {
647 const char* message = 662 const char* message =
648 "os.setenv(): String conversion of variable name failed."; 663 "os.setenv(): String conversion of variable name failed.";
649 return ThrowException(String::New(message)); 664 ThrowException(String::New(message));
665 return;
650 } 666 }
651 if (*value == NULL) { 667 if (*value == NULL) {
652 const char* message = 668 const char* message =
653 "os.setenv(): String conversion of variable contents failed."; 669 "os.setenv(): String conversion of variable contents failed.";
654 return ThrowException(String::New(message)); 670 ThrowException(String::New(message));
671 return;
655 } 672 }
656 setenv(*var, *value, 1); 673 setenv(*var, *value, 1);
657 return v8::Undefined();
658 } 674 }
659 675
660 676
661 Handle<Value> Shell::UnsetEnvironment(const Arguments& args) { 677 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
662 if (args.Length() != 1) { 678 if (args.Length() != 1) {
663 const char* message = "unsetenv() takes one argument"; 679 const char* message = "unsetenv() takes one argument";
664 return ThrowException(String::New(message)); 680 ThrowException(String::New(message));
681 return;
665 } 682 }
666 String::Utf8Value var(args[0]); 683 String::Utf8Value var(args[0]);
667 if (*var == NULL) { 684 if (*var == NULL) {
668 const char* message = 685 const char* message =
669 "os.setenv(): String conversion of variable name failed."; 686 "os.setenv(): String conversion of variable name failed.";
670 return ThrowException(String::New(message)); 687 ThrowException(String::New(message));
688 return;
671 } 689 }
672 unsetenv(*var); 690 unsetenv(*var);
673 return v8::Undefined();
674 } 691 }
675 692
676 693
677 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) { 694 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) {
678 os_templ->Set(String::New("system"), FunctionTemplate::New(System)); 695 os_templ->Set(String::New("system"), FunctionTemplate::New(System));
679 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory)); 696 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory));
680 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment)); 697 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment));
681 os_templ->Set(String::New("unsetenv"), 698 os_templ->Set(String::New("unsetenv"),
682 FunctionTemplate::New(UnsetEnvironment)); 699 FunctionTemplate::New(UnsetEnvironment));
683 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask)); 700 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask));
684 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory)); 701 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory));
685 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory)); 702 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory));
686 } 703 }
687 704
688 } // namespace v8 705 } // namespace v8
OLDNEW
« no previous file with comments | « src/d8.cc ('k') | src/extensions/externalize-string-extension.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698