summaryrefslogtreecommitdiffstats
path: root/src/process_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process_manager.c')
-rw-r--r--src/process_manager.c220
1 files changed, 0 insertions, 220 deletions
diff --git a/src/process_manager.c b/src/process_manager.c
deleted file mode 100644
index ad3ea33..0000000
--- a/src/process_manager.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2021 Collabora Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "app_launcher.h"
-#include "process_manager.h"
-
-struct _ProcessManager {
- GObject parent_instance;
-
- GList *process_data;
-};
-
-G_DEFINE_TYPE(ProcessManager, process_manager, G_TYPE_OBJECT);
-
-enum {
- STARTED,
- TERMINATED,
- N_SIGNALS
-};
-static guint signals[N_SIGNALS];
-
-/*
- * Application info structure, used for storing relevant data
- * in the `running_apps` list
- */
-struct process_runtime_data {
- guint watcher;
- GPid pid;
- const gchar *app_id;
-};
-
-/*
- * Initialization & cleanup functions
- */
-
-static void process_manager_dispose(GObject *object)
-{
- ProcessManager *self = APPLAUNCHD_PROCESS_MANAGER(object);
-
- g_return_if_fail(APPLAUNCHD_IS_PROCESS_MANAGER(self));
-
- if (self->process_data)
- g_list_free_full(g_steal_pointer(&self->process_data), g_free);
-
- G_OBJECT_CLASS(process_manager_parent_class)->dispose(object);
-}
-
-static void process_manager_finalize(GObject *object)
-{
- G_OBJECT_CLASS(process_manager_parent_class)->finalize(object);
-}
-
-static void process_manager_class_init(ProcessManagerClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *)klass;
-
- object_class->dispose = process_manager_dispose;
- object_class->finalize = process_manager_finalize;
-
- signals[STARTED] = g_signal_new("started", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0 ,
- NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_STRING);
-
- signals[TERMINATED] = g_signal_new("terminated", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0 ,
- NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_STRING);
-}
-
-static void process_manager_init(ProcessManager *self)
-{
-}
-
-/*
- * Internal functions
- */
-
-static const gchar *get_app_id_for_pid(ProcessManager *self, GPid pid)
-{
- g_return_val_if_fail(APPLAUNCHD_IS_PROCESS_MANAGER(self), NULL);
-
- AppLauncher *app_launcher = app_launcher_get_default();
- guint len = g_list_length(self->process_data);
-
- for (guint i = 0; i < len; i++) {
- struct process_runtime_data *runtime_data =
- g_list_nth_data(self->process_data, i);
-
- if (runtime_data->pid == pid)
- return runtime_data->app_id;
- }
-
- return NULL;
-}
-
-/*
- * Internal callbacks
- */
-
-/*
- * This function is called when a watched process terminated, so we can:
- * - cleanup this application's data (and reap the process so it
- * doesn't become a zombie)
- * - notify listeners that the process terminated
- */
-static void process_manager_app_terminated_cb(GPid pid,
- gint wait_status,
- gpointer data)
-{
- ProcessManager *self = data;
- AppLauncher *app_launcher = app_launcher_get_default();
- struct process_runtime_data *runtime_data;
- const gchar *app_id;
- AppInfo *app_info;
-
- g_return_if_fail(APPLAUNCHD_IS_PROCESS_MANAGER(self));
-
- app_id = get_app_id_for_pid(self, pid);
- if (!app_id) {
- g_warning("Unable to retrieve app id for pid %d", pid);
- return;
- }
-
- app_info = app_launcher_get_app_info(app_launcher, app_id);
- if (!app_info) {
- g_warning("Unable to find running app with pid %d", pid);
- return;
- }
-
- if (g_spawn_check_exit_status(wait_status, NULL))
- g_debug("Application '%s' terminated with exit code %i",
- app_id, WEXITSTATUS(wait_status));
- else
- g_warning("Application '%s' crashed", app_id);
-
- g_spawn_close_pid(pid);
-
- runtime_data = app_info_get_runtime_data(app_info);
- g_source_remove(runtime_data->watcher);
-
- app_info_set_status(app_info, APP_STATUS_INACTIVE);
- app_info_set_runtime_data(app_info, NULL);
-
- self->process_data = g_list_remove(self->process_data, runtime_data);
- g_free(runtime_data);
-
- g_signal_emit(self, signals[TERMINATED], 0, app_id);
-}
-
-/*
- * Public functions
- */
-
-ProcessManager *process_manager_new(void)
-{
- return g_object_new(APPLAUNCHD_TYPE_PROCESS_MANAGER, NULL);
-}
-
-/*
- * Start an application by executing the provided command line.
- */
-gboolean process_manager_start_app(ProcessManager *self,
- AppInfo *app_info)
-{
- g_return_val_if_fail(APPLAUNCHD_IS_PROCESS_MANAGER(self), FALSE);
- g_return_val_if_fail(APPLAUNCHD_IS_APP_INFO(app_info), FALSE);
-
- gboolean success;
- g_autofree GStrv args = NULL;
- const gchar *app_id = app_info_get_app_id(app_info);
- const gchar *command = app_info_get_command(app_info);
- struct process_runtime_data *runtime_data;
-
- runtime_data = g_new0(struct process_runtime_data, 1);
- if (!runtime_data) {
- g_critical("Unable to allocate runtime data structure for '%s'",
- app_id);
- return FALSE;
- }
-
- runtime_data->app_id = app_id;
-
- args = g_strsplit(command, " ", -1);
- success = g_spawn_async(NULL, args, NULL,
- G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
- NULL, NULL, &runtime_data->pid, NULL);
- if (!success) {
- g_critical("Unable to start application '%s'", app_id);
- g_free(runtime_data);
- return FALSE;
- }
-
- /*
- * Add a watcher for the child PID in order to get notified when it dies
- */
- runtime_data->watcher = g_child_watch_add(runtime_data->pid,
- process_manager_app_terminated_cb,
- self);
- self->process_data = g_list_append(self->process_data, runtime_data);
- app_info_set_runtime_data(app_info, runtime_data);
- app_info_set_status(app_info, APP_STATUS_RUNNING);
-
- g_signal_emit(self, signals[STARTED], 0, app_id);
-
- return TRUE;
-}