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

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

Issue 798743004: Add support for starting a detached process (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 5 years, 11 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.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
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 exec_control_fd, &child_errno, sizeof(child_errno)); 249 exec_control_fd, &child_errno, sizeof(child_errno));
250 if (bytes_written == sizeof(child_errno)) { 250 if (bytes_written == sizeof(child_errno)) {
251 FDUtils::WriteToBlocking( 251 FDUtils::WriteToBlocking(
252 exec_control_fd, os_error_message, strlen(os_error_message) + 1); 252 exec_control_fd, os_error_message, strlen(os_error_message) + 1);
253 } 253 }
254 VOID_TEMP_FAILURE_RETRY(close(exec_control_fd)); 254 VOID_TEMP_FAILURE_RETRY(close(exec_control_fd));
255 exit(1); 255 exit(1);
256 } 256 }
257 257
258 258
259 static void ReportPid(int exec_control_fd, int pid) {
260 // In the case of starting a detached process the actual pid of that process
261 // is communicated using the exec control pipe.
262 int bytes_written =
263 FDUtils::WriteToBlocking(exec_control_fd, &pid, sizeof(pid));
264 ASSERT(bytes_written == sizeof(int));
265 USE(bytes_written);
266 }
267
268
269 static void ReadChildError(int exec_control_fd, char** error_message) {
270 const int kMaxMessageSize = 256;
271 char* message = static_cast<char*>(malloc(kMaxMessageSize));
272 if (message != NULL) {
273 FDUtils::ReadFromBlocking(exec_control_fd, message, kMaxMessageSize);
274 message[kMaxMessageSize - 1] = '\0';
275 *error_message = message;
276 } else {
277 static const char* no_message = "Cannot get error message, out of memory";
278 *error_message = const_cast<char*>(no_message);
279 }
280 }
281
282
259 int Process::Start(const char* path, 283 int Process::Start(const char* path,
260 char* arguments[], 284 char* arguments[],
261 intptr_t arguments_length, 285 intptr_t arguments_length,
262 const char* working_directory, 286 const char* working_directory,
263 char* environment[], 287 char* environment[],
264 intptr_t environment_length, 288 intptr_t environment_length,
289 bool detach,
265 intptr_t* in, 290 intptr_t* in,
266 intptr_t* out, 291 intptr_t* out,
267 intptr_t* err, 292 intptr_t* err,
268 intptr_t* id, 293 intptr_t* id,
269 intptr_t* exit_event, 294 intptr_t* exit_event,
270 char** os_error_message) { 295 char** os_error_message) {
271 pid_t pid; 296 pid_t pid;
272 int read_in[2]; // Pipe for stdout to child process. 297 int read_in[2] = {-1, -1}; // Pipe for stdout to child process.
273 int read_err[2]; // Pipe for stderr to child process. 298 int read_err[2] = {-1, -1}; // Pipe for stderr to child process.
274 int write_out[2]; // Pipe for stdin to child process. 299 int write_out[2] = {-1, -1}; // Pipe for stdin to child process.
275 int exec_control[2]; // Pipe to get the result from exec. 300 int exec_control[2] = {-1, -1}; // Pipe to get the result from exec.
276 int result; 301 int result;
277 302
278 result = pipe(read_in); 303 result = TEMP_FAILURE_RETRY(pipe(exec_control));
279 if (result < 0) { 304 if (result < 0) {
280 SetChildOsErrorMessage(os_error_message); 305 SetChildOsErrorMessage(os_error_message);
281 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 306 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
282 return errno; 307 return errno;
283 } 308 }
284 FDUtils::SetCloseOnExec(read_in[0]);
285
286 result = pipe(read_err);
287 if (result < 0) {
288 SetChildOsErrorMessage(os_error_message);
289 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
290 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
291 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
292 return errno;
293 }
294 FDUtils::SetCloseOnExec(read_err[0]);
295
296 result = pipe(write_out);
297 if (result < 0) {
298 SetChildOsErrorMessage(os_error_message);
299 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
300 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
301 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
302 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
303 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
304 return errno;
305 }
306 FDUtils::SetCloseOnExec(write_out[1]);
307
308 result = pipe(exec_control);
309 if (result < 0) {
310 SetChildOsErrorMessage(os_error_message);
311 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
312 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
313 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
314 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
315 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
316 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
317 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
318 return errno;
319 }
320 FDUtils::SetCloseOnExec(exec_control[0]); 309 FDUtils::SetCloseOnExec(exec_control[0]);
321 FDUtils::SetCloseOnExec(exec_control[1]); 310 FDUtils::SetCloseOnExec(exec_control[1]);
322 311
312 // For a detached process the pipe to connect stdout is still used for
313 // signaling when to do the first fork.
314 result = TEMP_FAILURE_RETRY(pipe(read_in));
323 if (result < 0) { 315 if (result < 0) {
324 SetChildOsErrorMessage(os_error_message); 316 SetChildOsErrorMessage(os_error_message);
325 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
326 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
327 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
328 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
329 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
330 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
331 VOID_TEMP_FAILURE_RETRY(close(exec_control[0])); 317 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
332 VOID_TEMP_FAILURE_RETRY(close(exec_control[1])); 318 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
333 Log::PrintErr("fcntl failed: %s\n", *os_error_message); 319 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
334 return errno; 320 return errno;
335 } 321 }
322 FDUtils::SetCloseOnExec(read_in[0]);
323
324 // For detached processes the pipe to connect stderr and stdin are not used.
325 if (!detach) {
326 result = TEMP_FAILURE_RETRY(pipe(read_err));
327 if (result < 0) {
328 SetChildOsErrorMessage(os_error_message);
329 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
330 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
331 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
332 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
333 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
334 return errno;
335 }
336 FDUtils::SetCloseOnExec(read_err[0]);
337
338 result = TEMP_FAILURE_RETRY(pipe(write_out));
339 if (result < 0) {
340 SetChildOsErrorMessage(os_error_message);
341 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
342 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
343 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
344 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
345 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
346 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
347 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
348 return errno;
349 }
350 FDUtils::SetCloseOnExec(write_out[1]);
351 }
336 352
337 char** program_arguments = new char*[arguments_length + 2]; 353 char** program_arguments = new char*[arguments_length + 2];
338 program_arguments[0] = const_cast<char*>(path); 354 program_arguments[0] = const_cast<char*>(path);
339 for (int i = 0; i < arguments_length; i++) { 355 for (int i = 0; i < arguments_length; i++) {
340 program_arguments[i + 1] = arguments[i]; 356 program_arguments[i + 1] = arguments[i];
341 } 357 }
342 program_arguments[arguments_length + 1] = NULL; 358 program_arguments[arguments_length + 1] = NULL;
343 359
344 char** program_environment = NULL; 360 char** program_environment = NULL;
345 if (environment != NULL) { 361 if (environment != NULL) {
346 program_environment = new char*[environment_length + 1]; 362 program_environment = new char*[environment_length + 1];
347 for (int i = 0; i < environment_length; i++) { 363 for (int i = 0; i < environment_length; i++) {
348 program_environment[i] = environment[i]; 364 program_environment[i] = environment[i];
349 } 365 }
350 program_environment[environment_length] = NULL; 366 program_environment[environment_length] = NULL;
351 } 367 }
352 368
353 pid = TEMP_FAILURE_RETRY(fork()); 369 pid = TEMP_FAILURE_RETRY(fork());
354 if (pid < 0) { 370 if (pid < 0) {
355 SetChildOsErrorMessage(os_error_message); 371 SetChildOsErrorMessage(os_error_message);
356 delete[] program_arguments; 372 delete[] program_arguments;
373 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
374 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
357 VOID_TEMP_FAILURE_RETRY(close(read_in[0])); 375 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
358 VOID_TEMP_FAILURE_RETRY(close(read_in[1])); 376 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
359 VOID_TEMP_FAILURE_RETRY(close(read_err[0])); 377 if (!detach) {
360 VOID_TEMP_FAILURE_RETRY(close(read_err[1])); 378 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
361 VOID_TEMP_FAILURE_RETRY(close(write_out[0])); 379 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
362 VOID_TEMP_FAILURE_RETRY(close(write_out[1])); 380 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
363 VOID_TEMP_FAILURE_RETRY(close(exec_control[0])); 381 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
364 VOID_TEMP_FAILURE_RETRY(close(exec_control[1])); 382 }
365 return errno; 383 return errno;
366 } else if (pid == 0) { 384 } else if (pid == 0) {
367 // Wait for parent process before setting up the child process. 385 // Wait for parent process before setting up the child process.
368 char msg; 386 char msg;
369 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg)); 387 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg));
370 if (bytes_read != sizeof(msg)) { 388 if (bytes_read != sizeof(msg)) {
371 perror("Failed receiving notification message"); 389 perror("Failed receiving notification message");
372 exit(1); 390 exit(1);
373 } 391 }
392 if (detach) {
393 // For a detached process the pipe to connect stdout is only used for
394 // signaling when to do the first fork.
395 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
396 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
397 // Fork once more to start a new session.
398 pid = TEMP_FAILURE_RETRY(fork());
399 if (pid < 0) {
400 ReportChildError(exec_control[1]);
401 } else if (pid == 0) {
402 // Start a new session.
403 if (TEMP_FAILURE_RETRY(setsid()) == -1) {
404 ReportChildError(exec_control[1]);
405 } else {
406 // Do a final fork to not be the session leader.
407 pid = TEMP_FAILURE_RETRY(fork());
408 if (pid < 0) {
409 ReportChildError(exec_control[1]);
410 } else if (pid == 0) {
411 // Close all open file descriptors except for exec_control[1].
412 int max_fds = sysconf(_SC_OPEN_MAX);
413 if (max_fds == -1) max_fds = _POSIX_OPEN_MAX;
414 for (int fd = 0; fd < max_fds; fd++) {
415 if (fd != exec_control[1]) {
416 VOID_TEMP_FAILURE_RETRY(close(fd));
417 }
418 }
374 419
375 VOID_TEMP_FAILURE_RETRY(close(write_out[1])); 420 // Re-open stdin, stdout and stderr and connect them to /dev/null.
376 VOID_TEMP_FAILURE_RETRY(close(read_in[0])); 421 // The loop above should already have closed all of them, so
377 VOID_TEMP_FAILURE_RETRY(close(read_err[0])); 422 // creating new file descriptors should start at STDIN_FILENO.
378 VOID_TEMP_FAILURE_RETRY(close(exec_control[0])); 423 int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
424 if (fd != STDIN_FILENO) {
425 ReportChildError(exec_control[1]);
426 }
427 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) !=
428 STDOUT_FILENO) {
429 ReportChildError(exec_control[1]);
430 }
431 if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) !=
432 STDERR_FILENO) {
433 ReportChildError(exec_control[1]);
434 }
379 435
380 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) { 436 // Report the final PID and do the exec.
437 ReportPid(exec_control[1], getpid()); // getpid cannot fail.
438 VOID_TEMP_FAILURE_RETRY(
439 execvp(path, const_cast<char* const*>(program_arguments)));
440 ReportChildError(exec_control[1]);
441 } else {
442 exit(0);
443 }
444 }
445 } else {
446 exit(0);
447 }
448 } else {
449 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
450 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
451 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
452 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
453
454 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
455 ReportChildError(exec_control[1]);
456 }
457 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
458
459 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
460 ReportChildError(exec_control[1]);
461 }
462 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
463
464 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
465 ReportChildError(exec_control[1]);
466 }
467 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
468
469 if (working_directory != NULL && chdir(working_directory) == -1) {
470 ReportChildError(exec_control[1]);
471 }
472
473 if (program_environment != NULL) {
474 environ = program_environment;
475 }
476
477 VOID_TEMP_FAILURE_RETRY(
478 execvp(path, const_cast<char* const*>(program_arguments)));
479
381 ReportChildError(exec_control[1]); 480 ReportChildError(exec_control[1]);
382 } 481 }
383 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
384
385 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
386 ReportChildError(exec_control[1]);
387 }
388 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
389
390 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
391 ReportChildError(exec_control[1]);
392 }
393 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
394
395 if (working_directory != NULL && chdir(working_directory) == -1) {
396 ReportChildError(exec_control[1]);
397 }
398
399 if (program_environment != NULL) {
400 environ = program_environment;
401 }
402
403 execvp(path, const_cast<char* const*>(program_arguments));
404
405 ReportChildError(exec_control[1]);
406 } 482 }
407 483
408 // Be sure to listen for exit-codes, now we have a child-process. 484 // Be sure to listen for exit-codes, now we have a child-process.
409 ExitCodeHandler::ProcessStarted(); 485 ExitCodeHandler::ProcessStarted();
410 486
411 // The arguments and environment for the spawned process are not needed 487 // The arguments and environment for the spawned process are not needed
412 // any longer. 488 // any longer.
413 delete[] program_arguments; 489 delete[] program_arguments;
414 delete[] program_environment; 490 delete[] program_environment;
415 491
416 int event_fds[2]; 492 if (!detach) {
417 result = pipe(event_fds); 493 int event_fds[2];
418 if (result < 0) { 494 result = pipe(event_fds);
419 SetChildOsErrorMessage(os_error_message); 495 if (result < 0) {
420 VOID_TEMP_FAILURE_RETRY(close(read_in[0])); 496 SetChildOsErrorMessage(os_error_message);
421 VOID_TEMP_FAILURE_RETRY(close(read_in[1])); 497 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
422 VOID_TEMP_FAILURE_RETRY(close(read_err[0])); 498 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
423 VOID_TEMP_FAILURE_RETRY(close(read_err[1])); 499 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
424 VOID_TEMP_FAILURE_RETRY(close(write_out[0])); 500 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
425 VOID_TEMP_FAILURE_RETRY(close(write_out[1])); 501 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
426 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 502 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
427 return errno; 503 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
504 return errno;
505 }
506 FDUtils::SetCloseOnExec(event_fds[0]);
507 FDUtils::SetCloseOnExec(event_fds[1]);
508
509 ProcessInfoList::AddProcess(pid, event_fds[1]);
510 *exit_event = event_fds[0];
511 FDUtils::SetNonBlocking(event_fds[0]);
428 } 512 }
429 FDUtils::SetCloseOnExec(event_fds[0]);
430 FDUtils::SetCloseOnExec(event_fds[1]);
431
432 ProcessInfoList::AddProcess(pid, event_fds[1]);
433 *exit_event = event_fds[0];
434 FDUtils::SetNonBlocking(event_fds[0]);
435 513
436 // Notify child process to start. 514 // Notify child process to start.
437 char msg = '1'; 515 char msg = '1';
438 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg)); 516 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg));
439 if (result != sizeof(msg)) { 517 if (result != sizeof(msg)) {
440 perror("Failed sending notification message"); 518 perror("Failed sending notification message");
441 } 519 }
442 520
443 // Read exec result from child. If no data is returned the exec was
444 // successful and the exec call closed the pipe. Otherwise the errno
445 // is written to the pipe.
446 VOID_TEMP_FAILURE_RETRY(close(exec_control[1])); 521 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
522 bool failed = false;
447 int child_errno; 523 int child_errno;
448 int bytes_read = -1; 524 int bytes_read = -1;
449 ASSERT(sizeof(child_errno) == sizeof(errno)); 525 ASSERT(sizeof(child_errno) == sizeof(errno));
450 bytes_read = 526 if (!detach) {
451 FDUtils::ReadFromBlocking( 527 // Read exec result from child. If no data is returned the exec was
452 exec_control[0], &child_errno, sizeof(child_errno)); 528 // successful and the exec call closed the pipe. Otherwise the errno
453 if (bytes_read == sizeof(child_errno)) { 529 // is written to the pipe.
454 static const int kMaxMessageSize = 256; 530 bytes_read =
455 char* message = static_cast<char*>(malloc(kMaxMessageSize)); 531 FDUtils::ReadFromBlocking(
456 bytes_read = FDUtils::ReadFromBlocking(exec_control[0], 532 exec_control[0], &child_errno, sizeof(child_errno));
457 message, 533 if (bytes_read == sizeof(child_errno)) {
458 kMaxMessageSize); 534 ReadChildError(exec_control[0], os_error_message);
459 message[kMaxMessageSize - 1] = '\0'; 535 failed = true;
460 *os_error_message = message; 536 }
537 } else {
538 // Read exec result from child. If only pid data is returned the exec was
539 // successful and the exec call closed the pipe. Otherwise the errno
540 // is written to the pipe as well.
541 int result[2];
542 ASSERT(sizeof(int) == sizeof(child_errno));
543 bytes_read =
544 FDUtils::ReadFromBlocking(
545 exec_control[0], result, sizeof(result));
546 if (bytes_read == sizeof(int)) {
547 pid = result[0];
548 } else if (bytes_read == 2 * sizeof(int)) {
549 pid = result[0];
550 child_errno = result[1];
551 ReadChildError(exec_control[0], os_error_message);
552 failed = true;
553 }
461 } 554 }
462 VOID_TEMP_FAILURE_RETRY(close(exec_control[0])); 555 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
463 556
464 // Return error code if any failures. 557 // Return error code if any failures.
465 if (bytes_read != 0) { 558 if (failed) {
466 VOID_TEMP_FAILURE_RETRY(close(read_in[0])); 559 if (!detach) {
467 VOID_TEMP_FAILURE_RETRY(close(read_in[1])); 560 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
468 VOID_TEMP_FAILURE_RETRY(close(read_err[0])); 561 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
469 VOID_TEMP_FAILURE_RETRY(close(read_err[1])); 562 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
470 VOID_TEMP_FAILURE_RETRY(close(write_out[0])); 563 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
471 VOID_TEMP_FAILURE_RETRY(close(write_out[1])); 564 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
565 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
472 566
473 // Since exec() failed, we're not interested in the exit code. 567 // Since exec() failed, we're not interested in the exit code.
474 // We close the reading side of the exit code pipe here. 568 // We close the reading side of the exit code pipe here.
475 // GetProcessExitCodes will get a broken pipe error when it tries to write 569 // GetProcessExitCodes will get a broken pipe error when it tries to write
476 // to the writing side of the pipe and it will ignore the error. 570 // to the writing side of the pipe and it will ignore the error.
477 VOID_TEMP_FAILURE_RETRY(close(*exit_event)); 571 VOID_TEMP_FAILURE_RETRY(close(*exit_event));
478 *exit_event = -1; 572 *exit_event = -1;
479 573 }
480 if (bytes_read == -1) { 574 if (bytes_read == -1) {
481 return errno; // Read failed. 575 return errno; // Read failed.
482 } else { 576 } else {
483 return child_errno; // Exec failed. 577 return child_errno; // Exec failed.
484 } 578 }
485 } 579 }
486 580
487 FDUtils::SetNonBlocking(read_in[0]); 581 FDUtils::SetNonBlocking(read_in[0]);
488 *in = read_in[0]; 582 *in = read_in[0];
489 VOID_TEMP_FAILURE_RETRY(close(read_in[1])); 583 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 bzero(&act, sizeof(act)); 828 bzero(&act, sizeof(act));
735 act.sa_handler = SIG_DFL; 829 act.sa_handler = SIG_DFL;
736 sigaction(signal, &act, NULL); 830 sigaction(signal, &act, NULL);
737 } 831 }
738 } 832 }
739 833
740 } // namespace bin 834 } // namespace bin
741 } // namespace dart 835 } // namespace dart
742 836
743 #endif // defined(TARGET_OS_LINUX) 837 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698