OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium 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 #define _CRT_SECURE_NO_WARNINGS | 5 #define _CRT_SECURE_NO_WARNINGS |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/eintr_wrappers.h" |
8 #include "base/file_path.h" | 9 #include "base/file_path.h" |
9 #include "base/multiprocess_test.h" | 10 #include "base/multiprocess_test.h" |
10 #include "base/path_service.h" | 11 #include "base/path_service.h" |
11 #include "base/platform_thread.h" | 12 #include "base/platform_thread.h" |
12 #include "base/process_util.h" | 13 #include "base/process_util.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
14 | 15 |
15 #if defined(OS_LINUX) | 16 #if defined(OS_LINUX) |
16 #include <dlfcn.h> | 17 #include <dlfcn.h> |
17 #endif | 18 #endif |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 | 185 |
185 const int kChildPipe = 20; // FD # for write end of pipe in child process. | 186 const int kChildPipe = 20; // FD # for write end of pipe in child process. |
186 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { | 187 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { |
187 // This child process counts the number of open FDs, it then writes that | 188 // This child process counts the number of open FDs, it then writes that |
188 // number out to a pipe connected to the parent. | 189 // number out to a pipe connected to the parent. |
189 int num_open_files = 0; | 190 int num_open_files = 0; |
190 int write_pipe = kChildPipe; | 191 int write_pipe = kChildPipe; |
191 int max_files = GetMaxFilesOpenInProcess(); | 192 int max_files = GetMaxFilesOpenInProcess(); |
192 for (int i = STDERR_FILENO + 1; i < max_files; i++) { | 193 for (int i = STDERR_FILENO + 1; i < max_files; i++) { |
193 if (i != kChildPipe) { | 194 if (i != kChildPipe) { |
194 if (close(i) != -1) { | 195 if (HANDLE_EINTR(close(i)) != -1) { |
195 LOG(WARNING) << "Leaked FD " << i; | 196 LOG(WARNING) << "Leaked FD " << i; |
196 num_open_files += 1; | 197 num_open_files += 1; |
197 } | 198 } |
198 } | 199 } |
199 } | 200 } |
200 | 201 |
201 // InitLogging always opens a file at startup. | 202 // InitLogging always opens a file at startup. |
202 int expected_num_open_fds = 1; | 203 int expected_num_open_fds = 1; |
203 #if defined(OS_LINUX) | 204 #if defined(OS_LINUX) |
204 // On Linux, '/etc/localtime' is opened before the test's main() enters. | 205 // On Linux, '/etc/localtime' is opened before the test's main() enters. |
205 expected_num_open_fds += 1; | 206 expected_num_open_fds += 1; |
206 #endif // defined(OS_LINUX) | 207 #endif // defined(OS_LINUX) |
207 num_open_files -= expected_num_open_fds; | 208 num_open_files -= expected_num_open_fds; |
208 | 209 |
209 int written = write(write_pipe, &num_open_files, sizeof(num_open_files)); | 210 int written = HANDLE_EINTR(write(write_pipe, &num_open_files, |
| 211 sizeof(num_open_files))); |
210 DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files)); | 212 DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files)); |
211 close(write_pipe); | 213 HANDLE_EINTR(close(write_pipe)); |
212 | 214 |
213 return 0; | 215 return 0; |
214 } | 216 } |
215 | 217 |
216 TEST_F(ProcessUtilTest, FDRemapping) { | 218 TEST_F(ProcessUtilTest, FDRemapping) { |
217 // Open some files to check they don't get leaked to the child process. | 219 // Open some files to check they don't get leaked to the child process. |
218 int fds[2]; | 220 int fds[2]; |
219 if (pipe(fds) < 0) | 221 if (pipe(fds) < 0) |
220 NOTREACHED(); | 222 NOTREACHED(); |
221 int pipe_read_fd = fds[0]; | 223 int pipe_read_fd = fds[0]; |
222 int pipe_write_fd = fds[1]; | 224 int pipe_write_fd = fds[1]; |
223 | 225 |
224 // open some dummy fds to make sure they don't propogate over to the | 226 // open some dummy fds to make sure they don't propogate over to the |
225 // child process. | 227 // child process. |
226 int dev_null = open("/dev/null", O_RDONLY); | 228 int dev_null = open("/dev/null", O_RDONLY); |
227 int sockets[2]; | 229 int sockets[2]; |
228 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); | 230 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); |
229 | 231 |
230 file_handle_mapping_vector fd_mapping_vec; | 232 file_handle_mapping_vector fd_mapping_vec; |
231 fd_mapping_vec.push_back(std::pair<int,int>(pipe_write_fd, kChildPipe)); | 233 fd_mapping_vec.push_back(std::pair<int,int>(pipe_write_fd, kChildPipe)); |
232 ProcessHandle handle = this->SpawnChild(L"ProcessUtilsLeakFDChildProcess", | 234 ProcessHandle handle = this->SpawnChild(L"ProcessUtilsLeakFDChildProcess", |
233 fd_mapping_vec, | 235 fd_mapping_vec, |
234 false); | 236 false); |
235 ASSERT_NE(static_cast<ProcessHandle>(NULL), handle); | 237 ASSERT_NE(static_cast<ProcessHandle>(NULL), handle); |
236 close(pipe_write_fd); | 238 HANDLE_EINTR(close(pipe_write_fd)); |
237 | 239 |
238 // Read number of open files in client process from pipe; | 240 // Read number of open files in client process from pipe; |
239 int num_open_files = -1; | 241 int num_open_files = -1; |
240 ssize_t bytes_read = read(pipe_read_fd, &num_open_files, | 242 ssize_t bytes_read = |
241 sizeof(num_open_files)); | 243 HANDLE_EINTR(read(pipe_read_fd, &num_open_files, sizeof(num_open_files))); |
242 ASSERT_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); | 244 ASSERT_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); |
243 | 245 |
244 // Make sure 0 fds are leaked to the client. | 246 // Make sure 0 fds are leaked to the client. |
245 ASSERT_EQ(0, num_open_files); | 247 ASSERT_EQ(0, num_open_files); |
246 | 248 |
247 EXPECT_TRUE(WaitForSingleProcess(handle, 1000)); | 249 EXPECT_TRUE(WaitForSingleProcess(handle, 1000)); |
248 base::CloseProcessHandle(handle); | 250 base::CloseProcessHandle(handle); |
249 close(fds[0]); | 251 HANDLE_EINTR(close(fds[0])); |
250 close(sockets[0]); | 252 HANDLE_EINTR(close(sockets[0])); |
251 close(sockets[1]); | 253 HANDLE_EINTR(close(sockets[1])); |
252 close(dev_null); | 254 HANDLE_EINTR(close(dev_null)); |
253 } | 255 } |
254 | 256 |
255 TEST_F(ProcessUtilTest, GetAppOutput) { | 257 TEST_F(ProcessUtilTest, GetAppOutput) { |
256 std::string output; | 258 std::string output; |
257 EXPECT_TRUE(GetAppOutput(CommandLine(L"true"), &output)); | 259 EXPECT_TRUE(GetAppOutput(CommandLine(L"true"), &output)); |
258 EXPECT_STREQ("", output.c_str()); | 260 EXPECT_STREQ("", output.c_str()); |
259 | 261 |
260 EXPECT_FALSE(GetAppOutput(CommandLine(L"false"), &output)); | 262 EXPECT_FALSE(GetAppOutput(CommandLine(L"false"), &output)); |
261 | 263 |
262 std::vector<std::string> argv; | 264 std::vector<std::string> argv; |
263 argv.push_back("/bin/echo"); | 265 argv.push_back("/bin/echo"); |
264 argv.push_back("-n"); | 266 argv.push_back("-n"); |
265 argv.push_back("foobar42"); | 267 argv.push_back("foobar42"); |
266 EXPECT_TRUE(GetAppOutput(CommandLine(argv), &output)); | 268 EXPECT_TRUE(GetAppOutput(CommandLine(argv), &output)); |
267 EXPECT_STREQ("foobar42", output.c_str()); | 269 EXPECT_STREQ("foobar42", output.c_str()); |
268 } | 270 } |
269 | 271 |
270 #endif // defined(OS_POSIX) | 272 #endif // defined(OS_POSIX) |
271 | 273 |
272 } // namespace base | 274 } // namespace base |
OLD | NEW |