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

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

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

Powered by Google App Engine
This is Rietveld 408576698