OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |