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

Unified Diff: runtime/bin/process_linux.cc

Issue 3007703002: [dart:io] Namespaces for file IO (Closed)
Patch Set: Remove namespace_unsupported.cc Created 3 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/process_fuchsia.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/process_linux.cc
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 2431f0f61652516f78125c52843a4f7439c6e027..03d0bb73e292e38372b782f75a9d3c039f9a5b13 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -18,6 +18,7 @@
#include <unistd.h> // NOLINT
#include "bin/dartutils.h"
+#include "bin/directory.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/lockers.h"
@@ -243,7 +244,8 @@ Monitor* ExitCodeHandler::monitor_ = new Monitor();
class ProcessStarter {
public:
- ProcessStarter(const char* path,
+ ProcessStarter(Namespace* namespc,
+ const char* path,
char* arguments[],
intptr_t arguments_length,
const char* working_directory,
@@ -256,7 +258,8 @@ class ProcessStarter {
intptr_t* id,
intptr_t* exit_event,
char** os_error_message)
- : path_(path),
+ : namespc_(namespc),
+ path_(path),
working_directory_(working_directory),
mode_(mode),
in_(in),
@@ -432,6 +435,25 @@ class ProcessStarter {
}
}
+ // If fexecve() should be used to launch the program, returns the fd to use
+ // in fd and returns true. If execvp should be used, returns false. If there
+ // was an error that should be reported to the caller, sets fd to -1 and
+ // returns true.
+ bool ShouldUseFexecve(int* pathfd) {
+ ASSERT(pathfd != NULL);
+ NamespaceScope ns(namespc_, path_);
+ const intptr_t fd =
+ TEMP_FAILURE_RETRY(openat64(ns.fd(), ns.path(), O_RDONLY));
+ if ((fd == -1) && (errno == ENOENT)) {
+ if (strchr(path_, '/') == NULL) {
+ // There wasn't in the namespace and contained no '/'. Punt to execvp.
+ return false;
+ }
+ }
+ *pathfd = fd;
+ return true;
+ }
+
void ExecProcess() {
if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
ReportChildError();
@@ -446,7 +468,7 @@ class ProcessStarter {
}
if (working_directory_ != NULL &&
- TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1) {
+ !Directory::SetCurrent(namespc_, working_directory_)) {
ReportChildError();
}
@@ -454,8 +476,17 @@ class ProcessStarter {
environ = program_environment_;
}
- VOID_TEMP_FAILURE_RETRY(
- execvp(path_, const_cast<char* const*>(program_arguments_)));
+ int pathfd;
+ if (ShouldUseFexecve(&pathfd)) {
+ if (pathfd == -1) {
+ ReportChildError();
+ }
+ VOID_TEMP_FAILURE_RETRY(fexecve(
+ pathfd, const_cast<char* const*>(program_arguments_), environ));
+ } else {
+ VOID_TEMP_FAILURE_RETRY(
+ execvp(path_, const_cast<char* const*>(program_arguments_)));
+ }
ReportChildError();
}
@@ -497,22 +528,31 @@ class ProcessStarter {
}
if ((working_directory_ != NULL) &&
- (TEMP_FAILURE_RETRY(chdir(working_directory_)) == -1)) {
+ !Directory::SetCurrent(namespc_, working_directory_)) {
ReportChildError();
}
// Report the final PID and do the exec.
ReportPid(getpid()); // getpid cannot fail.
- VOID_TEMP_FAILURE_RETRY(
- execvp(path_, const_cast<char* const*>(program_arguments_)));
+ int pathfd;
+ if (ShouldUseFexecve(&pathfd)) {
+ if (pathfd == -1) {
+ ReportChildError();
+ }
+ VOID_TEMP_FAILURE_RETRY(fexecve(
+ pathfd, const_cast<char* const*>(program_arguments_), environ));
+ } else {
+ VOID_TEMP_FAILURE_RETRY(
+ execvp(path_, const_cast<char* const*>(program_arguments_)));
+ }
ReportChildError();
} else {
- // Exit the intermeiate process.
+ // Exit the intermediate process.
exit(0);
}
}
} else {
- // Exit the intermeiate process.
+ // Exit the intermediate process.
exit(0);
}
}
@@ -717,6 +757,7 @@ class ProcessStarter {
char** program_arguments_;
char** program_environment_;
+ Namespace* namespc_;
const char* path_;
const char* working_directory_;
ProcessStartMode mode_;
@@ -731,7 +772,8 @@ class ProcessStarter {
DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
};
-int Process::Start(const char* path,
+int Process::Start(Namespace* namespc,
+ const char* path,
char* arguments[],
intptr_t arguments_length,
const char* working_directory,
@@ -744,9 +786,9 @@ int Process::Start(const char* path,
intptr_t* id,
intptr_t* exit_event,
char** os_error_message) {
- ProcessStarter starter(path, arguments, arguments_length, working_directory,
- environment, environment_length, mode, in, out, err,
- id, exit_event, os_error_message);
+ ProcessStarter starter(namespc, path, arguments, arguments_length,
+ working_directory, environment, environment_length,
+ mode, in, out, err, id, exit_event, os_error_message);
return starter.Start();
}
« 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