OLD | NEW |
1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <chromeos/process.h> | 5 #include <chromeos/process.h> |
6 | 6 |
7 #include <sys/stat.h> | 7 #include <sys/stat.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <sys/wait.h> | 9 #include <sys/wait.h> |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #include <unistd.h> |
11 | 12 |
12 #include <map> | 13 #include <map> |
13 | 14 |
14 #include <base/eintr_wrapper.h> | 15 #include <base/eintr_wrapper.h> |
15 #include <base/file_util.h> | 16 #include <base/file_util.h> |
16 #include <base/logging.h> | 17 #include <base/logging.h> |
17 #include <base/string_number_conversions.h> | 18 #include <base/string_number_conversions.h> |
18 #include <base/string_util.h> | 19 #include <base/string_util.h> |
19 #include <base/time.h> | 20 #include <base/time.h> |
20 | 21 |
21 namespace chromeos { | 22 namespace chromeos { |
22 | 23 |
23 Process::Process() { | 24 Process::Process() { |
24 } | 25 } |
25 | 26 |
26 Process::~Process() { | 27 Process::~Process() { |
27 } | 28 } |
28 | 29 |
29 bool Process::ProcessExists(pid_t pid) { | 30 bool Process::ProcessExists(pid_t pid) { |
30 return file_util::DirectoryExists(FilePath(StringPrintf("/proc/%d", pid))); | 31 return file_util::DirectoryExists(FilePath(StringPrintf("/proc/%d", pid))); |
31 } | 32 } |
32 | 33 |
33 ProcessImpl::ProcessImpl() : pid_(0) { | 34 ProcessImpl::ProcessImpl() : pid_(0), uid_(-1), gid_(-1) { |
34 } | 35 } |
35 | 36 |
36 ProcessImpl::~ProcessImpl() { | 37 ProcessImpl::~ProcessImpl() { |
37 Reset(0); | 38 Reset(0); |
38 } | 39 } |
39 | 40 |
40 void ProcessImpl::AddArg(const std::string& arg) { | 41 void ProcessImpl::AddArg(const std::string& arg) { |
41 arguments_.push_back(arg); | 42 arguments_.push_back(arg); |
42 } | 43 } |
43 | 44 |
44 void ProcessImpl::RedirectOutput(const std::string& output_file) { | 45 void ProcessImpl::RedirectOutput(const std::string& output_file) { |
45 output_file_ = output_file; | 46 output_file_ = output_file; |
46 } | 47 } |
47 | 48 |
48 void ProcessImpl::RedirectUsingPipe(int child_fd, bool is_input) { | 49 void ProcessImpl::RedirectUsingPipe(int child_fd, bool is_input) { |
49 PipeInfo info; | 50 PipeInfo info; |
50 info.is_input_ = is_input; | 51 info.is_input_ = is_input; |
51 pipe_map_[child_fd] = info; | 52 pipe_map_[child_fd] = info; |
52 } | 53 } |
53 | 54 |
| 55 void ProcessImpl::SetUid(uid_t uid) { |
| 56 uid_ = uid; |
| 57 } |
| 58 |
| 59 void ProcessImpl::SetGid(gid_t gid) { |
| 60 gid_ = gid; |
| 61 } |
| 62 |
54 int ProcessImpl::GetPipe(int child_fd) { | 63 int ProcessImpl::GetPipe(int child_fd) { |
55 PipeMap::iterator i = pipe_map_.find(child_fd); | 64 PipeMap::iterator i = pipe_map_.find(child_fd); |
56 if (i == pipe_map_.end()) | 65 if (i == pipe_map_.end()) |
57 return -1; | 66 return -1; |
58 else | 67 else |
59 return i->second.parent_fd_; | 68 return i->second.parent_fd_; |
60 } | 69 } |
61 | 70 |
62 bool ProcessImpl::PopulatePipeMap() { | 71 bool ProcessImpl::PopulatePipeMap() { |
63 // Verify all target fds are already open. With this assumption we | 72 // Verify all target fds are already open. With this assumption we |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 } | 146 } |
138 if (!output_file_.empty()) { | 147 if (!output_file_.empty()) { |
139 int output_handle = HANDLE_EINTR( | 148 int output_handle = HANDLE_EINTR( |
140 open(output_file_.c_str(), | 149 open(output_file_.c_str(), |
141 O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666)); | 150 O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666)); |
142 int saved_errno = errno; | 151 int saved_errno = errno; |
143 if (output_handle < 0) { | 152 if (output_handle < 0) { |
144 LOG(ERROR) << "Could not create " << output_file_ | 153 LOG(ERROR) << "Could not create " << output_file_ |
145 << ": " << saved_errno; | 154 << ": " << saved_errno; |
146 // Avoid exit() to avoid atexit handlers from parent. | 155 // Avoid exit() to avoid atexit handlers from parent. |
147 _exit(127); | 156 _exit(kErrorExitStatus); |
148 } | 157 } |
149 HANDLE_EINTR(dup2(output_handle, STDOUT_FILENO)); | 158 HANDLE_EINTR(dup2(output_handle, STDOUT_FILENO)); |
150 HANDLE_EINTR(dup2(output_handle, STDERR_FILENO)); | 159 HANDLE_EINTR(dup2(output_handle, STDERR_FILENO)); |
151 // Only close output_handle if it does not happen to be one of | 160 // Only close output_handle if it does not happen to be one of |
152 // the two standard file descriptors we are trying to redirect. | 161 // the two standard file descriptors we are trying to redirect. |
153 if (output_handle != STDOUT_FILENO && output_handle != STDERR_FILENO) { | 162 if (output_handle != STDOUT_FILENO && output_handle != STDERR_FILENO) { |
154 HANDLE_EINTR(close(output_handle)); | 163 HANDLE_EINTR(close(output_handle)); |
155 } | 164 } |
156 } | 165 } |
| 166 if (uid_ >= 0 && setresuid(uid_, uid_, uid_) < 0) { |
| 167 int saved_errno = errno; |
| 168 LOG(ERROR) << "Unable to set UID to " << uid_ << ": " << saved_errno; |
| 169 _exit(kErrorExitStatus); |
| 170 } |
| 171 if (gid_ >= 0 && setresgid(gid_, gid_, gid_) < 0) { |
| 172 int saved_errno = errno; |
| 173 LOG(ERROR) << "Unable to set GID to " << gid_ << ": " << saved_errno; |
| 174 _exit(kErrorExitStatus); |
| 175 } |
157 execv(argv[0], &argv[0]); | 176 execv(argv[0], &argv[0]); |
158 saved_errno = errno; | 177 saved_errno = errno; |
159 LOG(ERROR) << "Exec of " << argv[0] << " failed: " << saved_errno; | 178 LOG(ERROR) << "Exec of " << argv[0] << " failed: " << saved_errno; |
160 _exit(127); | 179 _exit(kErrorExitStatus); |
161 } else { | 180 } else { |
162 // Still executing inside the parent process with known child pid. | 181 // Still executing inside the parent process with known child pid. |
163 arguments_.clear(); | 182 arguments_.clear(); |
164 UpdatePid(pid); | 183 UpdatePid(pid); |
165 // Close our copy of child side pipes. | 184 // Close our copy of child side pipes. |
166 for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) { | 185 for (PipeMap::iterator i = pipe_map_.begin(); i != pipe_map_.end(); ++i) { |
167 HANDLE_EINTR(close(i->second.child_fd_)); | 186 HANDLE_EINTR(close(i->second.child_fd_)); |
168 } | 187 } |
169 } | 188 } |
170 return true; | 189 return true; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 return true; | 290 return true; |
272 } | 291 } |
273 | 292 |
274 pid_t ProcessImpl::Release() { | 293 pid_t ProcessImpl::Release() { |
275 pid_t old_pid = pid_; | 294 pid_t old_pid = pid_; |
276 pid_ = 0; | 295 pid_ = 0; |
277 return old_pid; | 296 return old_pid; |
278 } | 297 } |
279 | 298 |
280 } // namespace chromeos | 299 } // namespace chromeos |
OLD | NEW |