Index: chrome/browser/chromeos/cros/input_method_library.cc |
diff --git a/chrome/browser/chromeos/cros/input_method_library.cc b/chrome/browser/chromeos/cros/input_method_library.cc |
index d02f23397d017603845fa31a251a8e2e1f5fc196..7dfbca8aa729909b811f31d41399a8afa546d1df 100644 |
--- a/chrome/browser/chromeos/cros/input_method_library.cc |
+++ b/chrome/browser/chromeos/cros/input_method_library.cc |
@@ -5,12 +5,13 @@ |
#include "chrome/browser/chromeos/cros/input_method_library.h" |
#include <glib.h> |
-#include <signal.h> |
#include "unicode/uloc.h" |
#include "base/basictypes.h" |
#include "base/message_loop.h" |
+#include "base/process_util.h" |
+#include "base/string_split.h" |
#include "base/string_util.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/chromeos/cros/cros_library.h" |
@@ -62,7 +63,7 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
defer_ime_startup_(false), |
enable_auto_ime_shutdown_(true), |
should_change_input_method_(false), |
- ibus_daemon_process_id_(0), |
+ ibus_daemon_process_handle_(base::kNullProcessHandle), |
initialized_successfully_(false), |
candidate_window_controller_(NULL) { |
// Here, we use the fallback input method descriptor but |
@@ -170,7 +171,7 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
tentative_current_input_method_id_ = input_method_id; |
// If the input method daemon is not running and the specified input |
// method is a keyboard layout, switch the keyboard directly. |
- if (ibus_daemon_process_id_ == 0 && |
+ if (ibus_daemon_process_handle_ == base::kNullProcessHandle && |
chromeos::input_method::IsKeyboardLayout(input_method_id)) { |
// We shouldn't use SetCurrentKeyboardLayoutByName() here. See |
// comments at ChangeCurrentInputMethod() for details. |
@@ -597,38 +598,36 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
} |
// Launches an input method procsess specified by the given command |
- // line. On success, returns true and stores the process ID in |
- // |process_id|. Otherwise, returns false, and the contents of |
- // |process_id| is untouched. OnImeShutdown will be called when the |
+ // line. On success, returns true and stores the process handle in |
+ // |process_handle|. Otherwise, returns false, and the contents of |
+ // |process_handle| is untouched. OnImeShutdown will be called when the |
// process terminates. |
bool LaunchInputMethodProcess(const std::string& command_line, |
- int* process_id) { |
- GError *error = NULL; |
- gchar **argv = NULL; |
- gint argc = NULL; |
- // TODO(zork): export "LD_PRELOAD=/usr/lib/libcrash.so" |
- if (!g_shell_parse_argv(command_line.c_str(), &argc, &argv, &error)) { |
- LOG(ERROR) << "Could not parse command: " << error->message; |
- g_error_free(error); |
- return false; |
- } |
+ base::ProcessHandle* process_handle) { |
+ std::vector<std::string> argv; |
+ base::file_handle_mapping_vector fds_to_remap; |
+ base::ProcessHandle handle = base::kNullProcessHandle; |
- int pid = 0; |
- const GSpawnFlags kFlags = G_SPAWN_DO_NOT_REAP_CHILD; |
- const gboolean result = g_spawn_async(NULL, argv, NULL, |
- kFlags, NULL, NULL, |
- &pid, &error); |
- g_strfreev(argv); |
+ // TODO(zork): export "LD_PRELOAD=/usr/lib/libcrash.so" |
+ base::SplitString(command_line, ' ', &argv); |
+ const bool result = base::LaunchApp(argv, |
+ fds_to_remap, // no remapping |
+ false, // wait |
+ &handle); |
if (!result) { |
- LOG(ERROR) << "Could not launch: " << command_line << ": " |
- << error->message; |
- g_error_free(error); |
+ LOG(ERROR) << "Could not launch: " << command_line; |
return false; |
} |
- g_child_watch_add(pid, reinterpret_cast<GChildWatchFunc>(OnImeShutdown), |
+ |
+ // g_child_watch_add is necessary to prevent the process from becoming a |
+ // zombie. |
+ // TODO(yusukes): port g_child_watch_add to base/process_utils_posix.cc. |
+ const base::ProcessId pid = base::GetProcId(handle); |
+ g_child_watch_add(pid, |
+ reinterpret_cast<GChildWatchFunc>(OnImeShutdown), |
this); |
- *process_id = pid; |
+ *process_handle = handle; |
VLOG(1) << command_line << " (PID=" << pid << ") is started"; |
return true; |
} |
@@ -651,25 +650,25 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
} |
} |
- if (ibus_daemon_process_id_ == 0) { |
+ if (ibus_daemon_process_handle_ == base::kNullProcessHandle) { |
// TODO(zork): Send output to /var/log/ibus.log |
const std::string ibus_daemon_command_line = |
StringPrintf("%s --panel=disable --cache=none --restart --replace", |
kIBusDaemonPath); |
if (!LaunchInputMethodProcess( |
- ibus_daemon_command_line, &ibus_daemon_process_id_)) { |
+ ibus_daemon_command_line, &ibus_daemon_process_handle_)) { |
LOG(ERROR) << "Failed to launch " << ibus_daemon_command_line; |
} |
} |
} |
// Called when the input method process is shut down. |
- static void OnImeShutdown(int pid, |
- int status, |
+ static void OnImeShutdown(GPid pid, |
+ gint status, |
InputMethodLibraryImpl* library) { |
- g_spawn_close_pid(pid); |
- if (library->ibus_daemon_process_id_ == pid) { |
- library->ibus_daemon_process_id_ = 0; |
+ if (library->ibus_daemon_process_handle_ != base::kNullProcessHandle && |
+ base::GetProcId(library->ibus_daemon_process_handle_) == pid) { |
+ library->ibus_daemon_process_handle_ = base::kNullProcessHandle; |
} |
// Restart input method daemon if needed. |
@@ -684,15 +683,15 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
return; |
should_launch_ime_ = false; |
- if (ibus_daemon_process_id_) { |
+ if (ibus_daemon_process_handle_ != base::kNullProcessHandle) { |
+ const base::ProcessId pid = base::GetProcId(ibus_daemon_process_handle_); |
if (!chromeos::StopInputMethodProcess(input_method_status_connection_)) { |
LOG(ERROR) << "StopInputMethodProcess IPC failed. Sending SIGTERM to " |
- << "PID " << ibus_daemon_process_id_; |
- kill(ibus_daemon_process_id_, SIGTERM); |
+ << "PID " << pid; |
+ base::KillProcess(ibus_daemon_process_handle_, -1, false /* wait */); |
} |
- VLOG(1) << "ibus-daemon (PID=" << ibus_daemon_process_id_ << ") is " |
- << "terminated"; |
- ibus_daemon_process_id_ = 0; |
+ VLOG(1) << "ibus-daemon (PID=" << pid << ") is terminated"; |
+ ibus_daemon_process_handle_ = base::kNullProcessHandle; |
} |
} |
@@ -765,9 +764,9 @@ class InputMethodLibraryImpl : public InputMethodLibrary, |
// requests becomes empty. |
bool should_change_input_method_; |
- // The process id of the IBus daemon. 0 if it's not running. The process |
- // ID 0 is not used in Linux, hence it's safe to use 0 for this purpose. |
- int ibus_daemon_process_id_; |
+ // The process handle of the IBus daemon. kNullProcessHandle if it's not |
+ // running. |
+ base::ProcessHandle ibus_daemon_process_handle_; |
// True if initialization is successfully done, meaning that libcros is |
// loaded and input method status monitoring is started. This value |