summaryrefslogtreecommitdiffstats
path: root/main/busybox/acpid.patch
blob: 494bf45757bec5f0877869f8a416cd91ed47607c (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
From 982fdaf4b2f335506e570a06d5eab09068da3f61 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 09 Jan 2012 04:01:25 +0000
Subject: acpid: close fds which are reported as dead (POLLERR/POLLHUP/POLLNVAL) by poll.

function                                             old     new   delta
acpid_main                                          1159    1229     +70
packed_usage                                       28977   28980      +3

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
(limited to 'util-linux/acpid.c')

diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 6e7321b..361a2b2 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -8,13 +8,13 @@
  */
 
 //usage:#define acpid_trivial_usage
-//usage:       "[-d] [-c CONFDIR] [-l LOGFILE] [-a ACTIONFILE] [-M MAPFILE] [-e PROC_EVENT_FILE] [-p PIDFILE]"
+//usage:       "[-df] [-c CONFDIR] [-l LOGFILE] [-a ACTIONFILE] [-M MAPFILE] [-e PROC_EVENT_FILE] [-p PIDFILE]"
 //usage:#define acpid_full_usage "\n\n"
 //usage:       "Listen to ACPI events and spawn specific helpers on event arrival\n"
+//usage:     "\n	-d	Log to stderr, not log file (implies -f)"
+//usage:     "\n	-f	Run in foreground"
 //usage:     "\n	-c DIR	Config directory [/etc/acpi]"
-//usage:     "\n	-d	Don't daemonize, (implies -f)"
 //usage:     "\n	-e FILE	/proc event file [/proc/acpi/event]"
-//usage:     "\n	-f	Run in foreground"
 //usage:     "\n	-l FILE	Log file [/var/log/acpid.log]"
 //usage:     "\n	-p FILE	Pid file [/var/run/acpid.pid]"
 //usage:     "\n	-a FILE	Action file [/etc/acpid.conf]"
@@ -225,7 +225,6 @@ static void parse_map_file(const char *filename)
 int acpid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int acpid_main(int argc UNUSED_PARAM, char **argv)
 {
-	struct input_event ev;
 	int nfd;
 	int opts;
 	struct pollfd *pfd;
@@ -248,15 +247,21 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
 	);
 
 	if (!(opts & OPT_f)) {
+		/* No -f "Foreground", we go to background */
 		bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv);
 	}
 
 	if (!(opts & OPT_d)) {
+		/* No -d "Debug", we log to log file.
+		 * This includes any output from children.
+		 */
+		xmove_fd(xopen(opt_logfile, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
+		xdup2(STDOUT_FILENO, STDERR_FILENO);
+		/* Also, acpid's messages (but not children) will go to syslog too */
 		openlog(applet_name, LOG_PID, LOG_DAEMON);
 		logmode = LOGMODE_SYSLOG | LOGMODE_STDIO;
-	} else {
-		xmove_fd(xopen(opt_logfile, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
 	}
+	/* else: -d "Debug", log is not redirected */
 
 	parse_conf_file(opt_action);
 	parse_map_file(opt_map);
@@ -272,13 +277,14 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
 		int fd;
 		char *dev_event;
 
-		dev_event = xasprintf((option_mask32 & OPT_e) ? "%s" : "%s%u", opt_input, nfd);
+		dev_event = xasprintf((opts & OPT_e) ? "%s" : "%s%u", opt_input, nfd);
 		fd = open(dev_event, O_RDONLY | O_NONBLOCK);
 		if (fd < 0) {
 			if (nfd == 0)
 				bb_simple_perror_msg_and_die(dev_event);
 			break;
 		}
+		free(dev_event);
 		pfd = xrealloc_vector(pfd, 1, nfd);
 		pfd[nfd].fd = fd;
 		pfd[nfd].events = POLLIN;
@@ -287,16 +293,26 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
 
 	write_pidfile(opt_pidfile);
 
-	while (poll(pfd, nfd, -1) > 0) {
+	while (safe_poll(pfd, nfd, -1) > 0) {
 		int i;
 		for (i = 0; i < nfd; i++) {
-			const char *event = NULL;
-
-			memset(&ev, 0, sizeof(ev));
-
-			if (!(pfd[i].revents & POLLIN))
-				continue;
+			const char *event;
+
+			if (!(pfd[i].revents & POLLIN)) {
+				if (pfd[i].revents == 0)
+					continue; /* this fd has nothing */
+
+				/* Likely POLLERR, POLLHUP, POLLNVAL.
+				 * Do not listen on this fd anymore.
+				 */
+				close(pfd[i].fd);
+				nfd--;
+				for (; i < nfd; i++)
+					pfd[i].fd = pfd[i + 1].fd;
+				break; /* do poll() again */
+			}
 
+			event = NULL;
 			if (option_mask32 & OPT_e) {
 				char *buf;
 				int len;
@@ -307,7 +323,10 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
 				if (len >= 0)
 					buf[len] = '\0';
 				event = find_action(NULL, buf);
+				free(buf);
 			} else {
+				struct input_event ev;
+
 				if (sizeof(ev) != full_read(pfd[i].fd, &ev, sizeof(ev)))
 					continue;
 
@@ -324,11 +343,8 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
 	}
 
 	if (ENABLE_FEATURE_CLEAN_UP) {
-		while (nfd--) {
-			if (pfd[nfd].fd) {
-				close(pfd[nfd].fd);
-			}
-		}
+		while (nfd--)
+			close(pfd[nfd].fd);
 		free(pfd);
 	}
 	remove_pidfile(opt_pidfile);
--
cgit v0.9.0.1-2-gef13