Ticket #340: connector.c

File connector.c, 2.4 KB (added by broder, 12 years ago)
Line 
1/* -*- c-basic-offset: 8; indent-tabs-mode: t -*- */
2#include <errno.h>
3#include <fcntl.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <stdio.h>
7#include <time.h>
8#include <unistd.h>
9#include <linux/connector.h>
10#include <linux/cn_proc.h>
11#include <linux/netlink.h>
12
13static const struct timespec ts = {0, 1000000};
14
15int connector_setup(void)
16{
17        int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
18        int flags;
19        struct sockaddr_nl my_addr = {
20                .nl_family = AF_NETLINK,
21                .nl_groups = CN_IDX_PROC,
22                .nl_pid = getpid(),
23        };
24        char buf[4096]; //XXX correct size
25        struct nlmsghdr *nl_hdr = (struct nlmsghdr *)buf;
26        struct cn_msg *cn_hdr = (struct cn_msg *)NLMSG_DATA(nl_hdr);
27        enum proc_cn_mcast_op *mcop_msg = (enum proc_cn_mcast_op *)cn_hdr->data;
28
29        if (sock < 0)
30                return sock;
31
32        flags = fcntl(sock, F_GETFL, 0);
33        if (flags < 0)
34                return -1;
35        if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0)
36                return -1;
37
38        if (bind(sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
39                return -1;
40
41        nl_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg) + sizeof(enum proc_cn_mcast_op));
42        nl_hdr->nlmsg_type = NLMSG_DONE;
43        nl_hdr->nlmsg_flags = 0;
44        nl_hdr->nlmsg_seq = 0;
45        nl_hdr->nlmsg_pid = getpid();
46
47        cn_hdr->id.idx = CN_IDX_PROC;
48        cn_hdr->id.val = CN_VAL_PROC;
49        cn_hdr->seq = 0;
50        cn_hdr->ack = 0;
51        cn_hdr->len = sizeof(enum proc_cn_mcast_op);
52
53        *mcop_msg = PROC_CN_MCAST_LISTEN;
54
55        if (send(sock, nl_hdr, nl_hdr->nlmsg_len, 0) != nl_hdr->nlmsg_len)
56                return -1;
57
58        return sock;
59}
60
61int main()
62{
63        struct proc_event *ev;
64        char buf[4096]; //XXX me too
65        int sock = connector_setup(), ret;
66        fd_set fds;
67
68        if (sock < 0) {
69                perror("setting up connector socket");
70                return 1;
71        }
72
73        FD_ZERO(&fds);
74        FD_SET(sock, &fds);
75
76        while (select(sock + 1, &fds, NULL, NULL, NULL)) {
77                FD_ZERO(&fds);
78                FD_SET(sock, &fds);
79
80                nanosleep(&ts, NULL);
81
82                while(1) {
83                        struct sockaddr_nl from_addr = {
84                                .nl_family = AF_NETLINK,
85                                .nl_groups = CN_IDX_PROC,
86                                .nl_pid = 1,
87                        };
88                        size_t s = sizeof(from_addr);
89
90                        ret = recvfrom(sock, buf, sizeof(buf), 0,
91                                       (struct sockaddr *)&from_addr, &s);
92                        if (ret == -1) {
93                                if (errno == EAGAIN)
94                                        break;
95                        }
96
97                        ev = (struct proc_event *)((struct cn_msg *)NLMSG_DATA(buf))->data;
98                        if (ev->what == PROC_EVENT_EXEC) {
99                                snprintf(buf, sizeof(buf),
100                                         "/proc/%d/exe",
101                                         ev->event_data.exec.process_tgid);
102                                ret = readlink(buf, buf, sizeof(buf));
103                                if (ret > 0) {
104                                        buf[ret] = 0;
105                                        printf("%s\n",
106                                               buf);
107                                }
108                        }
109                }
110        }
111}