diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-12-28 06:30:56 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-12-28 06:30:56 +0100 |
commit | e0a0733fe56afa691e93e9e396a7fbbed6ae1002 (patch) | |
tree | 66d2159929ec0bf049f7975bc3d52b4c38300503 | |
parent | 2e2686dc1b229252fae150bfe97d1c3010563eb9 (diff) | |
download | connman-e0a0733fe56afa691e93e9e396a7fbbed6ae1002.tar.gz connman-e0a0733fe56afa691e93e9e396a7fbbed6ae1002.tar.bz2 connman-e0a0733fe56afa691e93e9e396a7fbbed6ae1002.zip |
Add helpers for task handling
-rw-r--r-- | plugins/task.c | 145 | ||||
-rw-r--r-- | plugins/task.h | 35 |
2 files changed, 180 insertions, 0 deletions
diff --git a/plugins/task.c b/plugins/task.c new file mode 100644 index 00000000..dae54c75 --- /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 <config.h> +#endif + +#include <unistd.h> +#include <sys/wait.h> + +#include <glib.h> + +#include <connman/log.h> + +#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 00000000..0234d47a --- /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 <sys/types.h> + +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); |