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

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

Issue 23428002: Fix android compilation by copying process_linux.cc to process_android.cc. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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 | 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 <signal.h> // NOLINT 13 #include <signal.h> // NOLINT
14 #include <stdio.h> // NOLINT 14 #include <stdio.h> // NOLINT
15 #include <stdlib.h> // NOLINT 15 #include <stdlib.h> // NOLINT
16 #include <string.h> // NOLINT 16 #include <string.h> // NOLINT
17 #include <sys/wait.h> // NOLINT 17 #include <sys/wait.h> // NOLINT
18 #include <unistd.h> // NOLINT 18 #include <unistd.h> // NOLINT
19 19
20 #include "bin/fdutils.h" 20 #include "bin/fdutils.h"
21 #include "bin/log.h" 21 #include "bin/log.h"
22 #include "bin/thread.h" 22 #include "bin/thread.h"
23 23
24 24
25 extern char **environ;
26
27
25 namespace dart { 28 namespace dart {
26 namespace bin { 29 namespace bin {
27 30
28 // ProcessInfo is used to map a process id to the file descriptor for 31 // ProcessInfo is used to map a process id to the file descriptor for
29 // the pipe used to communicate the exit code of the process to Dart. 32 // the pipe used to communicate the exit code of the process to Dart.
30 // ProcessInfo objects are kept in the static singly-linked 33 // ProcessInfo objects are kept in the static singly-linked
31 // ProcessInfoList. 34 // ProcessInfoList.
32 class ProcessInfo { 35 class ProcessInfo {
33 public: 36 public:
34 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 37 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 int read_in[2]; // Pipe for stdout to child process. 328 int read_in[2]; // Pipe for stdout to child process.
326 int read_err[2]; // Pipe for stderr to child process. 329 int read_err[2]; // Pipe for stderr to child process.
327 int write_out[2]; // Pipe for stdin to child process. 330 int write_out[2]; // Pipe for stdin to child process.
328 int exec_control[2]; // Pipe to get the result from exec. 331 int exec_control[2]; // Pipe to get the result from exec.
329 int result; 332 int result;
330 333
331 bool initialized = ExitCodeHandler::EnsureInitialized(); 334 bool initialized = ExitCodeHandler::EnsureInitialized();
332 if (!initialized) { 335 if (!initialized) {
333 SetChildOsErrorMessage(os_error_message); 336 SetChildOsErrorMessage(os_error_message);
334 Log::PrintErr("Error initializing exit code handler: %s\n", 337 Log::PrintErr("Error initializing exit code handler: %s\n",
335 *os_error_message); 338 *os_error_message);
336 return errno; 339 return errno;
337 } 340 }
338 341
339 result = TEMP_FAILURE_RETRY(pipe(read_in)); 342 result = TEMP_FAILURE_RETRY(pipe(read_in));
340 if (result < 0) { 343 if (result < 0) {
341 SetChildOsErrorMessage(os_error_message); 344 SetChildOsErrorMessage(os_error_message);
342 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message); 345 Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
343 return errno; 346 return errno;
344 } 347 }
345 FDUtils::SetCloseOnExec(read_in[0]); 348 FDUtils::SetCloseOnExec(read_in[0]);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) { 461 if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
459 ReportChildError(exec_control[1]); 462 ReportChildError(exec_control[1]);
460 } 463 }
461 TEMP_FAILURE_RETRY(close(read_err[1])); 464 TEMP_FAILURE_RETRY(close(read_err[1]));
462 465
463 if (working_directory != NULL && 466 if (working_directory != NULL &&
464 TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) { 467 TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
465 ReportChildError(exec_control[1]); 468 ReportChildError(exec_control[1]);
466 } 469 }
467 470
468 if (environment != NULL) { 471 if (program_environment != NULL) {
469 TEMP_FAILURE_RETRY( 472 environ = program_environment;
470 execve(path,
471 const_cast<char* const*>(program_arguments),
472 program_environment));
473 } else {
474 TEMP_FAILURE_RETRY(
475 execvp(path, const_cast<char* const*>(program_arguments)));
476 } 473 }
474
475 TEMP_FAILURE_RETRY(
476 execvp(path, const_cast<char* const*>(program_arguments)));
477
477 ReportChildError(exec_control[1]); 478 ReportChildError(exec_control[1]);
478 } 479 }
479 480
480 // The arguments and environment for the spawned process are not needed 481 // The arguments and environment for the spawned process are not needed
481 // any longer. 482 // any longer.
482 delete[] program_arguments; 483 delete[] program_arguments;
483 delete[] program_environment; 484 delete[] program_environment;
484 485
485 int event_fds[2]; 486 int event_fds[2];
486 result = TEMP_FAILURE_RETRY(pipe(event_fds)); 487 result = TEMP_FAILURE_RETRY(pipe(event_fds));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 TEMP_FAILURE_RETRY(close(write_out[0])); 562 TEMP_FAILURE_RETRY(close(write_out[0]));
562 FDUtils::SetNonBlocking(read_err[0]); 563 FDUtils::SetNonBlocking(read_err[0]);
563 *err = read_err[0]; 564 *err = read_err[0];
564 TEMP_FAILURE_RETRY(close(read_err[1])); 565 TEMP_FAILURE_RETRY(close(read_err[1]));
565 566
566 *id = pid; 567 *id = pid;
567 return 0; 568 return 0;
568 } 569 }
569 570
570 571
572 class BufferList: public BufferListBase {
573 public:
574 bool Read(int fd, intptr_t available) {
575 // Read all available bytes.
576 while (available > 0) {
577 if (free_size_ == 0) Allocate();
578 ASSERT(free_size_ > 0);
579 ASSERT(free_size_ <= kBufferSize);
580 intptr_t block_size = dart::Utils::Minimum(free_size_, available);
581 intptr_t bytes = TEMP_FAILURE_RETRY(read(
582 fd,
583 reinterpret_cast<void*>(FreeSpaceAddress()),
584 block_size));
585 if (bytes < 0) return false;
586 data_size_ += bytes;
587 free_size_ -= bytes;
588 available -= bytes;
589 }
590 return true;
591 }
592 };
593
594
595 static bool CloseProcessBuffers(struct pollfd fds[3]) {
596 int e = errno;
597 VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
598 VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
599 VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
600 errno = e;
601 return false;
602 }
603
604
605 bool Process::Wait(intptr_t pid,
606 intptr_t in,
607 intptr_t out,
608 intptr_t err,
609 intptr_t exit_event,
610 ProcessResult* result) {
611 // Close input to the process right away.
612 VOID_TEMP_FAILURE_RETRY(close(in));
613
614 // There is no return from this function using Dart_PropagateError
615 // as memory used by the buffer lists is freed through their
616 // destructors.
617 BufferList out_data;
618 BufferList err_data;
619 union {
620 uint8_t bytes[8];
621 int32_t ints[2];
622 } exit_code_data;
623
624 struct pollfd fds[3];
625 fds[0].fd = out;
626 fds[1].fd = err;
627 fds[2].fd = exit_event;
628
629 for (int i = 0; i < 3; i++) {
630 fds[i].events = POLLIN;
631 }
632
633 int alive = 3;
634 while (alive > 0) {
635 // Blocking call waiting for events from the child process.
636 if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
637 return CloseProcessBuffers(fds);
638 }
639
640 // Process incoming data.
641 int current_alive = alive;
642 for (int i = 0; i < current_alive; i++) {
643 if (fds[i].revents & POLLIN) {
644 intptr_t avail = FDUtils::AvailableBytes(fds[i].fd);
645 if (fds[i].fd == out) {
646 if (!out_data.Read(out, avail)) {
647 return CloseProcessBuffers(fds);
648 }
649 } else if (fds[i].fd == err) {
650 if (!err_data.Read(err, avail)) {
651 return CloseProcessBuffers(fds);
652 }
653 } else if (fds[i].fd == exit_event) {
654 if (avail == 8) {
655 intptr_t b = TEMP_FAILURE_RETRY(read(exit_event,
656 exit_code_data.bytes, 8));
657 if (b != 8) {
658 return CloseProcessBuffers(fds);
659 }
660 }
661 } else {
662 UNREACHABLE();
663 }
664 }
665 if (fds[i].revents & POLLHUP) {
666 VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
667 alive--;
668 if (i < alive) {
669 fds[i] = fds[alive];
670 }
671 }
672 }
673 }
674
675 // All handles closed and all data read.
676 result->set_stdout_data(out_data.GetData());
677 result->set_stderr_data(err_data.GetData());
678
679 // Calculate the exit code.
680 intptr_t exit_code = exit_code_data.ints[0];
681 intptr_t negative = exit_code_data.ints[1];
682 if (negative) exit_code = -exit_code;
683 result->set_exit_code(exit_code);
684
685 return true;
686 }
687
688
571 bool Process::Kill(intptr_t id, int signal) { 689 bool Process::Kill(intptr_t id, int signal) {
572 int result = TEMP_FAILURE_RETRY(kill(id, signal)); 690 return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1);
573 if (result == -1) {
574 return false;
575 }
576 return true;
577 } 691 }
578 692
579 693
580 void Process::TerminateExitCodeHandler() { 694 void Process::TerminateExitCodeHandler() {
581 ExitCodeHandler::TerminateExitCodeThread(); 695 ExitCodeHandler::TerminateExitCodeThread();
582 } 696 }
583 697
584 698
585 intptr_t Process::CurrentProcessId() { 699 intptr_t Process::CurrentProcessId() {
586 return static_cast<intptr_t>(getpid()); 700 return static_cast<intptr_t>(getpid());
587 } 701 }
588 702
589 } // namespace bin 703 } // namespace bin
590 } // namespace dart 704 } // namespace dart
591 705
592 #endif // defined(TARGET_OS_ANDROID) 706 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/process_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698