summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/procctl.cpp
blob: a44529b416e179b462c309f11e0d0eb026e21fdb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <sys/wait.h>

#include <fcntl.h>
#include <unistd.h>

#include "procctl.h"

ProcContainer *ProcCtl::m_last = 0;
ProcCtl* ProcCtl::m_self = 0;

ProcCtl::ProcCtl() {
    signal( SIGCHLD, signal_handler );
}
ProcCtl::~ProcCtl() {
}
ProcCtl* ProcCtl::self() {
    if (!m_self ) {
        m_self = new ProcCtl;
    }
    return m_self;
}
void ProcCtl::add(pid_t pi,  int fd ) {
    ProcContainer * con = new ProcContainer;
    //memset(con, 0, sizeof(con) );
    con->pid = pi;
    con->fd = fd;
    con->status = 0;
    con->prev = m_last;

    m_last = con;

}
void ProcCtl::remove( pid_t pi ) {
    /*
     * We first check if the last item
     * is equal to  pi the we
     *
     */
    ProcContainer* con;
    if (m_last->pid == pi ) {
        con = m_last;
        m_last = con->prev;
        delete con;
        return;
    }

    con = m_last;
    ProcContainer* forw = 0l;
    while (con ) {
        /* remove it */
        if ( pi == con->pid ) {
            forw->prev = con->prev;
            delete con;
            return;
        }

        forw = con;
        con = con->prev;
    }

}
void ProcCtl::remove( ProcContainer con ) {
    remove( con.pid );
}
int ProcCtl::status(pid_t pid )const{
    ProcContainer *con = m_last;
    while (con) {
        if (con->pid == pid )
            return con->status;
        con = con->prev;
    }
    return -1;
}
void ProcCtl::signal_handler(int) {
    int status;
    signal( SIGCHLD,  signal_handler );
    pid_t pi = waitpid( -1, &status, WNOHANG  );

    /*
     * find the container for pid
     *
     */
    if ( pi < 0 ) {
        return;
    }

    ProcContainer* con = m_last;
    while (con) {
        if ( con->pid == pi ) {
            con->status = status;
            char result = 1;
            /* give a 'signal' */
            ::write(con->fd, &result, 1 );
        }
        con = con->prev;
    }
}