Skip to content

Commit 525cbec

Browse files
committed
Merge branch 'procfs'
Signed-off-by: Stefan Assmann <[email protected]>
2 parents 2083bf0 + 9f1b143 commit 525cbec

10 files changed

+336
-99
lines changed

Makefile

+17-5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ INSTALL_ETC=$(PREFIX)/etc
2727
INSTALL_INITD=/etc/init.d
2828
INSTALL_SBIN=$(PREFIX)/sbin
2929
INSTALL_MAN=$(PREFIX)/man
30+
INSTALL_UNITDIR=$(PREFIX)/lib/systemd/system
3031

3132
# typical OpenBSD or FreeBSD configuration
3233
#PREFIX=/usr/local
@@ -78,13 +79,13 @@ default: and $(INITSCRIPT) doc
7879
#
7980
# Version and date
8081
#
81-
VERSION=1.2.2
82-
DATE="27 Mar 2005"
82+
VERSION=1.2.3
83+
DATE="2015-12-06"
8384

8485
#
8586
# Man pages
8687
#
87-
MANPAGES=and.8 and.conf.5 and.priorities.5
88+
MANPAGES=and.8 and.conf.5 and.priorities.5 and.service
8889

8990
#
9091
# Determine architecture from uname(1)
@@ -142,8 +143,8 @@ endif
142143
#
143144
# Build the auto-nice daemon.
144145
#
145-
and: and.o and-$(ARCH).o
146-
$(LD) $(CFLAGS) and.o and-$(ARCH).o -o and $(LIBS)
146+
and: and.o and-proc.o and-$(ARCH).o
147+
$(LD) $(CFLAGS) and.o and-proc.o and-$(ARCH).o -o and $(LIBS)
147148

148149

149150
#
@@ -159,6 +160,9 @@ and.o: and.c and.h
159160
#
160161
# Unix variant specific stuff
161162
#
163+
and-proc.o: and.h and-proc.c
164+
$(CC) $(CFLAGS) -c and-proc.c
165+
162166
and-Linux.o: and.h and-Linux.c
163167
$(CC) $(CFLAGS) -c and-Linux.c
164168

@@ -210,6 +214,10 @@ and.priorities.5: and.priorities.5.man
210214
sed s/__VERSION__/$(VERSION)/g | \
211215
sed s/__DATE__/$(DATE)/g > $@
212216

217+
and.service: and.service.man
218+
cat $< | \
219+
sed s,EnvironmentFile=,EnvironmentFile=$(PREFIX),g | \
220+
sed s,ExecStart=/usr,ExecStart=$(PREFIX),g > $@
213221

214222
#
215223
# Install and under $(PREFIX)/bin etc.
@@ -219,9 +227,11 @@ install: and
219227
#-mkdir $(PREFIX)
220228
-mkdir -p $(DESTDIR)$(INSTALL_SBIN)
221229
-mkdir -p $(DESTDIR)$(INSTALL_ETC)/and/
230+
-mkdir -p $(DESTDIR)$(INSTALL_ETC)/sysconfig
222231
-mkdir -p $(DESTDIR)$(INSTALL_INITD)
223232
-mkdir -p $(DESTDIR)$(INSTALL_MAN)/man5
224233
-mkdir -p $(DESTDIR)$(INSTALL_MAN)/man8
234+
-mkdir -p $(DESTDIR)$(INSTALL_UNITDIR)
225235
$(INSTALL) -m 0755 and $(DESTDIR)$(INSTALL_SBIN)
226236
test -e $(DESTDIR)$(INSTALL_ETC)/and/and.conf || \
227237
$(INSTALL) -m 0644 and.conf $(DESTDIR)$(INSTALL_ETC)/and/
@@ -230,6 +240,8 @@ install: and
230240
$(INSTALL) -m 0644 and.8 $(DESTDIR)$(INSTALL_MAN)/man8
231241
$(INSTALL) -m 0644 and.conf.5 $(DESTDIR)$(INSTALL_MAN)/man5
232242
$(INSTALL) -m 0644 and.priorities.5 $(DESTDIR)$(INSTALL_MAN)/man5
243+
$(INSTALL) -m 0644 and.service $(DESTDIR)$(INSTALL_UNITDIR)/
244+
$(INSTALL) -m 0644 and.sysconf $(DESTDIR)$(INSTALL_ETC)/sysconfig/and
233245

234246
simpleinstall: and and.init
235247
strip and

and-Linux.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ struct and_procent *linux_getnext ()
103103
return &linux_proc;
104104
}
105105

