~ubuntu-branches/ubuntu/oneiric/irssi/oneiric

« back to all changes in this revision

Viewing changes to src/core/pidwait.c

  • Committer: Bazaar Package Importer
  • Author(s): Andres Rodriguez
  • Date: 2009-05-05 15:50:50 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090505155050-aoqlnpes7che9rtd
Tags: 0.8.13-1ubuntu1
* Merge from debian unstable (LP: #372411), remaining changes:
  - debian/patches: 03firsttimer_text
    + Adapt it so it tells you about connecting to irc.ubuntu.com and
      joining #ubuntu instead of irc.debian.org and #debian.
  - debian/patches: 90irc-ubuntu-com
* Fixed debian/patches/90irc-ubuntu-com for new irssi.conf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "signals.h"
23
23
#include "modules.h"
24
24
 
25
 
#include <sys/wait.h>
26
 
 
 
25
static GHashTable *child_pids;
27
26
static GSList *pids;
28
27
 
29
 
static unsigned int childcheck_tag;
30
28
static int signal_pidwait;
31
29
 
 
30
static void sig_child(GPid pid, gint status, gpointer data)
 
31
{
 
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));
 
36
}
 
37
 
32
38
/* add a pid to wait list */
33
39
void pidwait_add(int pid)
34
40
{
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));
 
45
        }
36
46
}
37
47
 
38
48
/* remove pid from wait list */
39
49
void pidwait_remove(int pid)
40
50
{
41
 
        pids = g_slist_remove(pids, GINT_TO_POINTER(pid));
 
51
        gpointer id = g_hash_table_lookup(child_pids, GINT_TO_POINTER(pid));
 
52
        if (id != NULL) {
 
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));
 
56
        }
42
57
}
43
58
 
44
59
/* return list of pids that are being waited.
48
63
        return pids;
49
64
}
50
65
 
51
 
static int child_check(void)
52
 
{
53
 
        GSList *tmp, *next;
54
 
        int status;
55
 
 
56
 
        /* wait for each pid.. */
57
 
        for (tmp = pids; tmp != NULL; tmp = next) {
58
 
                int pid = GPOINTER_TO_INT(tmp->data);
59
 
 
60
 
                next = tmp->next;
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);
66
 
                }
67
 
        }
68
 
        return 1;
69
 
}
70
 
 
71
66
void pidwait_init(void)
72
67
{
 
68
        child_pids = g_hash_table_new(g_direct_hash, g_direct_equal);
73
69
        pids = NULL;
74
 
        childcheck_tag = g_timeout_add(1000, (GSourceFunc) child_check, NULL);
75
70
 
76
71
        signal_pidwait = signal_get_uniq_id("pidwait");
77
72
}
78
73
 
79
74
void pidwait_deinit(void)
80
75
{
 
76
        g_hash_table_destroy(child_pids);
81
77
        g_slist_free(pids);
82
 
 
83
 
        g_source_remove(childcheck_tag);
84
78
}