diff options
author | bradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-15 23:55:21 +0000 |
---|---|---|
committer | bradchen@google.com <bradchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-15 23:55:21 +0000 |
commit | ca7c456246121d7e17c22181f0a76eb5c79d3ac0 (patch) | |
tree | 0d79285f4e3c0b1e0239225917c976720e9a0096 /base | |
parent | 3c52ba7a44c24fed4cc3991e9ceae0f366323521 (diff) | |
download | chromium_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.h | 6 | ||||
-rw-r--r-- | base/process_util_posix.cc | 11 | ||||
-rw-r--r-- | base/process_util_unittest.cc | 24 |
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) { |