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

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

Issue 3001963002: [dart:io] Namespaces for file IO (Closed)
Patch Set: Fuchsia fix 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_fuchsia.cc ('k') | runtime/bin/process_macos.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_LINUX) 6 #if defined(HOST_OS_LINUX)
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/resource.h> // NOLINT 16 #include <sys/resource.h> // NOLINT
17 #include <sys/wait.h> // NOLINT 17 #include <sys/wait.h> // NOLINT
18 #include <unistd.h> // NOLINT 18 #include <unistd.h> // NOLINT
19 19
20 #include "bin/dartutils.h" 20 #include "bin/dartutils.h"
21 #include "bin/directory.h"
21 #include "bin/fdutils.h" 22 #include "bin/fdutils.h"
22 #include "bin/file.h" 23 #include "bin/file.h"
23 #include "bin/lockers.h" 24 #include "bin/lockers.h"
24 #include "bin/log.h" 25 #include "bin/log.h"
25 #include "bin/reference_counting.h" 26 #include "bin/reference_counting.h"
26 #include "bin/thread.h" 27 #include "bin/thread.h"
27 28
28 #include "platform/signal_blocker.h" 29 #include "platform/signal_blocker.h"
29 #include "platform/utils.h" 30 #include "platform/utils.h"
30 31
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler); 237 DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
237 }; 238 };
238 239
239 bool ExitCodeHandler::running_ = false; 240 bool ExitCodeHandler::running_ = false;
240 int ExitCodeHandler::process_count_ = 0; 241 int ExitCodeHandler::process_count_ = 0;
241 bool ExitCodeHandler::terminate_done_ = false; 242 bool ExitCodeHandler::terminate_done_ = false;
242 Monitor* ExitCodeHandler::monitor_ = new Monitor(); 243 Monitor* ExitCodeHandler::monitor_ = new Monitor();
243 244
244 class ProcessStarter { 245 class ProcessStarter {
245 public: 246 public:
246 ProcessStarter(const char* path, 247 ProcessStarter(Namespace* namespc,
248 const char* path,
247 char* arguments[], 249 char* arguments[],
248 intptr_t arguments_length, 250 intptr_t arguments_length,
249 const char* working_directory, 251 const char* working_directory,
250 char* environment[], 252 char* environment[],
251 intptr_t environment_length, 253 intptr_t environment_length,
252 ProcessStartMode mode, 254 ProcessStartMode mode,
253 intptr_t* in, 255 intptr_t* in,
254 intptr_t* out, 256 intptr_t* out,
255 intptr_t* err, 257 intptr_t* err,
256 intptr_t* id, 258 intptr_t* id,
257 intptr_t* exit_event, 259 intptr_t* exit_event,
258 char** os_error_message) 260 char** os_error_message)
259 : path_(path), 261 : namespc_(namespc),
262 path_(path),
260 working_directory_(working_directory), 263 working_directory_(working_directory),
261 mode_(mode), 264 mode_(mode),
262 in_(in), 265 in_(in),
263 out_(out), 266 out_(out),
264 err_(err), 267 err_(err),
265 id_(id), 268 id_(id),
266 exit_event_(exit_event), 269 exit_event_(exit_event),
267 os_error_message_(os_error_message) { 270 os_error_message_(os_error_message) {
268 read_in_[0] = -1; 271 read_in_[0] = -1;
269 read_in_[1] = -1; 272 read_in_[1] = -1;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 perror("Failed receiving notification message"); 428 perror("Failed receiving notification message");
426 exit(1); 429 exit(1);
427 } 430 }
428 if (mode_ == kNormal) { 431 if (mode_ == kNormal) {
429 ExecProcess(); 432 ExecProcess();
430 } else { 433 } else {
431 ExecDetachedProcess(); 434 ExecDetachedProcess();
432 } 435 }
433 } 436 }
434 437
438 // If fexecve() should be used to launch the program, returns the fd to use
439 // in fd and returns true. If execvp should be used, returns false. If there
440 // was an error that should be reported to the caller, sets fd to -1 and
441 // returns true.
442 bool ShouldUseFexecve(int* pathfd) {
443 ASSERT(pathfd != NULL);
444 NamespaceScope ns(namespc_, path_);
445 const intptr_t fd =
446 TEMP_FAILURE_RETRY(openat64(ns.fd(), ns.path(), O_RDONLY));
447 if ((fd == -1) && (errno == ENOENT)) {
448 if (strchr(path_, '/') == NULL) {
449 // There wasn't in the namespace and contained no '/'. Punt to execvp.
450 return false;
451 }
452 }
453 *pathfd = fd;
454 return true;
455 }
456
435 void ExecProcess() { 457 void ExecProcess() {
436 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) { 458 if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
437 ReportChildError(); 459 ReportChildError();
438 } 460 }
439 461
440 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) { 462 if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
441 ReportChildError(); 463 ReportChildError();
442 } 464 }
443 465
444 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) { 466 if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
445 ReportChildError(); 467 ReportChildError();
446 } 468 }
447 469
448 if (working_directory_ != NULL && 470 if (working_directory_ != NULL &&
449 TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) { 471 !Directory::SetCurrent(namespc_, working_directory_)) {
450 ReportChildError(); 472 ReportChildError();
451 } 473 }
452 474
453 if (program_environment_ != NULL) { 475 if (program_environment_ != NULL) {
454 environ = program_environment_; 476 environ = program_environment_;
455 } 477 }
456 478
457 VOID_TEMP_FAILURE_RETRY( 479 int pathfd;
458 execvp(path_, const_cast<char* const*>(program_arguments_))); 480 if (ShouldUseFexecve(&pathfd)) {
481 if (pathfd == -1) {
482 ReportChildError();
483 }
484 VOID_TEMP_FAILURE_RETRY(fexecve(
485 pathfd, const_cast<char* const*>(program_arguments_), environ));
486 } else {
487 VOID_TEMP_FAILURE_RETRY(
488 execvp(path_, const_cast<char* const*>(program_arguments_)));
489 }
459 490
460 ReportChildError(); 491 ReportChildError();
461 } 492 }
462 493
463 void ExecDetachedProcess() { 494 void ExecDetachedProcess() {
464 if (mode_ == kDetached) { 495 if (mode_ == kDetached) {
465 ASSERT(write_out_[0] == -1); 496 ASSERT(write_out_[0] == -1);
466 ASSERT(write_out_[1] == -1); 497 ASSERT(write_out_[1] == -1);
467 ASSERT(read_err_[0] == -1); 498 ASSERT(read_err_[0] == -1);
468 ASSERT(read_err_[1] == -1); 499 ASSERT(read_err_[1] == -1);
(...skipping 21 matching lines...) Expand all
490 if (pid < 0) { 521 if (pid < 0) {
491 ReportChildError(); 522 ReportChildError();
492 } else if (pid == 0) { 523 } else if (pid == 0) {
493 if (mode_ == kDetached) { 524 if (mode_ == kDetached) {
494 SetupDetached(); 525 SetupDetached();
495 } else { 526 } else {
496 SetupDetachedWithStdio(); 527 SetupDetachedWithStdio();
497 } 528 }
498 529
499 if ((working_directory_ != NULL) && 530 if ((working_directory_ != NULL) &&
500 (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) { 531 !Directory::SetCurrent(namespc_, working_directory_)) {
501 ReportChildError(); 532 ReportChildError();
502 } 533 }
503 534
504 // Report the final PID and do the exec. 535 // Report the final PID and do the exec.
505 ReportPid(getpid()); // getpid cannot fail. 536 ReportPid(getpid()); // getpid cannot fail.
506 VOID_TEMP_FAILURE_RETRY( 537 int pathfd;
507 execvp(path_, const_cast<char* const*>(program_arguments_))); 538 if (ShouldUseFexecve(&pathfd)) {
539 if (pathfd == -1) {
540 ReportChildError();
541 }
542 VOID_TEMP_FAILURE_RETRY(fexecve(
543 pathfd, const_cast<char* const*>(program_arguments_), environ));
544 } else {
545 VOID_TEMP_FAILURE_RETRY(
546 execvp(path_, const_cast<char* const*>(program_arguments_)));
547 }
508 ReportChildError(); 548 ReportChildError();
509 } else { 549 } else {
510 // Exit the intermeiate process. 550 // Exit the intermediate process.
511 exit(0); 551 exit(0);
512 } 552 }
513 } 553 }
514 } else { 554 } else {
515 // Exit the intermeiate process. 555 // Exit the intermediate process.
516 exit(0); 556 exit(0);
517 } 557 }
518 } 558 }
519 559
520 int RegisterProcess(pid_t pid) { 560 int RegisterProcess(pid_t pid) {
521 int result; 561 int result;
522 int event_fds[2]; 562 int event_fds[2];
523 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC)); 563 result = TEMP_FAILURE_RETRY(pipe2(event_fds, O_CLOEXEC));
524 if (result < 0) { 564 if (result < 0) {
525 return CleanupAndReturnError(); 565 return CleanupAndReturnError();
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 } 750 }
711 751
712 int read_in_[2]; // Pipe for stdout to child process. 752 int read_in_[2]; // Pipe for stdout to child process.
713 int read_err_[2]; // Pipe for stderr to child process. 753 int read_err_[2]; // Pipe for stderr to child process.
714 int write_out_[2]; // Pipe for stdin to child process. 754 int write_out_[2]; // Pipe for stdin to child process.
715 int exec_control_[2]; // Pipe to get the result from exec. 755 int exec_control_[2]; // Pipe to get the result from exec.
716 756
717 char** program_arguments_; 757 char** program_arguments_;
718 char** program_environment_; 758 char** program_environment_;
719 759
760 Namespace* namespc_;
720 const char* path_; 761 const char* path_;
721 const char* working_directory_; 762 const char* working_directory_;
722 ProcessStartMode mode_; 763 ProcessStartMode mode_;
723 intptr_t* in_; 764 intptr_t* in_;
724 intptr_t* out_; 765 intptr_t* out_;
725 intptr_t* err_; 766 intptr_t* err_;
726 intptr_t* id_; 767 intptr_t* id_;
727 intptr_t* exit_event_; 768 intptr_t* exit_event_;
728 char** os_error_message_; 769 char** os_error_message_;
729 770
730 DISALLOW_ALLOCATION(); 771 DISALLOW_ALLOCATION();
731 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); 772 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
732 }; 773 };
733 774
734 int Process::Start(const char* path, 775 int Process::Start(Namespace* namespc,
776 const char* path,
735 char* arguments[], 777 char* arguments[],
736 intptr_t arguments_length, 778 intptr_t arguments_length,
737 const char* working_directory, 779 const char* working_directory,
738 char* environment[], 780 char* environment[],
739 intptr_t environment_length, 781 intptr_t environment_length,
740 ProcessStartMode mode, 782 ProcessStartMode mode,
741 intptr_t* in, 783 intptr_t* in,
742 intptr_t* out, 784 intptr_t* out,
743 intptr_t* err, 785 intptr_t* err,
744 intptr_t* id, 786 intptr_t* id,
745 intptr_t* exit_event, 787 intptr_t* exit_event,
746 char** os_error_message) { 788 char** os_error_message) {
747 ProcessStarter starter(path, arguments, arguments_length, working_directory, 789 ProcessStarter starter(namespc, path, arguments, arguments_length,
748 environment, environment_length, mode, in, out, err, 790 working_directory, environment, environment_length,
749 id, exit_event, os_error_message); 791 mode, in, out, err, id, exit_event, os_error_message);
750 return starter.Start(); 792 return starter.Start();
751 } 793 }
752 794
753 static bool CloseProcessBuffers(struct pollfd fds[3]) { 795 static bool CloseProcessBuffers(struct pollfd fds[3]) {
754 int e = errno; 796 int e = errno;
755 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd)); 797 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
756 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd)); 798 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
757 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd)); 799 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
758 errno = e; 800 errno = e;
759 return false; 801 return false;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 bzero(&act, sizeof(act)); 1037 bzero(&act, sizeof(act));
996 act.sa_handler = SIG_DFL; 1038 act.sa_handler = SIG_DFL;
997 sigaction(signal, &act, NULL); 1039 sigaction(signal, &act, NULL);
998 } 1040 }
999 } 1041 }
1000 1042
1001 } // namespace bin 1043 } // namespace bin
1002 } // namespace dart 1044 } // namespace dart
1003 1045
1004 #endif // defined(HOST_OS_LINUX) 1046 #endif // defined(HOST_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/process_fuchsia.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698