From e0a0733fe56afa691e93e9e396a7fbbed6ae1002 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 28 Dec 2008 06:30:56 +0100 Subject: [PATCH] Add helpers for task handling --- plugins/task.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/task.h | 35 ++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 plugins/task.c create mode 100644 plugins/task.h diff --git a/plugins/task.c b/plugins/task.c new file mode 100644 index 0000000..dae54c7 --- /dev/null +++ b/plugins/task.c @@ -0,0 +1,145 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include + +#include "task.h" + +struct task_data { + pid_t pid; + int index; + task_cb_t callback; + void *user_data; +}; + +static GSList *task_list = NULL; + +struct task_data *task_find_by_pid(pid_t pid) +{ + GSList *list; + + for (list = task_list; list; list = list->next) { + struct task_data *task = list->data; + + if (task->pid == pid) + return task; + } + + return NULL; +} + +struct task_data *task_find_by_index(int index) +{ + GSList *list; + + for (list = task_list; list; list = list->next) { + struct task_data *task = list->data; + + if (task->index == index) + return task; + } + + return NULL; +} + +static void task_died(GPid pid, gint status, gpointer user_data) +{ + struct task_data *task = user_data; + + if (WIFEXITED(status)) + DBG("task %p exit status %d", task, WEXITSTATUS(status)); + else + DBG("task %p signal %d", task, WTERMSIG(status)); + + g_spawn_close_pid(pid); + task->pid = 0; + + task_list = g_slist_remove(task_list, task); + + if (task->callback) + task->callback(task->index, task->user_data); + + g_free(task); +} + +static void task_setup(gpointer user_data) +{ + struct task_data *task = user_data; + + DBG("task %p", task); +} + +struct task_data *task_spawn(int index, char **argv, char **envp, + task_cb_t callback, void *user_data) +{ + GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD | + G_SPAWN_STDOUT_TO_DEV_NULL; + struct task_data *task; + + DBG("index %d", index); + + task = g_try_new0(struct task_data, 1); + if (task == NULL) + return NULL; + + task->index = index; + + task->callback = callback; + task->user_data = user_data; + + if (g_spawn_async(NULL, argv, envp, flags, + task_setup, task, &task->pid, NULL) == FALSE) { + connman_error("Failed to spawn task"); + return NULL; + } + + task_list = g_slist_append(task_list, task); + + g_child_watch_add(task->pid, task_died, task); + + DBG("task %p pid %d", task, task->pid); + + return task; +} + +int task_kill(struct task_data *task) +{ + DBG("task %p", task); + + if (task->pid > 0) + kill(task->pid, SIGTERM); + + return 0; +} + +void *task_get_data(struct task_data *task) +{ + return task->user_data; +} diff --git a/plugins/task.h b/plugins/task.h new file mode 100644 index 0000000..0234d47 --- /dev/null +++ b/plugins/task.h @@ -0,0 +1,35 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +struct task_data; + +typedef void (* task_cb_t) (int index, void *user_data); + +struct task_data *task_find_by_pid(pid_t pid); +struct task_data *task_find_by_index(int index); + +struct task_data *task_spawn(int index, char **argv, char **envp, + task_cb_t callback, void *user_data); +int task_kill(struct task_data *task); + +void *task_get_data(struct task_data *task); -- 2.7.4