Index: runtime/bin/process_fuchsia.cc |
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc |
index 88b115abf8dda9691151e2b559131fae9a8344a8..422816140bc0a7d5fa03c78489c9f8196eabbb52 100644 |
--- a/runtime/bin/process_fuchsia.cc |
+++ b/runtime/bin/process_fuchsia.cc |
@@ -61,6 +61,7 @@ class ProcessInfo { |
if (closed != 0) { |
FATAL("Failed to close process exit code pipe"); |
} |
+ mx_handle_close(process_); |
} |
mx_handle_t process() const { return process_; } |
intptr_t exit_pipe_fd() const { return exit_pipe_fd_; } |
@@ -87,7 +88,6 @@ class ProcessInfoList { |
active_processes_ = info; |
} |
- |
static intptr_t LookupProcessExitFd(mx_handle_t process) { |
MutexLocker locker(mutex_); |
ProcessInfo* current = active_processes_; |
@@ -100,6 +100,9 @@ class ProcessInfoList { |
return 0; |
} |
+ static bool Exists(mx_handle_t process) { |
+ return LookupProcessExitFd(process) != 0; |
+ } |
static void RemoveProcess(mx_handle_t process) { |
MutexLocker locker(mutex_); |
@@ -305,8 +308,8 @@ class ExitCodeHandler { |
return_code, exit_code_fd); |
if (exit_code_fd != 0) { |
int exit_message[2]; |
- exit_message[0] = return_code; |
- exit_message[1] = 0; // Do not negate return_code. |
+ exit_message[0] = abs(return_code); |
+ exit_message[1] = return_code >= 0 ? 0 : 1; |
intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message, |
sizeof(exit_message)); |
ASSERT((result == -1) || (result == sizeof(exit_code_fd))); |
@@ -551,13 +554,37 @@ bool Process::Wait(intptr_t pid, |
} |
result->set_exit_code(exit_code); |
+ // Close the process handle. |
+ mx_handle_t process = static_cast<mx_handle_t>(pid); |
+ mx_handle_close(process); |
return true; |
} |
bool Process::Kill(intptr_t id, int signal) { |
- errno = ENOSYS; |
- return false; |
+ LOG_INFO("Sending signal %d to process with id %ld\n", signal, id); |
+ // mx_task_kill is definitely going to kill the process. |
+ if ((signal != SIGTERM) && (signal != SIGKILL)) { |
+ LOG_ERR("Signal %d not supported\n", signal); |
+ errno = ENOSYS; |
+ return false; |
+ } |
+ // We can only use mx_task_kill if we know id is a process handle, and we only |
+ // know that for sure if it's in our list. |
+ mx_handle_t process = static_cast<mx_handle_t>(id); |
+ if (!ProcessInfoList::Exists(process)) { |
+ LOG_ERR("Process %ld wasn't in the ProcessInfoList\n", id); |
+ errno = ESRCH; // No such process. |
+ return false; |
+ } |
+ mx_status_t status = mx_task_kill(process); |
+ if (status != NO_ERROR) { |
+ LOG_ERR("mx_task_kill failed: %s\n", mx_status_get_string(status)); |
+ errno = EPERM; // TODO(zra): Figure out what it really should be. |
+ return false; |
+ } |
+ LOG_INFO("Signal %d sent successfully to process %ld\n", signal, id); |
+ return true; |
} |