22
22
#include "signals.h"
23
23
#include "modules.h"
25
static GHashTable *child_pids;
27
26
static GSList *pids;
29
static unsigned int childcheck_tag;
30
28
static int signal_pidwait;
30
static void sig_child(GPid pid, gint status, gpointer data)
32
signal_emit_id(signal_pidwait, 2, GINT_TO_POINTER(pid),
33
GINT_TO_POINTER(status));
34
g_hash_table_remove(child_pids, GINT_TO_POINTER(pid));
35
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
32
38
/* add a pid to wait list */
33
39
void pidwait_add(int pid)
35
pids = g_slist_append(pids, GINT_TO_POINTER(pid));
41
if (g_hash_table_lookup(child_pids, GINT_TO_POINTER(pid)) == NULL) {
42
int id = g_child_watch_add_full(10, pid, sig_child, NULL, NULL);
43
g_hash_table_insert(child_pids, GINT_TO_POINTER(pid), GINT_TO_POINTER(id));
44
pids = g_slist_append(pids, GINT_TO_POINTER(pid));
38
48
/* remove pid from wait list */
39
49
void pidwait_remove(int pid)
41
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
51
gpointer id = g_hash_table_lookup(child_pids, GINT_TO_POINTER(pid));
53
g_source_remove(GPOINTER_TO_INT(id));
54
g_hash_table_remove(child_pids, GINT_TO_POINTER(pid));
55
pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
44
59
/* return list of pids that are being waited.
51
static int child_check(void)
56
/* wait for each pid.. */
57
for (tmp = pids; tmp != NULL; tmp = next) {
58
int pid = GPOINTER_TO_INT(tmp->data);
61
if (waitpid(pid, &status, WNOHANG) > 0) {
62
/* process terminated, remove from list */
63
signal_emit_id(signal_pidwait, 2, tmp->data,
64
GINT_TO_POINTER(status));
65
pids = g_slist_remove(pids, tmp->data);
71
66
void pidwait_init(void)
68
child_pids = g_hash_table_new(g_direct_hash, g_direct_equal);
74
childcheck_tag = g_timeout_add(1000, (GSourceFunc) child_check, NULL);
76
71
signal_pidwait = signal_get_uniq_id("pidwait");
79
74
void pidwait_deinit(void)
76
g_hash_table_destroy(child_pids);
81
77
g_slist_free(pids);
83
g_source_remove(childcheck_tag);