summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorbradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 23:55:21 +0000
committerbradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 23:55:21 +0000
commitca7c456246121d7e17c22181f0a76eb5c79d3ac0 (patch)
tree0d79285f4e3c0b1e0239225917c976720e9a0096 /base
parent3c52ba7a44c24fed4cc3991e9ceae0f366323521 (diff)
downloadchromium_src-ca7c456246121d7e17c22181f0a76eb5c79d3ac0.zip
chromium_src-ca7c456246121d7e17c22181f0a76eb5c79d3ac0.tar.gz
chromium_src-ca7c456246121d7e17c22181f0a76eb5c79d3ac0.tar.bz2
Add a "clone" option to base/process_util.h:LaunchProcess(). Useful inside Linux sandbox.
BUG=nativeclient:480 TEST=base/process_util_unittest.cc Review URL: http://codereview.chromium.org/7401002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/process_util.h6
-rw-r--r--base/process_util_posix.cc11
-rw-r--r--base/process_util_unittest.cc24
3 files changed, 32 insertions, 9 deletions
diff --git a/base/process_util.h b/base/process_util.h
index 234bb4f..ef1eee8 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -202,7 +202,8 @@ struct LaunchOptions {
start_hidden(false), inherit_handles(false), as_user(NULL),
empty_desktop_name(false)
#else
- environ(NULL), fds_to_remap(NULL), new_process_group(false)
+ environ(NULL), fds_to_remap(NULL), new_process_group(false),
+ clone_flags(0)
#endif
{}
@@ -243,6 +244,9 @@ struct LaunchOptions {
// inheriting the parent's process group. The pgid of the child process
// will be the same as its pid.
bool new_process_group;
+
+ // If non-zero, start the process using clone(), using flags as provided.
+ int clone_flags;
#endif
};
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index 0fc8c0e..3bc4d97 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -541,7 +541,16 @@ bool LaunchProcess(const std::vector<std::string>& argv,
if (options.environ)
new_environ.reset(AlterEnvironment(*options.environ, GetEnvironment()));
- pid = fork();
+ if (options.clone_flags) {
+#if defined(OS_LINUX)
+ pid = syscall(__NR_clone, options.clone_flags, 0, 0, 0);
+#else
+ pid = -1; // hygiene; prevent clang warnings
+ NOTREACHED() << "Tried to use clone() on non-Linux system";
+#endif
+ } else {
+ pid = fork();
+ }
if (pid < 0) {
PLOG(ERROR) << "fork";
return false;
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc
index 5256b37..405beb4 100644
--- a/base/process_util_unittest.cc
+++ b/base/process_util_unittest.cc
@@ -24,6 +24,7 @@
#include <errno.h>
#include <malloc.h>
#include <glib.h>
+#include <sched.h>
#endif
#if defined(OS_POSIX)
#include <dlfcn.h>
@@ -495,7 +496,8 @@ TEST_F(ProcessUtilTest, FDRemapping) {
namespace {
-std::string TestLaunchProcess(const base::environment_vector& env_changes) {
+std::string TestLaunchProcess(const base::environment_vector& env_changes,
+ const int clone_flags) {
std::vector<std::string> args;
base::file_handle_mapping_vector fds_to_remap;
@@ -511,6 +513,7 @@ std::string TestLaunchProcess(const base::environment_vector& env_changes) {
options.wait = true;
options.environ = &env_changes;
options.fds_to_remap = &fds_to_remap;
+ options.clone_flags = clone_flags;
EXPECT_TRUE(base::LaunchProcess(args, options, NULL));
PCHECK(HANDLE_EINTR(close(fds[1])) == 0);
@@ -536,29 +539,36 @@ const char kLargeString[] =
TEST_F(ProcessUtilTest, LaunchProcess) {
base::environment_vector env_changes;
+ const int no_clone_flags = 0;
env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
std::string("bar")));
- EXPECT_EQ("bar\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ("bar\n", TestLaunchProcess(env_changes, no_clone_flags));
env_changes.clear();
EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */));
- EXPECT_EQ("testing\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ("testing\n", TestLaunchProcess(env_changes, no_clone_flags));
env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
std::string("")));
- EXPECT_EQ("\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ("\n", TestLaunchProcess(env_changes, no_clone_flags));
env_changes[0].second = "foo";
- EXPECT_EQ("foo\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ("foo\n", TestLaunchProcess(env_changes, no_clone_flags));
env_changes.clear();
EXPECT_EQ(0, setenv("BASE_TEST", kLargeString, 1 /* override */));
- EXPECT_EQ(std::string(kLargeString) + "\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ(std::string(kLargeString) + "\n",
+ TestLaunchProcess(env_changes, no_clone_flags));
env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
std::string("wibble")));
- EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes));
+ EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, no_clone_flags));
+
+#if defined(OS_LINUX)
+ // test a non-trival value for clone_flags
+ EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, CLONE_FS | SIGCHLD));
+#endif
}
TEST_F(ProcessUtilTest, AlterEnvironment) {