OLD | NEW |
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 v8::FunctionCallbackInfo<v8::Value>& 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 args.GetIsolate()->ThrowException( |
| 249 String::New("system: Argument 4 must be a number")); |
249 return false; | 250 return false; |
250 } | 251 } |
251 } | 252 } |
252 if (args.Length() > 2) { | 253 if (args.Length() > 2) { |
253 if (args[2]->IsNumber()) { | 254 if (args[2]->IsNumber()) { |
254 *read_timeout = args[2]->Int32Value(); | 255 *read_timeout = args[2]->Int32Value(); |
255 } else { | 256 } else { |
256 ThrowException(String::New("system: Argument 3 must be a number")); | 257 args.GetIsolate()->ThrowException( |
| 258 String::New("system: Argument 3 must be a number")); |
257 return false; | 259 return false; |
258 } | 260 } |
259 } | 261 } |
260 return true; | 262 return true; |
261 } | 263 } |
262 | 264 |
263 | 265 |
264 static const int kReadFD = 0; | 266 static const int kReadFD = 0; |
265 static const int kWriteFD = 1; | 267 static const int kWriteFD = 1; |
266 | 268 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 | 451 |
450 // Implementation of the system() function (see d8.h for details). | 452 // Implementation of the system() function (see d8.h for details). |
451 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) { | 453 void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) { |
452 HandleScope scope(args.GetIsolate()); | 454 HandleScope scope(args.GetIsolate()); |
453 int read_timeout = -1; | 455 int read_timeout = -1; |
454 int total_timeout = -1; | 456 int total_timeout = -1; |
455 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return; | 457 if (!GetTimeouts(args, &read_timeout, &total_timeout)) return; |
456 Handle<Array> command_args; | 458 Handle<Array> command_args; |
457 if (args.Length() > 1) { | 459 if (args.Length() > 1) { |
458 if (!args[1]->IsArray()) { | 460 if (!args[1]->IsArray()) { |
459 ThrowException(String::New("system: Argument 2 must be an array")); | 461 args.GetIsolate()->ThrowException( |
| 462 String::New("system: Argument 2 must be an array")); |
460 return; | 463 return; |
461 } | 464 } |
462 command_args = Handle<Array>::Cast(args[1]); | 465 command_args = Handle<Array>::Cast(args[1]); |
463 } else { | 466 } else { |
464 command_args = Array::New(0); | 467 command_args = Array::New(0); |
465 } | 468 } |
466 if (command_args->Length() > ExecArgs::kMaxArgs) { | 469 if (command_args->Length() > ExecArgs::kMaxArgs) { |
467 ThrowException(String::New("Too many arguments to system()")); | 470 args.GetIsolate()->ThrowException( |
| 471 String::New("Too many arguments to system()")); |
468 return; | 472 return; |
469 } | 473 } |
470 if (args.Length() < 1) { | 474 if (args.Length() < 1) { |
471 ThrowException(String::New("Too few arguments to system()")); | 475 args.GetIsolate()->ThrowException( |
| 476 String::New("Too few arguments to system()")); |
472 return; | 477 return; |
473 } | 478 } |
474 | 479 |
475 struct timeval start_time; | 480 struct timeval start_time; |
476 gettimeofday(&start_time, NULL); | 481 gettimeofday(&start_time, NULL); |
477 | 482 |
478 ExecArgs exec_args; | 483 ExecArgs exec_args; |
479 if (!exec_args.Init(args[0], command_args)) { | 484 if (!exec_args.Init(args[0], command_args)) { |
480 return; | 485 return; |
481 } | 486 } |
482 int exec_error_fds[2]; | 487 int exec_error_fds[2]; |
483 int stdout_fds[2]; | 488 int stdout_fds[2]; |
484 | 489 |
485 if (pipe(exec_error_fds) != 0) { | 490 if (pipe(exec_error_fds) != 0) { |
486 ThrowException(String::New("pipe syscall failed.")); | 491 args.GetIsolate()->ThrowException( |
| 492 String::New("pipe syscall failed.")); |
487 return; | 493 return; |
488 } | 494 } |
489 if (pipe(stdout_fds) != 0) { | 495 if (pipe(stdout_fds) != 0) { |
490 ThrowException(String::New("pipe syscall failed.")); | 496 args.GetIsolate()->ThrowException( |
| 497 String::New("pipe syscall failed.")); |
491 return; | 498 return; |
492 } | 499 } |
493 | 500 |
494 pid_t pid = fork(); | 501 pid_t pid = fork(); |
495 if (pid == 0) { // Child process. | 502 if (pid == 0) { // Child process. |
496 ExecSubprocess(exec_error_fds, stdout_fds, exec_args); | 503 ExecSubprocess(exec_error_fds, stdout_fds, exec_args); |
497 exit(1); | 504 exit(1); |
498 } | 505 } |
499 | 506 |
500 // Parent process. Ensure that we clean up if we exit this function early. | 507 // Parent process. Ensure that we clean up if we exit this function early. |
(...skipping 23 matching lines...) Expand all Loading... |
524 return; | 531 return; |
525 } | 532 } |
526 | 533 |
527 args.GetReturnValue().Set(accumulator); | 534 args.GetReturnValue().Set(accumulator); |
528 } | 535 } |
529 | 536 |
530 | 537 |
531 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 538 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
532 if (args.Length() != 1) { | 539 if (args.Length() != 1) { |
533 const char* message = "chdir() takes one argument"; | 540 const char* message = "chdir() takes one argument"; |
534 ThrowException(String::New(message)); | 541 args.GetIsolate()->ThrowException(String::New(message)); |
535 return; | 542 return; |
536 } | 543 } |
537 String::Utf8Value directory(args[0]); | 544 String::Utf8Value directory(args[0]); |
538 if (*directory == NULL) { | 545 if (*directory == NULL) { |
539 const char* message = "os.chdir(): String conversion of argument failed."; | 546 const char* message = "os.chdir(): String conversion of argument failed."; |
540 ThrowException(String::New(message)); | 547 args.GetIsolate()->ThrowException(String::New(message)); |
541 return; | 548 return; |
542 } | 549 } |
543 if (chdir(*directory) != 0) { | 550 if (chdir(*directory) != 0) { |
544 ThrowException(String::New(strerror(errno))); | 551 args.GetIsolate()->ThrowException(String::New(strerror(errno))); |
545 return; | 552 return; |
546 } | 553 } |
547 } | 554 } |
548 | 555 |
549 | 556 |
550 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) { | 557 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) { |
551 if (args.Length() != 1) { | 558 if (args.Length() != 1) { |
552 const char* message = "umask() takes one argument"; | 559 const char* message = "umask() takes one argument"; |
553 ThrowException(String::New(message)); | 560 args.GetIsolate()->ThrowException(String::New(message)); |
554 return; | 561 return; |
555 } | 562 } |
556 if (args[0]->IsNumber()) { | 563 if (args[0]->IsNumber()) { |
557 mode_t mask = args[0]->Int32Value(); | 564 mode_t mask = args[0]->Int32Value(); |
558 int previous = umask(mask); | 565 int previous = umask(mask); |
559 args.GetReturnValue().Set(previous); | 566 args.GetReturnValue().Set(previous); |
560 return; | 567 return; |
561 } else { | 568 } else { |
562 const char* message = "umask() argument must be numeric"; | 569 const char* message = "umask() argument must be numeric"; |
563 ThrowException(String::New(message)); | 570 args.GetIsolate()->ThrowException(String::New(message)); |
564 return; | 571 return; |
565 } | 572 } |
566 } | 573 } |
567 | 574 |
568 | 575 |
569 static bool CheckItsADirectory(char* directory) { | 576 static bool CheckItsADirectory(char* directory) { |
570 struct stat stat_buf; | 577 struct stat stat_buf; |
571 int stat_result = stat(directory, &stat_buf); | 578 int stat_result = stat(directory, &stat_buf); |
572 if (stat_result != 0) { | 579 if (stat_result != 0) { |
573 ThrowException(String::New(strerror(errno))); | 580 ThrowException(String::New(strerror(errno))); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 } | 616 } |
610 | 617 |
611 | 618 |
612 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 619 void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
613 mode_t mask = 0777; | 620 mode_t mask = 0777; |
614 if (args.Length() == 2) { | 621 if (args.Length() == 2) { |
615 if (args[1]->IsNumber()) { | 622 if (args[1]->IsNumber()) { |
616 mask = args[1]->Int32Value(); | 623 mask = args[1]->Int32Value(); |
617 } else { | 624 } else { |
618 const char* message = "mkdirp() second argument must be numeric"; | 625 const char* message = "mkdirp() second argument must be numeric"; |
619 ThrowException(String::New(message)); | 626 args.GetIsolate()->ThrowException(String::New(message)); |
620 return; | 627 return; |
621 } | 628 } |
622 } else if (args.Length() != 1) { | 629 } else if (args.Length() != 1) { |
623 const char* message = "mkdirp() takes one or two arguments"; | 630 const char* message = "mkdirp() takes one or two arguments"; |
624 ThrowException(String::New(message)); | 631 args.GetIsolate()->ThrowException(String::New(message)); |
625 return; | 632 return; |
626 } | 633 } |
627 String::Utf8Value directory(args[0]); | 634 String::Utf8Value directory(args[0]); |
628 if (*directory == NULL) { | 635 if (*directory == NULL) { |
629 const char* message = "os.mkdirp(): String conversion of argument failed."; | 636 const char* message = "os.mkdirp(): String conversion of argument failed."; |
630 ThrowException(String::New(message)); | 637 args.GetIsolate()->ThrowException(String::New(message)); |
631 return; | 638 return; |
632 } | 639 } |
633 mkdirp(*directory, mask); | 640 mkdirp(*directory, mask); |
634 } | 641 } |
635 | 642 |
636 | 643 |
637 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 644 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
638 if (args.Length() != 1) { | 645 if (args.Length() != 1) { |
639 const char* message = "rmdir() takes one or two arguments"; | 646 const char* message = "rmdir() takes one or two arguments"; |
640 ThrowException(String::New(message)); | 647 args.GetIsolate()->ThrowException(String::New(message)); |
641 return; | 648 return; |
642 } | 649 } |
643 String::Utf8Value directory(args[0]); | 650 String::Utf8Value directory(args[0]); |
644 if (*directory == NULL) { | 651 if (*directory == NULL) { |
645 const char* message = "os.rmdir(): String conversion of argument failed."; | 652 const char* message = "os.rmdir(): String conversion of argument failed."; |
646 ThrowException(String::New(message)); | 653 args.GetIsolate()->ThrowException(String::New(message)); |
647 return; | 654 return; |
648 } | 655 } |
649 rmdir(*directory); | 656 rmdir(*directory); |
650 } | 657 } |
651 | 658 |
652 | 659 |
653 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { | 660 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { |
654 if (args.Length() != 2) { | 661 if (args.Length() != 2) { |
655 const char* message = "setenv() takes two arguments"; | 662 const char* message = "setenv() takes two arguments"; |
656 ThrowException(String::New(message)); | 663 args.GetIsolate()->ThrowException(String::New(message)); |
657 return; | 664 return; |
658 } | 665 } |
659 String::Utf8Value var(args[0]); | 666 String::Utf8Value var(args[0]); |
660 String::Utf8Value value(args[1]); | 667 String::Utf8Value value(args[1]); |
661 if (*var == NULL) { | 668 if (*var == NULL) { |
662 const char* message = | 669 const char* message = |
663 "os.setenv(): String conversion of variable name failed."; | 670 "os.setenv(): String conversion of variable name failed."; |
664 ThrowException(String::New(message)); | 671 args.GetIsolate()->ThrowException(String::New(message)); |
665 return; | 672 return; |
666 } | 673 } |
667 if (*value == NULL) { | 674 if (*value == NULL) { |
668 const char* message = | 675 const char* message = |
669 "os.setenv(): String conversion of variable contents failed."; | 676 "os.setenv(): String conversion of variable contents failed."; |
670 ThrowException(String::New(message)); | 677 args.GetIsolate()->ThrowException(String::New(message)); |
671 return; | 678 return; |
672 } | 679 } |
673 setenv(*var, *value, 1); | 680 setenv(*var, *value, 1); |
674 } | 681 } |
675 | 682 |
676 | 683 |
677 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { | 684 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) { |
678 if (args.Length() != 1) { | 685 if (args.Length() != 1) { |
679 const char* message = "unsetenv() takes one argument"; | 686 const char* message = "unsetenv() takes one argument"; |
680 ThrowException(String::New(message)); | 687 args.GetIsolate()->ThrowException(String::New(message)); |
681 return; | 688 return; |
682 } | 689 } |
683 String::Utf8Value var(args[0]); | 690 String::Utf8Value var(args[0]); |
684 if (*var == NULL) { | 691 if (*var == NULL) { |
685 const char* message = | 692 const char* message = |
686 "os.setenv(): String conversion of variable name failed."; | 693 "os.setenv(): String conversion of variable name failed."; |
687 ThrowException(String::New(message)); | 694 args.GetIsolate()->ThrowException(String::New(message)); |
688 return; | 695 return; |
689 } | 696 } |
690 unsetenv(*var); | 697 unsetenv(*var); |
691 } | 698 } |
692 | 699 |
693 | 700 |
694 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) { | 701 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) { |
695 os_templ->Set(String::New("system"), FunctionTemplate::New(System)); | 702 os_templ->Set(String::New("system"), FunctionTemplate::New(System)); |
696 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory)); | 703 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory)); |
697 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment)); | 704 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment)); |
698 os_templ->Set(String::New("unsetenv"), | 705 os_templ->Set(String::New("unsetenv"), |
699 FunctionTemplate::New(UnsetEnvironment)); | 706 FunctionTemplate::New(UnsetEnvironment)); |
700 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask)); | 707 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask)); |
701 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory)); | 708 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory)); |
702 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory)); | 709 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory)); |
703 } | 710 } |
704 | 711 |
705 } // namespace v8 | 712 } // namespace v8 |
OLD | NEW |