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

Side by Side Diff: runtime/bin/process_android.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/file_system_watcher_macos.cc ('k') | runtime/bin/process_linux.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_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
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 "bin/fdutils.h" 19 #include "bin/fdutils.h"
20 #include "bin/log.h" 20 #include "bin/log.h"
21 #include "bin/signal_blocker.h"
22 #include "bin/thread.h" 21 #include "bin/thread.h"
23 22
23 #include "platform/signal_blocker.h"
24
24 25
25 extern char **environ; 26 extern char **environ;
26 27
27 28
28 namespace dart { 29 namespace dart {
29 namespace bin { 30 namespace bin {
30 31
31 // ProcessInfo is used to map a process id to the file descriptor for 32 // ProcessInfo is used to map a process id to the file descriptor for
32 // the pipe used to communicate the exit code of the process to Dart. 33 // the pipe used to communicate the exit code of the process to Dart.
33 // ProcessInfo objects are kept in the static singly-linked 34 // ProcessInfo objects are kept in the static singly-linked
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 145
145 if (!running_) { 146 if (!running_) {
146 return; 147 return;
147 } 148 }
148 149
149 // Set terminate_done_ to false, so we can use it as a guard for our 150 // Set terminate_done_ to false, so we can use it as a guard for our
150 // monitor. 151 // monitor.
151 running_ = false; 152 running_ = false;
152 153
153 // Fork to wake up waitpid. 154 // Fork to wake up waitpid.
154 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fork()) == 0) { 155 if (TEMP_FAILURE_RETRY(fork()) == 0) {
155 exit(0); 156 exit(0);
156 } 157 }
157 158
158 monitor_->Notify(); 159 monitor_->Notify();
159 160
160 while (!terminate_done_) { 161 while (!terminate_done_) {
161 monitor_->Wait(dart::Monitor::kNoTimeout); 162 monitor_->Wait(dart::Monitor::kNoTimeout);
162 } 163 }
163 } 164 }
164 165
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 char os_error_message[kBufferSize]; 245 char os_error_message[kBufferSize];
245 strerror_r(errno, os_error_message, kBufferSize); 246 strerror_r(errno, os_error_message, kBufferSize);
246 ASSERT(sizeof(child_errno) == sizeof(errno)); 247 ASSERT(sizeof(child_errno) == sizeof(errno));
247 int bytes_written = 248 int bytes_written =
248 FDUtils::WriteToBlocking( 249 FDUtils::WriteToBlocking(
249 exec_control_fd, &child_errno, sizeof(child_errno)); 250 exec_control_fd, &child_errno, sizeof(child_errno));
250 if (bytes_written == sizeof(child_errno)) { 251 if (bytes_written == sizeof(child_errno)) {
251 FDUtils::WriteToBlocking( 252 FDUtils::WriteToBlocking(
252 exec_control_fd, os_error_message, strlen(os_error_message) + 1); 253 exec_control_fd, os_error_message, strlen(os_error_message) + 1);
253 } 254 }
254 TEMP_FAILURE_RETRY(close(exec_control_fd)); 255 VOID_TEMP_FAILURE_RETRY(close(exec_control_fd));
255 exit(1); 256 exit(1);
256 } 257 }
257 258
258 259
259 int Process::Start(const char* path, 260 int Process::Start(const char* path,
260 char* arguments[], 261 char* arguments[],
261 intptr_t arguments_length, 262 intptr_t arguments_length,
262 const char* working_directory, 263 const char* working_directory,
263 char* environment[], 264 char* environment[],
264 intptr_t environment_length, 265 intptr_t environment_length,
(...skipping 14 matching lines...) Expand all
279 if (result < 0) { 280 if (result < 0) {
280 SetChildOsErrorMessage(os_error_message); 281 SetChildOsErrorMessage(os_error_message);
281 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 282 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
282 return errno; 283 return errno;
283 } 284 }
284 FDUtils::SetCloseOnExec(read_in[0]); 285 FDUtils::SetCloseOnExec(read_in[0]);
285 286
286 result = TEMP_FAILURE_RETRY(pipe(read_err)); 287 result = TEMP_FAILURE_RETRY(pipe(read_err));
287 if (result < 0) { 288 if (result < 0) {
288 SetChildOsErrorMessage(os_error_message); 289 SetChildOsErrorMessage(os_error_message);
289 TEMP_FAILURE_RETRY(close(read_in[0])); 290 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
290 TEMP_FAILURE_RETRY(close(read_in[1])); 291 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
291 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 292 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
292 return errno; 293 return errno;
293 } 294 }
294 FDUtils::SetCloseOnExec(read_err[0]); 295 FDUtils::SetCloseOnExec(read_err[0]);
295 296
296 result = TEMP_FAILURE_RETRY(pipe(write_out)); 297 result = TEMP_FAILURE_RETRY(pipe(write_out));
297 if (result < 0) { 298 if (result < 0) {
298 SetChildOsErrorMessage(os_error_message); 299 SetChildOsErrorMessage(os_error_message);
299 TEMP_FAILURE_RETRY(close(read_in[0])); 300 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
300 TEMP_FAILURE_RETRY(close(read_in[1])); 301 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
301 TEMP_FAILURE_RETRY(close(read_err[0])); 302 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
302 TEMP_FAILURE_RETRY(close(read_err[1])); 303 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
303 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 304 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
304 return errno; 305 return errno;
305 } 306 }
306 FDUtils::SetCloseOnExec(write_out[1]); 307 FDUtils::SetCloseOnExec(write_out[1]);
307 308
308 result = TEMP_FAILURE_RETRY(pipe(exec_control)); 309 result = TEMP_FAILURE_RETRY(pipe(exec_control));
309 if (result < 0) { 310 if (result < 0) {
310 SetChildOsErrorMessage(os_error_message); 311 SetChildOsErrorMessage(os_error_message);
311 TEMP_FAILURE_RETRY(close(read_in[0])); 312 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
312 TEMP_FAILURE_RETRY(close(read_in[1])); 313 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
313 TEMP_FAILURE_RETRY(close(read_err[0])); 314 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
314 TEMP_FAILURE_RETRY(close(read_err[1])); 315 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
315 TEMP_FAILURE_RETRY(close(write_out[0])); 316 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
316 TEMP_FAILURE_RETRY(close(write_out[1])); 317 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
317 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 318 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
318 return errno; 319 return errno;
319 } 320 }
320 FDUtils::SetCloseOnExec(exec_control[0]); 321 FDUtils::SetCloseOnExec(exec_control[0]);
321 FDUtils::SetCloseOnExec(exec_control[1]); 322 FDUtils::SetCloseOnExec(exec_control[1]);
322 323
323 if (result < 0) { 324 if (result < 0) {
324 SetChildOsErrorMessage(os_error_message); 325 SetChildOsErrorMessage(os_error_message);
325 TEMP_FAILURE_RETRY(close(read_in[0])); 326 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
326 TEMP_FAILURE_RETRY(close(read_in[1])); 327 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
327 TEMP_FAILURE_RETRY(close(read_err[0])); 328 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
328 TEMP_FAILURE_RETRY(close(read_err[1])); 329 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
329 TEMP_FAILURE_RETRY(close(write_out[0])); 330 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
330 TEMP_FAILURE_RETRY(close(write_out[1])); 331 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
331 TEMP_FAILURE_RETRY(close(exec_control[0])); 332 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
332 TEMP_FAILURE_RETRY(close(exec_control[1])); 333 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
333 Log::PrintErr("fcntl failed: %s\n", *os_error_message); 334 Log::PrintErr("fcntl failed: %s\n", *os_error_message);
334 return errno; 335 return errno;
335 } 336 }
336 337
337 char** program_arguments = new char*[arguments_length + 2]; 338 char** program_arguments = new char*[arguments_length + 2];
338 program_arguments[0] = const_cast<char*>(path); 339 program_arguments[0] = const_cast<char*>(path);
339 for (int i = 0; i < arguments_length; i++) { 340 for (int i = 0; i < arguments_length; i++) {
340 program_arguments[i + 1] = arguments[i]; 341 program_arguments[i + 1] = arguments[i];
341 } 342 }
342 program_arguments[arguments_length + 1] = NULL; 343 program_arguments[arguments_length + 1] = NULL;
343 344
344 char** program_environment = NULL; 345 char** program_environment = NULL;
345 if (environment != NULL) { 346 if (environment != NULL) {
346 program_environment = new char*[environment_length + 1]; 347 program_environment = new char*[environment_length + 1];
347 for (int i = 0; i < environment_length; i++) { 348 for (int i = 0; i < environment_length; i++) {
348 program_environment[i] = environment[i]; 349 program_environment[i] = environment[i];
349 } 350 }
350 program_environment[environment_length] = NULL; 351 program_environment[environment_length] = NULL;
351 } 352 }
352 353
353 pid = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fork()); 354 pid = TEMP_FAILURE_RETRY(fork());
354 if (pid < 0) { 355 if (pid < 0) {
355 SetChildOsErrorMessage(os_error_message); 356 SetChildOsErrorMessage(os_error_message);
356 delete[] program_arguments; 357 delete[] program_arguments;
357 TEMP_FAILURE_RETRY(close(read_in[0])); 358 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
358 TEMP_FAILURE_RETRY(close(read_in[1])); 359 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
359 TEMP_FAILURE_RETRY(close(read_err[0])); 360 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
360 TEMP_FAILURE_RETRY(close(read_err[1])); 361 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
361 TEMP_FAILURE_RETRY(close(write_out[0])); 362 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
362 TEMP_FAILURE_RETRY(close(write_out[1])); 363 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
363 TEMP_FAILURE_RETRY(close(exec_control[0])); 364 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
364 TEMP_FAILURE_RETRY(close(exec_control[1])); 365 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
365 return errno; 366 return errno;
366 } else if (pid == 0) { 367 } else if (pid == 0) {
367 // Wait for parent process before setting up the child process. 368 // Wait for parent process before setting up the child process.
368 char msg; 369 char msg;
369 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg)); 370 int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg));
370 if (bytes_read != sizeof(msg)) { 371 if (bytes_read != sizeof(msg)) {
371 perror("Failed receiving notification message"); 372 perror("Failed receiving notification message");
372 exit(1); 373 exit(1);
373 } 374 }
374 375
375 TEMP_FAILURE_RETRY(close(write_out[1])); 376 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
376 TEMP_FAILURE_RETRY(close(read_in[0])); 377 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
377 TEMP_FAILURE_RETRY(close(read_err[0])); 378 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
378 TEMP_FAILURE_RETRY(close(exec_control[0])); 379 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
379 380
380 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) { 381 if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
381 ReportChildError(exec_control[1]); 382 ReportChildError(exec_control[1]);
382 } 383 }
383 TEMP_FAILURE_RETRY(close(write_out[0])); 384 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
384 385
385 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) { 386 if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
386 ReportChildError(exec_control[1]); 387 ReportChildError(exec_control[1]);
387 } 388 }
388 TEMP_FAILURE_RETRY(close(read_in[1])); 389 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
389 390
390 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) { 391 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
391 ReportChildError(exec_control[1]); 392 ReportChildError(exec_control[1]);
392 } 393 }
393 TEMP_FAILURE_RETRY(close(read_err[1])); 394 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
394 395
395 if (working_directory != NULL && 396 if (working_directory != NULL &&
396 TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) { 397 TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
397 ReportChildError(exec_control[1]); 398 ReportChildError(exec_control[1]);
398 } 399 }
399 400
400 if (program_environment != NULL) { 401 if (program_environment != NULL) {
401 environ = program_environment; 402 environ = program_environment;
402 } 403 }
403 404
404 TEMP_FAILURE_RETRY( 405 TEMP_FAILURE_RETRY(
405 execvp(path, const_cast<char* const*>(program_arguments))); 406 execvp(path, const_cast<char* const*>(program_arguments)));
406 407
407 ReportChildError(exec_control[1]); 408 ReportChildError(exec_control[1]);
408 } 409 }
409 410
410 // Be sure to listen for exit-codes, now we have a child-process. 411 // Be sure to listen for exit-codes, now we have a child-process.
411 ExitCodeHandler::ProcessStarted(); 412 ExitCodeHandler::ProcessStarted();
412 413
413 // The arguments and environment for the spawned process are not needed 414 // The arguments and environment for the spawned process are not needed
414 // any longer. 415 // any longer.
415 delete[] program_arguments; 416 delete[] program_arguments;
416 delete[] program_environment; 417 delete[] program_environment;
417 418
418 int event_fds[2]; 419 int event_fds[2];
419 result = TEMP_FAILURE_RETRY(pipe(event_fds)); 420 result = TEMP_FAILURE_RETRY(pipe(event_fds));
420 if (result < 0) { 421 if (result < 0) {
421 SetChildOsErrorMessage(os_error_message); 422 SetChildOsErrorMessage(os_error_message);
422 TEMP_FAILURE_RETRY(close(read_in[0])); 423 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
423 TEMP_FAILURE_RETRY(close(read_in[1])); 424 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
424 TEMP_FAILURE_RETRY(close(read_err[0])); 425 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
425 TEMP_FAILURE_RETRY(close(read_err[1])); 426 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
426 TEMP_FAILURE_RETRY(close(write_out[0])); 427 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
427 TEMP_FAILURE_RETRY(close(write_out[1])); 428 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
428 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 429 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
429 return errno; 430 return errno;
430 } 431 }
431 FDUtils::SetCloseOnExec(event_fds[0]); 432 FDUtils::SetCloseOnExec(event_fds[0]);
432 FDUtils::SetCloseOnExec(event_fds[1]); 433 FDUtils::SetCloseOnExec(event_fds[1]);
433 434
434 ProcessInfoList::AddProcess(pid, event_fds[1]); 435 ProcessInfoList::AddProcess(pid, event_fds[1]);
435 *exit_event = event_fds[0]; 436 *exit_event = event_fds[0];
436 FDUtils::SetNonBlocking(event_fds[0]); 437 FDUtils::SetNonBlocking(event_fds[0]);
437 438
438 // Notify child process to start. 439 // Notify child process to start.
439 char msg = '1'; 440 char msg = '1';
440 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg)); 441 result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg));
441 if (result != sizeof(msg)) { 442 if (result != sizeof(msg)) {
442 perror("Failed sending notification message"); 443 perror("Failed sending notification message");
443 } 444 }
444 445
445 // Read exec result from child. If no data is returned the exec was 446 // Read exec result from child. If no data is returned the exec was
446 // successful and the exec call closed the pipe. Otherwise the errno 447 // successful and the exec call closed the pipe. Otherwise the errno
447 // is written to the pipe. 448 // is written to the pipe.
448 TEMP_FAILURE_RETRY(close(exec_control[1])); 449 VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
449 int child_errno; 450 int child_errno;
450 int bytes_read = -1; 451 int bytes_read = -1;
451 ASSERT(sizeof(child_errno) == sizeof(errno)); 452 ASSERT(sizeof(child_errno) == sizeof(errno));
452 bytes_read = 453 bytes_read =
453 FDUtils::ReadFromBlocking( 454 FDUtils::ReadFromBlocking(
454 exec_control[0], &child_errno, sizeof(child_errno)); 455 exec_control[0], &child_errno, sizeof(child_errno));
455 if (bytes_read == sizeof(child_errno)) { 456 if (bytes_read == sizeof(child_errno)) {
456 static const int kMaxMessageSize = 256; 457 static const int kMaxMessageSize = 256;
457 char* message = static_cast<char*>(malloc(kMaxMessageSize)); 458 char* message = static_cast<char*>(malloc(kMaxMessageSize));
458 bytes_read = FDUtils::ReadFromBlocking(exec_control[0], 459 bytes_read = FDUtils::ReadFromBlocking(exec_control[0],
459 message, 460 message,
460 kMaxMessageSize); 461 kMaxMessageSize);
461 message[kMaxMessageSize - 1] = '\0'; 462 message[kMaxMessageSize - 1] = '\0';
462 *os_error_message = message; 463 *os_error_message = message;
463 } 464 }
464 TEMP_FAILURE_RETRY(close(exec_control[0])); 465 VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
465 466
466 // Return error code if any failures. 467 // Return error code if any failures.
467 if (bytes_read != 0) { 468 if (bytes_read != 0) {
468 TEMP_FAILURE_RETRY(close(read_in[0])); 469 VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
469 TEMP_FAILURE_RETRY(close(read_in[1])); 470 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
470 TEMP_FAILURE_RETRY(close(read_err[0])); 471 VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
471 TEMP_FAILURE_RETRY(close(read_err[1])); 472 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
472 TEMP_FAILURE_RETRY(close(write_out[0])); 473 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
473 TEMP_FAILURE_RETRY(close(write_out[1])); 474 VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
474 475
475 // Since exec() failed, we're not interested in the exit code. 476 // Since exec() failed, we're not interested in the exit code.
476 // We close the reading side of the exit code pipe here. 477 // We close the reading side of the exit code pipe here.
477 // GetProcessExitCodes will get a broken pipe error when it tries to write 478 // GetProcessExitCodes will get a broken pipe error when it tries to write
478 // to the writing side of the pipe and it will ignore the error. 479 // to the writing side of the pipe and it will ignore the error.
479 TEMP_FAILURE_RETRY(close(*exit_event)); 480 VOID_TEMP_FAILURE_RETRY(close(*exit_event));
480 *exit_event = -1; 481 *exit_event = -1;
481 482
482 if (bytes_read == -1) { 483 if (bytes_read == -1) {
483 return errno; // Read failed. 484 return errno; // Read failed.
484 } else { 485 } else {
485 return child_errno; // Exec failed. 486 return child_errno; // Exec failed.
486 } 487 }
487 } 488 }
488 489
489 FDUtils::SetNonBlocking(read_in[0]); 490 FDUtils::SetNonBlocking(read_in[0]);
490 *in = read_in[0]; 491 *in = read_in[0];
491 TEMP_FAILURE_RETRY(close(read_in[1])); 492 VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
492 FDUtils::SetNonBlocking(write_out[1]); 493 FDUtils::SetNonBlocking(write_out[1]);
493 *out = write_out[1]; 494 *out = write_out[1];
494 TEMP_FAILURE_RETRY(close(write_out[0])); 495 VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
495 FDUtils::SetNonBlocking(read_err[0]); 496 FDUtils::SetNonBlocking(read_err[0]);
496 *err = read_err[0]; 497 *err = read_err[0];
497 TEMP_FAILURE_RETRY(close(read_err[1])); 498 VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
498 499
499 *id = pid; 500 *id = pid;
500 return 0; 501 return 0;
501 } 502 }
502 503
503 504
504 class BufferList: public BufferListBase { 505 class BufferList: public BufferListBase {
505 public: 506 public:
506 bool Read(int fd, intptr_t available) { 507 bool Read(int fd, intptr_t available) {
507 // Read all available bytes. 508 // Read all available bytes.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 intptr_t Process::SetSignalHandler(intptr_t signal) { 668 intptr_t Process::SetSignalHandler(intptr_t signal) {
668 bool found = false; 669 bool found = false;
669 for (int i = 0; i < kSignalsCount; i++) { 670 for (int i = 0; i < kSignalsCount; i++) {
670 if (kSignals[i] == signal) { 671 if (kSignals[i] == signal) {
671 found = true; 672 found = true;
672 break; 673 break;
673 } 674 }
674 } 675 }
675 if (!found) return -1; 676 if (!found) return -1;
676 int fds[2]; 677 int fds[2];
677 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(pipe(fds)) != 0) { 678 if (NO_RETRY_EXPECTED(pipe(fds)) != 0) {
678 return -1; 679 return -1;
679 } 680 }
680 if (!FDUtils::SetNonBlocking(fds[0])) { 681 if (!FDUtils::SetNonBlocking(fds[0])) {
681 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0])); 682 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
682 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1])); 683 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
683 return -1; 684 return -1;
684 } 685 }
685 ThreadSignalBlocker blocker(kSignalsCount, kSignals); 686 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
686 MutexLocker lock(signal_mutex); 687 MutexLocker lock(signal_mutex);
687 SignalInfo* handler = signal_handlers; 688 SignalInfo* handler = signal_handlers;
688 bool listen = true; 689 bool listen = true;
689 while (handler != NULL) { 690 while (handler != NULL) {
690 if (handler->signal() == signal) { 691 if (handler->signal() == signal) {
691 listen = false; 692 listen = false;
692 break; 693 break;
693 } 694 }
694 handler = handler->next(); 695 handler = handler->next();
695 } 696 }
696 if (listen) { 697 if (listen) {
697 struct sigaction act; 698 struct sigaction act;
698 bzero(&act, sizeof(act)); 699 bzero(&act, sizeof(act));
699 act.sa_handler = SignalHandler; 700 act.sa_handler = SignalHandler;
700 sigemptyset(&act.sa_mask); 701 sigemptyset(&act.sa_mask);
701 for (int i = 0; i < kSignalsCount; i++) { 702 for (int i = 0; i < kSignalsCount; i++) {
702 sigaddset(&act.sa_mask, kSignals[i]); 703 sigaddset(&act.sa_mask, kSignals[i]);
703 } 704 }
704 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 705 int status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
705 sigaction(signal, &act, NULL));
706 if (status < 0) { 706 if (status < 0) {
707 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0])); 707 VOID_TEMP_FAILURE_RETRY(close(fds[0]));
708 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1])); 708 VOID_TEMP_FAILURE_RETRY(close(fds[1]));
709 return -1; 709 return -1;
710 } 710 }
711 } 711 }
712 if (signal_handlers == NULL) { 712 if (signal_handlers == NULL) {
713 signal_handlers = new SignalInfo(fds[1], signal); 713 signal_handlers = new SignalInfo(fds[1], signal);
714 } else { 714 } else {
715 new SignalInfo(fds[1], signal, signal_handlers); 715 new SignalInfo(fds[1], signal, signal_handlers);
716 } 716 }
717 return fds[0]; 717 return fds[0];
718 } 718 }
(...skipping 16 matching lines...) Expand all
735 } 735 }
736 } 736 }
737 SignalInfo* next = handler->next(); 737 SignalInfo* next = handler->next();
738 if (remove) delete handler; 738 if (remove) delete handler;
739 handler = next; 739 handler = next;
740 } 740 }
741 if (unlisten) { 741 if (unlisten) {
742 struct sigaction act; 742 struct sigaction act;
743 bzero(&act, sizeof(act)); 743 bzero(&act, sizeof(act));
744 act.sa_handler = SIG_DFL; 744 act.sa_handler = SIG_DFL;
745 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL)); 745 VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
746 } 746 }
747 } 747 }
748 748
749 } // namespace bin 749 } // namespace bin
750 } // namespace dart 750 } // namespace dart
751 751
752 #endif // defined(TARGET_OS_ANDROID) 752 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « runtime/bin/file_system_watcher_macos.cc ('k') | runtime/bin/process_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698