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#include "libbb.h"
27#include "common_bufsiz.h"
28#include <linux/netlink.h>
29
30#define BUFFER_SIZE 16*1024
31
32#define env ((char **)bb_common_bufsiz1)
33#define INIT_G() do { setup_common_bufsiz(); } while (0)
34enum {
35 MAX_ENV = COMMON_BUFSIZE / sizeof(char*) - 1,
36
37
38
39};
40
41#ifndef SO_RCVBUFFORCE
42#define SO_RCVBUFFORCE 33
43#endif
44enum { RCVBUF = 2 * 1024 * 1024 };
45
46int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
47int uevent_main(int argc UNUSED_PARAM, char **argv)
48{
49 int fd;
50
51 INIT_G();
52
53 argv++;
54
55
56
57
58
59
60
61 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, RCVBUF);
62
63 for (;;) {
64 char *netbuf;
65 char *s, *end;
66 ssize_t len;
67 int idx;
68
69
70
71
72
73 netbuf = mmap(NULL, BUFFER_SIZE,
74 PROT_READ | PROT_WRITE,
75 MAP_PRIVATE | MAP_ANON,
76 -1, 0);
77 if (netbuf == MAP_FAILED)
78 bb_perror_msg_and_die("mmap");
79
80
81 len = safe_read(fd, netbuf, BUFFER_SIZE - 1);
82 if (len < 0)
83 bb_perror_msg_and_die("read");
84 end = netbuf + len;
85 *end = '\0';
86
87
88
89
90 if (!argv[0])
91 putchar('\n');
92 idx = 0;
93 s = netbuf;
94 while (s < end) {
95 if (!argv[0])
96 puts(s);
97 if (strchr(s, '=') && idx < MAX_ENV)
98 env[idx++] = s;
99 s += strlen(s) + 1;
100 }
101 env[idx] = NULL;
102
103 if (argv[0]) {
104 idx = 0;
105 while (env[idx])
106 putenv(env[idx++]);
107 spawn_and_wait(argv);
108 idx = 0;
109 while (env[idx])
110 bb_unsetenv(env[idx++]);
111 }
112 munmap(netbuf, BUFFER_SIZE);
113 }
114
115 return 0;
116}
117