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

Side by Side Diff: runtime/bin/process_linux.cc

Issue 165723007: Move signal_blocker to platform and use it by default in TEMP_FAILURE_RETRY. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tiny fix. Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/process_android.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
7 7
8 #include "bin/process.h" 8 #include "bin/process.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <poll.h> // NOLINT 12 #include <poll.h> // NOLINT
13 #include <stdio.h> // NOLINT 13 #include <stdio.h> // NOLINT
14 #include <stdlib.h> // NOLINT 14 #include <stdlib.h> // NOLINT
15 #include <string.h> // NOLINT 15 #include <string.h> // NOLINT
16 #include <sys/wait.h> // NOLINT 16 #include <sys/wait.h> // NOLINT
17 #include <unistd.h> // NOLINT 17 #include <unistd.h> // NOLINT
18 18
19 #include "platform/signal_blocker.h"
19 #include "bin/fdutils.h" 20 #include "bin/fdutils.h"
20 #include "bin/log.h" 21 #include "bin/log.h"
21 #include "bin/signal_blocker.h"
22 #include "bin/thread.h" 22 #include "bin/thread.h"
23 23
24 24
25 extern char **environ; 25 extern char **environ;
26 26
27 27
28 namespace dart { 28 namespace dart {
29 namespace bin { 29 namespace bin {
30 30
31 // ProcessInfo is used to map a process id to the file descriptor for 31 // ProcessInfo is used to map a process id to the file descriptor for
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 144
145 if (!running_) { 145 if (!running_) {
146 return; 146 return;
147 } 147 }
148 148
149 // Set terminate_done_ to false, so we can use it as a guard for our 149 // Set terminate_done_ to false, so we can use it as a guard for our
150 // monitor. 150 // monitor.
151 running_ = false; 151 running_ = false;
152 152
153 // Fork to wake up waitpid. 153 // Fork to wake up waitpid.
154 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fork()) == 0) { 154 if (TEMP_FAILURE_RETRY(fork()) == 0) {
155 exit(0); 155 exit(0);
156 } 156 }
157 157
158 monitor_->Notify(); 158 monitor_->Notify();
159 159
160 while (!terminate_done_) { 160 while (!terminate_done_) {
161 monitor_->Wait(dart::Monitor::kNoTimeout); 161 monitor_->Wait(dart::Monitor::kNoTimeout);
162 } 162 }
163 } 163 }
164 164
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 char error_buf[kBufferSize]; 243 char error_buf[kBufferSize];
244 char* os_error_message = strerror_r(errno, error_buf, kBufferSize); 244 char* os_error_message = strerror_r(errno, error_buf, kBufferSize);
245 ASSERT(sizeof(child_errno) == sizeof(errno)); 245 ASSERT(sizeof(child_errno) == sizeof(errno));
246 int bytes_written = 246 int bytes_written =
247 FDUtils::WriteToBlocking( 247 FDUtils::WriteToBlocking(
248 exec_control_fd, &child_errno, sizeof(child_errno)); 248 exec_control_fd, &child_errno, sizeof(child_errno));
249 if (bytes_written == sizeof(child_errno)) { 249 if (bytes_written == sizeof(child_errno)) {
250 FDUtils::WriteToBlocking( 250 FDUtils::WriteToBlocking(
251 exec_control_fd, os_error_message, strlen(os_error_message) + 1); 251 exec_control_fd, os_error_message, strlen(os_error_message) + 1);
252 } 252 }
253 TEMP_FAILURE_RETRY(close(exec_control_fd)); 253 VOID_TEMP_FAILURE_RETRY(close(exec_control_fd));
254 exit(1); 254 exit(1);
255 } 255 }
256 256
257 257
258 int Process::Start(const char* path, 258 int Process::Start(const char* path,
259 char* arguments[], 259 char* arguments[],
260 intptr_t arguments_length, 260 intptr_t arguments_length,
261 const char* working_directory, 261 const char* working_directory,
262 char* environment[], 262 char* environment[],
263 intptr_t environment_length, 263 intptr_t environment_length,
264 intptr_t* in, 264 intptr_t* in,
265 intptr_t* out, 265 intptr_t* out,
266 intptr_t* err, 266 intptr_t* err,
267 intptr_t* id, 267 intptr_t* id,
268 intptr_t* exit_event, 268 intptr_t* exit_event,
269 char** os_error_message) { 269 char** os_error_message) {
270 pid_t pid; 270 pid_t pid;
271 int read_in[2]; // Pipe for stdout to child process. 271 int read_in[2]; // Pipe for stdout to child process.
272 int read_err[2]; // Pipe for stderr to child process. 272 int read_err[2]; // Pipe for stderr to child process.
273 int write_out[2]; // Pipe for stdin to child process. 273 int write_out[2]; // Pipe for stdin to child process.
274 int exec_control[2]; // Pipe to get the result from exec. 274 int exec_control[2]; // Pipe to get the result from exec.
275 int result; 275 int result;
276 276
277 result = TEMP_FAILURE_RETRY(pipe(read_in)); 277 result = pipe(read_in);
278 if (result < 0) { 278 if (result < 0) {
279 SetChildOsErrorMessage(os_error_message); 279 SetChildOsErrorMessage(os_error_message);
280 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 280 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
281 return errno; 281 return errno;
282 } 282 }
283 FDUtils::SetCloseOnExec(read_in[0]); 283 FDUtils::SetCloseOnExec(read_in[0]);
284 284
285 result = TEMP_FAILURE_RETRY(pipe(read_err)); 285 result = pipe(read_err);
286 if (result < 0) { 286 if (result < 0) {
287 SetChildOsErrorMessage(os_error_message); 287 SetChildOsErrorMessage(os_error_message);
288 TEMP_FAILURE_RETRY(close(read_in[0])); 288 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
289 TEMP_FAILURE_RETRY(close(read_in[1])); 289 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
290 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 290 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
291 return errno; 291 return errno;
292 } 292 }
293 FDUtils::SetCloseOnExec(read_err[0]); 293 FDUtils::SetCloseOnExec(read_err[0]);
294 294
295 result = TEMP_FAILURE_RETRY(pipe(write_out)); 295 result = pipe(write_out);
296 if (result < 0) { 296 if (result < 0) {
297 SetChildOsErrorMessage(os_error_message); 297 SetChildOsErrorMessage(os_error_message);
298 TEMP_FAILURE_RETRY(close(read_in[0])); 298 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
299 TEMP_FAILURE_RETRY(close(read_in[1])); 299 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
300 TEMP_FAILURE_RETRY(close(read_err[0])); 300 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
301 TEMP_FAILURE_RETRY(close(read_err[1])); 301 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
302 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 302 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
303 return errno; 303 return errno;
304 } 304 }
305 FDUtils::SetCloseOnExec(write_out[1]); 305 FDUtils::SetCloseOnExec(write_out[1]);
306 306
307 result = TEMP_FAILURE_RETRY(pipe(exec_control)); 307 result = pipe(exec_control);
308 if (result < 0) { 308 if (result < 0) {
309 SetChildOsErrorMessage(os_error_message); 309 SetChildOsErrorMessage(os_error_message);
310 TEMP_FAILURE_RETRY(close(read_in[0])); 310 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
311 TEMP_FAILURE_RETRY(close(read_in[1])); 311 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
312 TEMP_FAILURE_RETRY(close(read_err[0])); 312 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
313 TEMP_FAILURE_RETRY(close(read_err[1])); 313 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
314 TEMP_FAILURE_RETRY(close(write_out[0])); 314 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
315 TEMP_FAILURE_RETRY(close(write_out[1])); 315 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
316 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 316 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
317 return errno; 317 return errno;
318 } 318 }
319 FDUtils::SetCloseOnExec(exec_control[0]); 319 FDUtils::SetCloseOnExec(exec_control[0]);
320 FDUtils::SetCloseOnExec(exec_control[1]); 320 FDUtils::SetCloseOnExec(exec_control[1]);
321 321
322 if (result < 0) { 322 if (result < 0) {
323 SetChildOsErrorMessage(os_error_message); 323 SetChildOsErrorMessage(os_error_message);
324 TEMP_FAILURE_RETRY(close(read_in[0])); 324 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
325 TEMP_FAILURE_RETRY(close(read_in[1])); 325 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
326 TEMP_FAILURE_RETRY(close(read_err[0])); 326 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
327 TEMP_FAILURE_RETRY(close(read_err[1])); 327 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
328 TEMP_FAILURE_RETRY(close(write_out[0])); 328 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
329 TEMP_FAILURE_RETRY(close(write_out[1])); 329 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
330 TEMP_FAILURE_RETRY(close(exec_control[0])); 330 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
331 TEMP_FAILURE_RETRY(close(exec_control[1])); 331 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
332 Log::PrintErr("fcntl failed: %s\n", *os_error_message); 332 Log::PrintErr("fcntl failed: %s\n", *os_error_message);
333 return errno; 333 return errno;
334 } 334 }
335 335
336 char** program_arguments = new char*[arguments_length + 2]; 336 char** program_arguments = new char*[arguments_length + 2];
337 program_arguments[0] = const_cast<char*>(path); 337 program_arguments[0] = const_cast<char*>(path);
338 for (int i = 0; i < arguments_length; i++) { 338 for (int i = 0; i < arguments_length; i++) {
339 program_arguments[i + 1] = arguments[i]; 339 program_arguments[i + 1] = arguments[i];
340 } 340 }
341 program_arguments[arguments_length + 1] = NULL; 341 program_arguments[arguments_length + 1] = NULL;
342 342
343 char** program_environment = NULL; 343 char** program_environment = NULL;
344 if (environment != NULL) { 344 if (environment != NULL) {
345 program_environment = new char*[environment_length + 1]; 345 program_environment = new char*[environment_length + 1];
346 for (int i = 0; i < environment_length; i++) { 346 for (int i = 0; i < environment_length; i++) {
347 program_environment[i] = environment[i]; 347 program_environment[i] = environment[i];
348 } 348 }
349 program_environment[environment_length] = NULL; 349 program_environment[environment_length] = NULL;
350 } 350 }
351 351
352 pid = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fork()); 352 pid = TEMP_FAILURE_RETRY(fork());
353 if (pid < 0) { 353 if (pid < 0) {
354 SetChildOsErrorMessage(os_error_message); 354 SetChildOsErrorMessage(os_error_message);
355 delete[] program_arguments; 355 delete[] program_arguments;
356 TEMP_FAILURE_RETRY(close(read_in[0])); 356 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
357 TEMP_FAILURE_RETRY(close(read_in[1])); 357 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
358 TEMP_FAILURE_RETRY(close(read_err[0])); 358 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
359 TEMP_FAILURE_RETRY(close(read_err[1])); 359 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
360 TEMP_FAILURE_RETRY(close(write_out[0])); 360 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
361 TEMP_FAILURE_RETRY(close(write_out[1])); 361 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
362 TEMP_FAILURE_RETRY(close(exec_control[0])); 362 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
363 TEMP_FAILURE_RETRY(close(exec_control[1])); 363 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
364 return errno; 364 return errno;
365 } else if (pid == 0) { 365 } else if (pid == 0) {
366 // Wait for parent process before setting up the child process. 366 // Wait for parent process before setting up the child process.
367 char msg; 367 char msg;
368 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg)); 368 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg));
369 if (bytes_read != sizeof(msg)) { 369 if (bytes_read != sizeof(msg)) {
370 perror("Failed receiving notification message"); 370 perror("Failed receiving notification message");
371 exit(1); 371 exit(1);
372 } 372 }
373 373
374 TEMP_FAILURE_RETRY(close(write_out[1])); 374 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
375 TEMP_FAILURE_RETRY(close(read_in[0])); 375 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
376 TEMP_FAILURE_RETRY(close(read_err[0])); 376 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
377 TEMP_FAILURE_RETRY(close(exec_control[0])); 377 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
378 378
379 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) { 379 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
380 ReportChildError(exec_control[1]); 380 ReportChildError(exec_control[1]);
381 } 381 }
382 TEMP_FAILURE_RETRY(close(write_out[0])); 382 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
383 383
384 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) { 384 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
385 ReportChildError(exec_control[1]); 385 ReportChildError(exec_control[1]);
386 } 386 }
387 TEMP_FAILURE_RETRY(close(read_in[1])); 387 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
388 388
389 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) { 389 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
390 ReportChildError(exec_control[1]); 390 ReportChildError(exec_control[1]);
391 } 391 }
392 TEMP_FAILURE_RETRY(close(read_err[1])); 392 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
393 393
394 if (working_directory != NULL && 394 if (working_directory != NULL && chdir(working_directory) == -1) {
395 TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
396 ReportChildError(exec_control[1]); 395 ReportChildError(exec_control[1]);
397 } 396 }
398 397
399 if (program_environment != NULL) { 398 if (program_environment != NULL) {
400 environ = program_environment; 399 environ = program_environment;
401 } 400 }
402 401
403 TEMP_FAILURE_RETRY( 402 execvp(path, const_cast<char* const*>(program_arguments));
404 execvp(path, const_cast<char* const*>(program_arguments)));
405 403
406 ReportChildError(exec_control[1]); 404 ReportChildError(exec_control[1]);
407 } 405 }
408 406
409 // Be sure to listen for exit-codes, now we have a child-process. 407 // Be sure to listen for exit-codes, now we have a child-process.
410 ExitCodeHandler::ProcessStarted(); 408 ExitCodeHandler::ProcessStarted();
411 409
412 // The arguments and environment for the spawned process are not needed 410 // The arguments and environment for the spawned process are not needed
413 // any longer. 411 // any longer.
414 delete[] program_arguments; 412 delete[] program_arguments;
415 delete[] program_environment; 413 delete[] program_environment;
416 414
417 int event_fds[2]; 415 int event_fds[2];
418 result = TEMP_FAILURE_RETRY(pipe(event_fds)); 416 result = pipe(event_fds);
419 if (result < 0) { 417 if (result < 0) {
420 SetChildOsErrorMessage(os_error_message); 418 SetChildOsErrorMessage(os_error_message);
421 TEMP_FAILURE_RETRY(close(read_in[0])); 419 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
422 TEMP_FAILURE_RETRY(close(read_in[1])); 420 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
423 TEMP_FAILURE_RETRY(close(read_err[0])); 421 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
424 TEMP_FAILURE_RETRY(close(read_err[1])); 422 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
425 TEMP_FAILURE_RETRY(close(write_out[0])); 423 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
426 TEMP_FAILURE_RETRY(close(write_out[1])); 424 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
427 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 425 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
428 return errno; 426 return errno;
429 } 427 }
430 FDUtils::SetCloseOnExec(event_fds[0]); 428 FDUtils::SetCloseOnExec(event_fds[0]);
431 FDUtils::SetCloseOnExec(event_fds[1]); 429 FDUtils::SetCloseOnExec(event_fds[1]);
432 430
433 ProcessInfoList::AddProcess(pid, event_fds[1]); 431 ProcessInfoList::AddProcess(pid, event_fds[1]);
434 *exit_event = event_fds[0]; 432 *exit_event = event_fds[0];
435 FDUtils::SetNonBlocking(event_fds[0]); 433 FDUtils::SetNonBlocking(event_fds[0]);
436 434
437 // Notify child process to start. 435 // Notify child process to start.
438 char msg = '1'; 436 char msg = '1';
439 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg)); 437 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg));
440 if (result != sizeof(msg)) { 438 if (result != sizeof(msg)) {
441 perror("Failed sending notification message"); 439 perror("Failed sending notification message");
442 } 440 }
443 441
444 // Read exec result from child. If no data is returned the exec was 442 // Read exec result from child. If no data is returned the exec was
445 // successful and the exec call closed the pipe. Otherwise the errno 443 // successful and the exec call closed the pipe. Otherwise the errno
446 // is written to the pipe. 444 // is written to the pipe.
447 TEMP_FAILURE_RETRY(close(exec_control[1])); 445 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
448 int child_errno; 446 int child_errno;
449 int bytes_read = -1; 447 int bytes_read = -1;
450 ASSERT(sizeof(child_errno) == sizeof(errno)); 448 ASSERT(sizeof(child_errno) == sizeof(errno));
451 bytes_read = 449 bytes_read =
452 FDUtils::ReadFromBlocking( 450 FDUtils::ReadFromBlocking(
453 exec_control[0], &child_errno, sizeof(child_errno)); 451 exec_control[0], &child_errno, sizeof(child_errno));
454 if (bytes_read == sizeof(child_errno)) { 452 if (bytes_read == sizeof(child_errno)) {
455 static const int kMaxMessageSize = 256; 453 static const int kMaxMessageSize = 256;
456 char* message = static_cast<char*>(malloc(kMaxMessageSize)); 454 char* message = static_cast<char*>(malloc(kMaxMessageSize));
457 bytes_read = FDUtils::ReadFromBlocking(exec_control[0], 455 bytes_read = FDUtils::ReadFromBlocking(exec_control[0],
458 message, 456 message,
459 kMaxMessageSize); 457 kMaxMessageSize);
460 message[kMaxMessageSize - 1] = '\0'; 458 message[kMaxMessageSize - 1] = '\0';
461 *os_error_message = message; 459 *os_error_message = message;
462 } 460 }
463 TEMP_FAILURE_RETRY(close(exec_control[0])); 461 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
464 462
465 // Return error code if any failures. 463 // Return error code if any failures.
466 if (bytes_read != 0) { 464 if (bytes_read != 0) {
467 TEMP_FAILURE_RETRY(close(read_in[0])); 465 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
468 TEMP_FAILURE_RETRY(close(read_in[1])); 466 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
469 TEMP_FAILURE_RETRY(close(read_err[0])); 467 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
470 TEMP_FAILURE_RETRY(close(read_err[1])); 468 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
471 TEMP_FAILURE_RETRY(close(write_out[0])); 469 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
472 TEMP_FAILURE_RETRY(close(write_out[1])); 470 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
473 471
474 // Since exec() failed, we're not interested in the exit code. 472 // Since exec() failed, we're not interested in the exit code.
475 // We close the reading side of the exit code pipe here. 473 // We close the reading side of the exit code pipe here.
476 // GetProcessExitCodes will get a broken pipe error when it tries to write 474 // GetProcessExitCodes will get a broken pipe error when it tries to write
477 // to the writing side of the pipe and it will ignore the error. 475 // to the writing side of the pipe and it will ignore the error.
478 TEMP_FAILURE_RETRY(close(*exit_event)); 476 VOID_TEMP_FAILURE_RETRY(close(*exit_event));
479 *exit_event = -1; 477 *exit_event = -1;
480 478
481 if (bytes_read == -1) { 479 if (bytes_read == -1) {
482 return errno; // Read failed. 480 return errno; // Read failed.
483 } else { 481 } else {
484 return child_errno; // Exec failed. 482 return child_errno; // Exec failed.
485 } 483 }
486 } 484 }
487 485
488 FDUtils::SetNonBlocking(read_in[0]); 486 FDUtils::SetNonBlocking(read_in[0]);
489 *in = read_in[0]; 487 *in = read_in[0];
490 TEMP_FAILURE_RETRY(close(read_in[1])); 488 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
491 FDUtils::SetNonBlocking(write_out[1]); 489 FDUtils::SetNonBlocking(write_out[1]);
492 *out = write_out[1]; 490 *out = write_out[1];
493 TEMP_FAILURE_RETRY(close(write_out[0])); 491 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
494 FDUtils::SetNonBlocking(read_err[0]); 492 FDUtils::SetNonBlocking(read_err[0]);
495 *err = read_err[0]; 493 *err = read_err[0];
496 TEMP_FAILURE_RETRY(close(read_err[1])); 494 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
497 495
498 *id = pid; 496 *id = pid;
499 return 0; 497 return 0;
500 } 498 }
501 499
502 500
503 class BufferList: public BufferListBase { 501 class BufferList: public BufferListBase {
504 public: 502 public:
505 bool Read(int fd, intptr_t available) { 503 bool Read(int fd, intptr_t available) {
506 // Read all available bytes. 504 // Read all available bytes.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 intptr_t exit_code = exit_code_data.ints[0]; 609 intptr_t exit_code = exit_code_data.ints[0];
612 intptr_t negative = exit_code_data.ints[1]; 610 intptr_t negative = exit_code_data.ints[1];
613 if (negative) exit_code = -exit_code; 611 if (negative) exit_code = -exit_code;
614 result->set_exit_code(exit_code); 612 result->set_exit_code(exit_code);
615 613
616 return true; 614 return true;
617 } 615 }
618 616
619 617
620 bool Process::Kill(intptr_t id, int signal) { 618 bool Process::Kill(intptr_t id, int signal) {
621 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1); 619 return kill(id, signal) != -1;
622 } 620 }
623 621
624 622
625 void Process::TerminateExitCodeHandler() { 623 void Process::TerminateExitCodeHandler() {
626 ExitCodeHandler::TerminateExitCodeThread(); 624 ExitCodeHandler::TerminateExitCodeThread();
627 } 625 }
628 626
629 627
630 intptr_t Process::CurrentProcessId() { 628 intptr_t Process::CurrentProcessId() {
631 return static_cast<intptr_t>(getpid()); 629 return static_cast<intptr_t>(getpid());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 intptr_t Process::SetSignalHandler(intptr_t signal) { 664 intptr_t Process::SetSignalHandler(intptr_t signal) {
667 bool found = false; 665 bool found = false;
668 for (int i = 0; i < kSignalsCount; i++) { 666 for (int i = 0; i < kSignalsCount; i++) {
669 if (kSignals[i] == signal) { 667 if (kSignals[i] == signal) {
670 found = true; 668 found = true;
671 break; 669 break;
672 } 670 }
673 } 671 }
674 if (!found) return -1; 672 if (!found) return -1;
675 int fds[2]; 673 int fds[2];
676 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(pipe(fds)) != 0) { 674 if (pipe(fds) != 0) {
677 return -1; 675 return -1;
678 } 676 }
679 if (!FDUtils::SetNonBlocking(fds[0])) { 677 if (!FDUtils::SetNonBlocking(fds[0])) {
680 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0])); 678 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
681 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1])); 679 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
682 return -1; 680 return -1;
683 } 681 }
684 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 682 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
685 MutexLocker lock(signal_mutex); 683 MutexLocker lock(signal_mutex);
686 SignalInfo* handler = signal_handlers; 684 SignalInfo* handler = signal_handlers;
687 bool listen = true; 685 bool listen = true;
688 while (handler != NULL) { 686 while (handler != NULL) {
689 if (handler->signal() == signal) { 687 if (handler->signal() == signal) {
690 listen = false; 688 listen = false;
691 break; 689 break;
692 } 690 }
693 handler = handler->next(); 691 handler = handler->next();
694 } 692 }
695 if (listen) { 693 if (listen) {
696 struct sigaction act; 694 struct sigaction act;
697 bzero(&act, sizeof(act)); 695 bzero(&act, sizeof(act));
698 act.sa_handler = SignalHandler; 696 act.sa_handler = SignalHandler;
699 sigemptyset(&act.sa_mask); 697 sigemptyset(&act.sa_mask);
700 for (int i = 0; i < kSignalsCount; i++) { 698 for (int i = 0; i < kSignalsCount; i++) {
701 sigaddset(&act.sa_mask, kSignals[i]); 699 sigaddset(&act.sa_mask, kSignals[i]);
702 } 700 }
703 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 701 int status = sigaction(signal, &act, NULL);
704 sigaction(signal, &act, NULL));
705 if (status < 0) { 702 if (status < 0) {
706 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0])); 703 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
707 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1])); 704 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
708 return -1; 705 return -1;
709 } 706 }
710 } 707 }
711 if (signal_handlers == NULL) { 708 if (signal_handlers == NULL) {
712 signal_handlers = new SignalInfo(fds[1], signal); 709 signal_handlers = new SignalInfo(fds[1], signal);
713 } else { 710 } else {
714 new SignalInfo(fds[1], signal, signal_handlers); 711 new SignalInfo(fds[1], signal, signal_handlers);
715 } 712 }
716 return fds[0]; 713 return fds[0];
717 } 714 }
(...skipping 16 matching lines...) Expand all
734 } 731 }
735 } 732 }
736 SignalInfo* next = handler->next(); 733 SignalInfo* next = handler->next();
737 if (remove) delete handler; 734 if (remove) delete handler;
738 handler = next; 735 handler = next;
739 } 736 }
740 if (unlisten) { 737 if (unlisten) {
741 struct sigaction act; 738 struct sigaction act;
742 bzero(&act, sizeof(act)); 739 bzero(&act, sizeof(act));
743 act.sa_handler = SIG_DFL; 740 act.sa_handler = SIG_DFL;
744 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL)); 741 sigaction(signal, &act, NULL);
745 } 742 }
746 } 743 }
747 744
748 } // namespace bin 745 } // namespace bin
749 } // namespace dart 746 } // namespace dart
750 747
751 #endif // defined(TARGET_OS_LINUX) 748 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/process_android.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698