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

Side by Side Diff: runtime/bin/process_android.cc

Issue 3007703002: [dart:io] Namespaces for file IO (Closed)
Patch Set: Remove namespace_unsupported.cc Created 3 years, 3 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
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_fuchsia.cc » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(HOST_OS_ANDROID) 6 #if defined(HOST_OS_ANDROID)
7 7
8 #include "bin/process.h" 8 #include "bin/process.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <poll.h> // NOLINT 12 #include <poll.h> // NOLINT
13 #include <stdio.h> // NOLINT 13 #include <stdio.h> // NOLINT
14 #include <stdlib.h> // NOLINT 14 #include <stdlib.h> // NOLINT
15 #include <string.h> // NOLINT 15 #include <string.h> // NOLINT
16 #include <sys/wait.h> // NOLINT 16 #include <sys/wait.h> // NOLINT
17 #include <unistd.h> // NOLINT 17 #include <unistd.h> // NOLINT
18 18
19 #include "bin/dartutils.h" 19 #include "bin/dartutils.h"
20 #include "bin/directory.h"
20 #include "bin/fdutils.h" 21 #include "bin/fdutils.h"
21 #include "bin/file.h" 22 #include "bin/file.h"
22 #include "bin/lockers.h" 23 #include "bin/lockers.h"
23 #include "bin/log.h" 24 #include "bin/log.h"
25 #include "bin/namespace.h"
24 #include "bin/reference_counting.h" 26 #include "bin/reference_counting.h"
25 #include "bin/thread.h" 27 #include "bin/thread.h"
26 28
27 #include "platform/signal_blocker.h" 29 #include "platform/signal_blocker.h"
28 #include "platform/utils.h" 30 #include "platform/utils.h"
29 31
30 extern char** environ; 32 extern char** environ;
31 33
32 namespace dart { 34 namespace dart {
33 namespace bin { 35 namespace bin {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); 237 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
236 }; 238 };
237 239
238 bool ExitCodeHandler::running_ = false; 240 bool ExitCodeHandler::running_ = false;
239 int ExitCodeHandler::process_count_ = 0; 241 int ExitCodeHandler::process_count_ = 0;
240 bool ExitCodeHandler::terminate_done_ = false; 242 bool ExitCodeHandler::terminate_done_ = false;
241 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 243 Monitor* ExitCodeHandler::monitor_ = new Monitor();
242 244
243 class ProcessStarter { 245 class ProcessStarter {
244 public: 246 public:
245 ProcessStarter(const char* path, 247 ProcessStarter(Namespace* namespc,
248 const char* path,
246 char* arguments[], 249 char* arguments[],
247 intptr_t arguments_length, 250 intptr_t arguments_length,
248 const char* working_directory, 251 const char* working_directory,
249 char* environment[], 252 char* environment[],
250 intptr_t environment_length, 253 intptr_t environment_length,
251 ProcessStartMode mode, 254 ProcessStartMode mode,
252 intptr_t* in, 255 intptr_t* in,
253 intptr_t* out, 256 intptr_t* out,
254 intptr_t* err, 257 intptr_t* err,
255 intptr_t* id, 258 intptr_t* id,
256 intptr_t* exit_event, 259 intptr_t* exit_event,
257 char** os_error_message) 260 char** os_error_message)
258 : path_(path), 261 : namespc_(namespc),
262 path_(path),
259 working_directory_(working_directory), 263 working_directory_(working_directory),
260 mode_(mode), 264 mode_(mode),
261 in_(in), 265 in_(in),
262 out_(out), 266 out_(out),
263 err_(err), 267 err_(err),
264 id_(id), 268 id_(id),
265 exit_event_(exit_event), 269 exit_event_(exit_event),
266 os_error_message_(os_error_message) { 270 os_error_message_(os_error_message) {
267 read_in_[0] = -1; 271 read_in_[0] = -1;
268 read_in_[1] = -1; 272 read_in_[1] = -1;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 perror("Failed receiving notification message"); 428 perror("Failed receiving notification message");
425 exit(1); 429 exit(1);
426 } 430 }
427 if (mode_ == kNormal) { 431 if (mode_ == kNormal) {
428 ExecProcess(); 432 ExecProcess();
429 } else { 433 } else {
430 ExecDetachedProcess(); 434 ExecDetachedProcess();
431 } 435 }
432 } 436 }
433 437
438 const char* ResolvePath() {
439 const char* resolved_path = File::GetCanonicalPath(namespc_, path_);
440 return resolved_path == NULL ? path_ : resolved_path;
441 }
442
434 void ExecProcess() { 443 void ExecProcess() {
435 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 444 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
436 ReportChildError(); 445 ReportChildError();
437 } 446 }
438 447
439 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 448 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
440 ReportChildError(); 449 ReportChildError();
441 } 450 }
442 451
443 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 452 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
444 ReportChildError(); 453 ReportChildError();
445 } 454 }
446 455
447 if (working_directory_ != NULL && 456 if (working_directory_ != NULL &&
448 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 457 !Directory::SetCurrent(namespc_, working_directory_)) {
449 ReportChildError(); 458 ReportChildError();
450 } 459 }
451 460
452 if (program_environment_ != NULL) { 461 if (program_environment_ != NULL) {
453 environ = program_environment_; 462 environ = program_environment_;
454 } 463 }
455 464
465 const char* resolved_path = ResolvePath();
456 VOID_TEMP_FAILURE_RETRY( 466 VOID_TEMP_FAILURE_RETRY(
457 execvp(path_, const_cast<char* const*>(program_arguments_))); 467 execvp(resolved_path, const_cast<char* const*>(program_arguments_)));
458 468
459 ReportChildError(); 469 ReportChildError();
460 } 470 }
461 471
462 void ExecDetachedProcess() { 472 void ExecDetachedProcess() {
463 if (mode_ == kDetached) { 473 if (mode_ == kDetached) {
464 ASSERT(write_out_[0] == -1); 474 ASSERT(write_out_[0] == -1);
465 ASSERT(write_out_[1] == -1); 475 ASSERT(write_out_[1] == -1);
466 ASSERT(read_err_[0] == -1); 476 ASSERT(read_err_[0] == -1);
467 ASSERT(read_err_[1] == -1); 477 ASSERT(read_err_[1] == -1);
(...skipping 21 matching lines...) Expand all
489 if (pid < 0) { 499 if (pid < 0) {
490 ReportChildError(); 500 ReportChildError();
491 } else if (pid == 0) { 501 } else if (pid == 0) {
492 if (mode_ == kDetached) { 502 if (mode_ == kDetached) {
493 SetupDetached(); 503 SetupDetached();
494 } else { 504 } else {
495 SetupDetachedWithStdio(); 505 SetupDetachedWithStdio();
496 } 506 }
497 507
498 if ((working_directory_ != NULL) && 508 if ((working_directory_ != NULL) &&
499 (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) { 509 !Directory::SetCurrent(namespc_, working_directory_)) {
500 ReportChildError(); 510 ReportChildError();
501 } 511 }
502 512
503 // Report the final PID and do the exec. 513 // Report the final PID and do the exec.
504 ReportPid(getpid()); // getpid cannot fail. 514 ReportPid(getpid()); // getpid cannot fail.
505 VOID_TEMP_FAILURE_RETRY( 515 const char* resolved_path = ResolvePath();
506 execvp(path_, const_cast<char* const*>(program_arguments_))); 516 VOID_TEMP_FAILURE_RETRY(execvp(
517 resolved_path, const_cast<char* const*>(program_arguments_)));
507 ReportChildError(); 518 ReportChildError();
508 } else { 519 } else {
509 // Exit the intermediate process. 520 // Exit the intermediate process.
510 exit(0); 521 exit(0);
511 } 522 }
512 } 523 }
513 } else { 524 } else {
514 // Exit the intermediate process. 525 // Exit the intermediate process.
515 exit(0); 526 exit(0);
516 } 527 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 char* error_message = DartUtils::ScopedCString(kBufferSize); 659 char* error_message = DartUtils::ScopedCString(kBufferSize);
649 Utils::StrError(errno, error_message, kBufferSize); 660 Utils::StrError(errno, error_message, kBufferSize);
650 *os_error_message_ = error_message; 661 *os_error_message_ = error_message;
651 } 662 }
652 663
653 void ReportChildError() { 664 void ReportChildError() {
654 // In the case of failure in the child process write the errno and 665 // In the case of failure in the child process write the errno and
655 // the OS error message to the exec control pipe and exit. 666 // the OS error message to the exec control pipe and exit.
656 int child_errno = errno; 667 int child_errno = errno;
657 const int kBufferSize = 1024; 668 const int kBufferSize = 1024;
658 char os_error_message[kBufferSize]; 669 char error_buf[kBufferSize];
659 Utils::StrError(errno, os_error_message, kBufferSize); 670 char* os_error_message = Utils::StrError(errno, error_buf, kBufferSize);
660 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno, 671 int bytes_written = FDUtils::WriteToBlocking(exec_control_[1], &child_errno,
661 sizeof(child_errno)); 672 sizeof(child_errno));
662 if (bytes_written == sizeof(child_errno)) { 673 if (bytes_written == sizeof(child_errno)) {
663 FDUtils::WriteToBlocking(exec_control_[1], os_error_message, 674 FDUtils::WriteToBlocking(exec_control_[1], os_error_message,
664 strlen(os_error_message) + 1); 675 strlen(os_error_message) + 1);
665 } 676 }
666 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); 677 VOID_TEMP_FAILURE_RETRY(close(exec_control_[1]));
667 678
668 // We avoid running through registered atexit() handlers because that is 679 // We avoid running through registered atexit() handlers because that is
669 // unnecessary work. 680 // unnecessary work.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } 720 }
710 721
711 int read_in_[2]; // Pipe for stdout to child process. 722 int read_in_[2]; // Pipe for stdout to child process.
712 int read_err_[2]; // Pipe for stderr to child process. 723 int read_err_[2]; // Pipe for stderr to child process.
713 int write_out_[2]; // Pipe for stdin to child process. 724 int write_out_[2]; // Pipe for stdin to child process.
714 int exec_control_[2]; // Pipe to get the result from exec. 725 int exec_control_[2]; // Pipe to get the result from exec.
715 726
716 char** program_arguments_; 727 char** program_arguments_;
717 char** program_environment_; 728 char** program_environment_;
718 729
730 Namespace* namespc_;
719 const char* path_; 731 const char* path_;
720 const char* working_directory_; 732 const char* working_directory_;
721 ProcessStartMode mode_; 733 ProcessStartMode mode_;
722 intptr_t* in_; 734 intptr_t* in_;
723 intptr_t* out_; 735 intptr_t* out_;
724 intptr_t* err_; 736 intptr_t* err_;
725 intptr_t* id_; 737 intptr_t* id_;
726 intptr_t* exit_event_; 738 intptr_t* exit_event_;
727 char** os_error_message_; 739 char** os_error_message_;
728 740
729 DISALLOW_ALLOCATION(); 741 DISALLOW_ALLOCATION();
730 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); 742 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
731 }; 743 };
732 744
733 int Process::Start(const char* path, 745 int Process::Start(Namespace* namespc,
746 const char* path,
734 char* arguments[], 747 char* arguments[],
735 intptr_t arguments_length, 748 intptr_t arguments_length,
736 const char* working_directory, 749 const char* working_directory,
737 char* environment[], 750 char* environment[],
738 intptr_t environment_length, 751 intptr_t environment_length,
739 ProcessStartMode mode, 752 ProcessStartMode mode,
740 intptr_t* in, 753 intptr_t* in,
741 intptr_t* out, 754 intptr_t* out,
742 intptr_t* err, 755 intptr_t* err,
743 intptr_t* id, 756 intptr_t* id,
744 intptr_t* exit_event, 757 intptr_t* exit_event,
745 char** os_error_message) { 758 char** os_error_message) {
746 ProcessStarter starter(path, arguments, arguments_length, working_directory, 759 ProcessStarter starter(namespc, path, arguments, arguments_length,
747 environment, environment_length, mode, in, out, err, 760 working_directory, environment, environment_length,
748 id, exit_event, os_error_message); 761 mode, in, out, err, id, exit_event, os_error_message);
749 return starter.Start(); 762 return starter.Start();
750 } 763 }
751 764
752 static bool CloseProcessBuffers(struct pollfd fds[3]) { 765 static bool CloseProcessBuffers(struct pollfd fds[3]) {
753 int e = errno; 766 int e = errno;
754 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 767 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
755 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 768 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
756 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 769 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
757 errno = e; 770 errno = e;
758 return false; 771 return false;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 bzero(&act, sizeof(act)); 1010 bzero(&act, sizeof(act));
998 act.sa_handler = SIG_DFL; 1011 act.sa_handler = SIG_DFL;
999 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL)); 1012 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
1000 } 1013 }
1001 } 1014 }
1002 1015
1003 } // namespace bin 1016 } // namespace bin
1004 } // namespace dart 1017 } // namespace dart
1005 1018
1006 #endif // defined(HOST_OS_ANDROID) 1019 #endif // defined(HOST_OS_ANDROID)
OLDNEW
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698