106+
struct and_procent *linux_getfrompid (int pid)
107+
{
108+
char name [1024];
109+
struct stat dirstat;
110+
111+
/* stat() /proc/<pid> directory to get uid/gid */
112+
snprintf(name, 1024, "/proc/%d", pid);
113+
stat(name,&dirstat);
114+
/* read the job's stat "file" to get command, nice level, etc */
115+
snprintf(name, 1024, "/proc/%d/stat", pid);
116+
linux_readproc(name);
117+
linux_proc.uid = dirstat.st_uid;
118+
linux_proc.gid = dirstat.st_gid;
119+
120+
return &linux_proc;
121+
}
122+
106123
struct and_procent *linux_getfirst ()
107124
{
108125
if (linux_procdir) {
@@ -119,6 +136,6 @@ struct and_procent *linux_getfirst ()
119136

120137
int main (int argc, char** argv)
121138
{
122-
and_setprocreader(&linux_getfirst,&linux_getnext);
139+
and_setprocreader(&linux_getfirst, &linux_getnext, &linux_getfrompid);
123140
return and_main(argc,argv);
124141
}

and-proc.c

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include <sys/socket.h>
2+
#include <linux/netlink.h>
3+
#include <linux/connector.h>
4+
#include <linux/cn_proc.h>
5+
#include <signal.h>
6+
#include <errno.h>
7+
#include <stdbool.h>
8+
#include <unistd.h>
9+
#include <string.h>
10+
#include <stdlib.h>
11+
#include <stdio.h>
12+
13+
#include "and.h"
14+
15+
bool need_exit = false;
16+
/*
17+
* connect to netlink
18+
* returns netlink socket, or -1 on error
19+
*/
20+
int nl_connect()
21+
{
22+
int rc;
23+
int nl_sock;
24+
struct sockaddr_nl sa_nl;
25+
26+
nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
27+
if (nl_sock == -1) {
28+
perror("socket");
29+
return -1;
30+
}
31+
32+
sa_nl.nl_family = AF_NETLINK;
33+
sa_nl.nl_groups = CN_IDX_PROC;
34+
sa_nl.nl_pid = getpid();
35+
36+
rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
37+
if (rc == -1) {
38+
perror("bind");
39+
close(nl_sock);
40+
return -1;
41+
}
42+
43+
return nl_sock;
44+
}
45+
46+
/*
47+
* subscribe on proc events (process notifications)
48+
*/
49+
int proc_set_ev_listen(int nl_sock, bool enable)
50+
{
51+
int rc;
52+
struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
53+
struct nlmsghdr nl_hdr;
54+
struct __attribute__ ((__packed__)) {
55+
struct cn_msg cn_msg;
56+
enum proc_cn_mcast_op cn_mcast;
57+
};
58+
} nlcn_msg;
59+
60+
memset(&nlcn_msg, 0, sizeof(nlcn_msg));
61+
nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
62+
nlcn_msg.nl_hdr.nlmsg_pid = getpid();
63+
nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
64+
65+
nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
66+
nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
67+
nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
68+
69+
nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;
70+
71+
rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
72+
if (rc == -1) {
73+
perror("netlink send");
74+
return -1;
75+
}
76+
77+
return 0;
78+
}
79+
80+
/*
81+
* handle a single process event
82+
*/
83+
int proc_handle_ev(int nl_sock)
84+
{
85+
int rc;
86+
87+
struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
88+
struct nlmsghdr nl_hdr;
89+
struct __attribute__ ((__packed__)) {
90+
struct cn_msg cn_msg;
91+
struct proc_event proc_ev;
92+
};
93+
} nlcn_msg;
94+
struct sockaddr_nl addr;
95+
socklen_t addrlen;
96+
97+
while (!need_exit) {
98+
rc = recvfrom(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0, (struct sockaddr *)&addr, &addrlen);
99+
if (addr.nl_pid) /* check that message is from kernel */
100+
continue;
101+
if (rc == 0) {
102+
/* shutdown? */
103+
return -1;
104+
} else if (rc == -1) {
105+
and_printf(0, "netlink receive error\n");
106+
return -1;
107+
}
108+
switch (nlcn_msg.proc_ev.what) {
109+
case PROC_EVENT_NONE:
110+
and_printf(1, "start listening to netlink...\n");
111+
break;
112+
case PROC_EVENT_FORK:
113+
//if (fork() == 0) /* handle event in child */
114+
// return nlcn_msg.proc_ev.event_data.fork.parent_pid;
115+
//and_printf(1, "FORK pid=%d ppid=%d\n", nlcn_msg.proc_ev.event_data.fork.child_pid,nlcn_msg.proc_ev.event_data.fork.parent_pid);
116+
break;
117+
case PROC_EVENT_EXEC:
118+
if (fork() == 0) /* handle event in child */
119+
return nlcn_msg.proc_ev.event_data.exec.process_pid;
120+
and_printf(2, "EXEC pid=%d\n", nlcn_msg.proc_ev.event_data.exec.process_pid);
121+
break;
122+
case PROC_EVENT_UID:
123+
case PROC_EVENT_GID:
124+
case PROC_EVENT_SID:
125+
case PROC_EVENT_PTRACE:
126+
case PROC_EVENT_COMM:
127+
case PROC_EVENT_EXIT:
128+
break;
129+
default:
130+
and_printf(1, "unhandled proc_event %d\n", nlcn_msg.proc_ev.what);
131+
break;
132+
}
133+
}
134+
return 0;
135+
}
136+
137+

0 commit comments

Comments
 (0)