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

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

Issue 2619233003: Fuchsia: Adds support for Process.kill() (Closed)
Patch Set: Remove whitespace Created 3 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
« no previous file with comments | « no previous file | runtime/tests/vm/dart/hello_fuchsia_test.dart » ('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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_FUCHSIA) 8 #if defined(TARGET_OS_FUCHSIA)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 // ProcessInfoList. 54 // ProcessInfoList.
55 class ProcessInfo { 55 class ProcessInfo {
56 public: 56 public:
57 ProcessInfo(mx_handle_t process, intptr_t fd) 57 ProcessInfo(mx_handle_t process, intptr_t fd)
58 : process_(process), exit_pipe_fd_(fd) {} 58 : process_(process), exit_pipe_fd_(fd) {}
59 ~ProcessInfo() { 59 ~ProcessInfo() {
60 int closed = NO_RETRY_EXPECTED(close(exit_pipe_fd_)); 60 int closed = NO_RETRY_EXPECTED(close(exit_pipe_fd_));
61 if (closed != 0) { 61 if (closed != 0) {
62 FATAL("Failed to close process exit code pipe"); 62 FATAL("Failed to close process exit code pipe");
63 } 63 }
64 mx_handle_close(process_);
64 } 65 }
65 mx_handle_t process() const { return process_; } 66 mx_handle_t process() const { return process_; }
66 intptr_t exit_pipe_fd() const { return exit_pipe_fd_; } 67 intptr_t exit_pipe_fd() const { return exit_pipe_fd_; }
67 ProcessInfo* next() const { return next_; } 68 ProcessInfo* next() const { return next_; }
68 void set_next(ProcessInfo* info) { next_ = info; } 69 void set_next(ProcessInfo* info) { next_ = info; }
69 70
70 private: 71 private:
71 mx_handle_t process_; 72 mx_handle_t process_;
72 intptr_t exit_pipe_fd_; 73 intptr_t exit_pipe_fd_;
73 ProcessInfo* next_; 74 ProcessInfo* next_;
74 75
75 DISALLOW_COPY_AND_ASSIGN(ProcessInfo); 76 DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
76 }; 77 };
77 78
78 79
79 // Singly-linked list of ProcessInfo objects for all active processes 80 // Singly-linked list of ProcessInfo objects for all active processes
80 // started from Dart. 81 // started from Dart.
81 class ProcessInfoList { 82 class ProcessInfoList {
82 public: 83 public:
83 static void AddProcess(mx_handle_t process, intptr_t fd) { 84 static void AddProcess(mx_handle_t process, intptr_t fd) {
84 MutexLocker locker(mutex_); 85 MutexLocker locker(mutex_);
85 ProcessInfo* info = new ProcessInfo(process, fd); 86 ProcessInfo* info = new ProcessInfo(process, fd);
86 info->set_next(active_processes_); 87 info->set_next(active_processes_);
87 active_processes_ = info; 88 active_processes_ = info;
88 } 89 }
89 90
90
91 static intptr_t LookupProcessExitFd(mx_handle_t process) { 91 static intptr_t LookupProcessExitFd(mx_handle_t process) {
92 MutexLocker locker(mutex_); 92 MutexLocker locker(mutex_);
93 ProcessInfo* current = active_processes_; 93 ProcessInfo* current = active_processes_;
94 while (current != NULL) { 94 while (current != NULL) {
95 if (current->process() == process) { 95 if (current->process() == process) {
96 return current->exit_pipe_fd(); 96 return current->exit_pipe_fd();
97 } 97 }
98 current = current->next(); 98 current = current->next();
99 } 99 }
100 return 0; 100 return 0;
101 } 101 }
102 102
103 static bool Exists(mx_handle_t process) {
104 return LookupProcessExitFd(process) != 0;
105 }
103 106
104 static void RemoveProcess(mx_handle_t process) { 107 static void RemoveProcess(mx_handle_t process) {
105 MutexLocker locker(mutex_); 108 MutexLocker locker(mutex_);
106 ProcessInfo* prev = NULL; 109 ProcessInfo* prev = NULL;
107 ProcessInfo* current = active_processes_; 110 ProcessInfo* current = active_processes_;
108 while (current != NULL) { 111 while (current != NULL) {
109 if (current->process() == process) { 112 if (current->process() == process) {
110 if (prev == NULL) { 113 if (prev == NULL) {
111 active_processes_ = current->next(); 114 active_processes_ = current->next();
112 } else { 115 } else {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 mx_status_get_string(status)); 301 mx_status_get_string(status));
299 } 302 }
300 LOG_INFO("ExitCodeHandler thread process %ld exited with %d\n", process, 303 LOG_INFO("ExitCodeHandler thread process %ld exited with %d\n", process,
301 return_code); 304 return_code);
302 305
303 const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process); 306 const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process);
304 LOG_INFO("ExitCodeHandler thread sending %ld code %d on fd %ld\n", process, 307 LOG_INFO("ExitCodeHandler thread sending %ld code %d on fd %ld\n", process,
305 return_code, exit_code_fd); 308 return_code, exit_code_fd);
306 if (exit_code_fd != 0) { 309 if (exit_code_fd != 0) {
307 int exit_message[2]; 310 int exit_message[2];
308 exit_message[0] = return_code; 311 exit_message[0] = abs(return_code);
309 exit_message[1] = 0; // Do not negate return_code. 312 exit_message[1] = return_code >= 0 ? 0 : 1;
310 intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message, 313 intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message,
311 sizeof(exit_message)); 314 sizeof(exit_message));
312 ASSERT((result == -1) || (result == sizeof(exit_code_fd))); 315 ASSERT((result == -1) || (result == sizeof(exit_code_fd)));
313 if ((result == -1) && (errno != EPIPE)) { 316 if ((result == -1) && (errno != EPIPE)) {
314 int err = errno; 317 int err = errno;
315 FATAL1("Failed to write exit code to pipe: %d\n", err); 318 FATAL1("Failed to write exit code to pipe: %d\n", err);
316 } 319 }
317 LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result, 320 LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result,
318 exit_code_fd); 321 exit_code_fd);
319 LOG_INFO("ExitCodeHandler thread removing process %ld from list\n", 322 LOG_INFO("ExitCodeHandler thread removing process %ld from list\n",
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 DEBUG_ASSERT(err_data.IsEmpty()); 547 DEBUG_ASSERT(err_data.IsEmpty());
545 548
546 // Calculate the exit code. 549 // Calculate the exit code.
547 intptr_t exit_code = exit_code_data.ints[0]; 550 intptr_t exit_code = exit_code_data.ints[0];
548 intptr_t negative = exit_code_data.ints[1]; 551 intptr_t negative = exit_code_data.ints[1];
549 if (negative != 0) { 552 if (negative != 0) {
550 exit_code = -exit_code; 553 exit_code = -exit_code;
551 } 554 }
552 result->set_exit_code(exit_code); 555 result->set_exit_code(exit_code);
553 556
557 // Close the process handle.
558 mx_handle_t process = static_cast<mx_handle_t>(pid);
559 mx_handle_close(process);
554 return true; 560 return true;
555 } 561 }
556 562
557 563
558 bool Process::Kill(intptr_t id, int signal) { 564 bool Process::Kill(intptr_t id, int signal) {
559 errno = ENOSYS; 565 LOG_INFO("Sending signal %d to process with id %ld\n", signal, id);
560 return false; 566 // mx_task_kill is definitely going to kill the process.
567 if ((signal != SIGTERM) && (signal != SIGKILL)) {
568 LOG_ERR("Signal %d not supported\n", signal);
569 errno = ENOSYS;
570 return false;
571 }
572 // We can only use mx_task_kill if we know id is a process handle, and we only
573 // know that for sure if it's in our list.
574 mx_handle_t process = static_cast<mx_handle_t>(id);
575 if (!ProcessInfoList::Exists(process)) {
576 LOG_ERR("Process %ld wasn't in the ProcessInfoList\n", id);
577 errno = ESRCH; // No such process.
578 return false;
579 }
580 mx_status_t status = mx_task_kill(process);
581 if (status != NO_ERROR) {
582 LOG_ERR("mx_task_kill failed: %s\n", mx_status_get_string(status));
583 errno = EPERM; // TODO(zra): Figure out what it really should be.
584 return false;
585 }
586 LOG_INFO("Signal %d sent successfully to process %ld\n", signal, id);
587 return true;
561 } 588 }
562 589
563 590
564 class ProcessStarter { 591 class ProcessStarter {
565 public: 592 public:
566 ProcessStarter(const char* path, 593 ProcessStarter(const char* path,
567 char* arguments[], 594 char* arguments[],
568 intptr_t arguments_length, 595 intptr_t arguments_length,
569 const char* working_directory, 596 const char* working_directory,
570 char* environment[], 597 char* environment[],
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 void Process::ClearSignalHandler(intptr_t signal) { 839 void Process::ClearSignalHandler(intptr_t signal) {
813 UNIMPLEMENTED(); 840 UNIMPLEMENTED();
814 } 841 }
815 842
816 } // namespace bin 843 } // namespace bin
817 } // namespace dart 844 } // namespace dart
818 845
819 #endif // defined(TARGET_OS_FUCHSIA) 846 #endif // defined(TARGET_OS_FUCHSIA)
820 847
821 #endif // !defined(DART_IO_DISABLED) 848 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « no previous file | runtime/tests/vm/dart/hello_fuchsia_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698