diff options
Diffstat (limited to 'meta/packages/busybox/busybox-1.01/udhcppidfile.patch')
-rw-r--r-- | meta/packages/busybox/busybox-1.01/udhcppidfile.patch | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/meta/packages/busybox/busybox-1.01/udhcppidfile.patch b/meta/packages/busybox/busybox-1.01/udhcppidfile.patch new file mode 100644 index 0000000000..fb2b2ec19a --- /dev/null +++ b/meta/packages/busybox/busybox-1.01/udhcppidfile.patch | |||
@@ -0,0 +1,276 @@ | |||
1 | --- busybox-1.00/networking/udhcp/pidfile.h-dist 2004-04-15 03:51:26.000000000 +1000 | ||
2 | +++ busybox-1.00/networking/udhcp/pidfile.h 2004-10-27 15:46:38.000000000 +1000 | ||
3 | @@ -21,5 +21,5 @@ | ||
4 | |||
5 | |||
6 | int pidfile_acquire(const char *pidfile); | ||
7 | -void pidfile_write_release(int pid_fd); | ||
8 | +int pidfile_reassign(const char *pidfile, int newpid); | ||
9 | |||
10 | --- busybox-1.00/networking/udhcp/pidfile.c-dist 2004-04-15 03:51:25.000000000 +1000 | ||
11 | +++ busybox-1.00/networking/udhcp/pidfile.c 2004-10-27 19:43:40.000000000 +1000 | ||
12 | @@ -25,6 +25,7 @@ | ||
13 | #include <unistd.h> | ||
14 | #include <stdio.h> | ||
15 | #include <stdlib.h> | ||
16 | +#include <errno.h> | ||
17 | |||
18 | #include "pidfile.h" | ||
19 | #include "common.h" | ||
20 | @@ -37,39 +38,146 @@ | ||
21 | } | ||
22 | |||
23 | |||
24 | -int pidfile_acquire(const char *pidfile) | ||
25 | +static int pidfile_open(const char *pidfile) | ||
26 | { | ||
27 | - int pid_fd; | ||
28 | - if (!pidfile) return -1; | ||
29 | + int fd; | ||
30 | |||
31 | - pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644); | ||
32 | - if (pid_fd < 0) { | ||
33 | - LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile); | ||
34 | - } else { | ||
35 | - lockf(pid_fd, F_LOCK, 0); | ||
36 | - if (!saved_pidfile) | ||
37 | - atexit(pidfile_delete); | ||
38 | - saved_pidfile = (char *) pidfile; | ||
39 | + if ((fd = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0) { | ||
40 | + LOG(LOG_ERR, "pidfile_open: open %s failed: %m\n", pidfile); | ||
41 | + return (-1); | ||
42 | + } | ||
43 | + | ||
44 | + /* NOTE: lockf is not inherited by child after fork */ | ||
45 | + if (lockf(fd, F_LOCK, 0) < 0) { | ||
46 | + LOG(LOG_ERR, "pidfile_open: lock %s failed: %m\n", pidfile); | ||
47 | + close(fd); | ||
48 | + return (-1); | ||
49 | + } | ||
50 | + | ||
51 | + return (fd); | ||
52 | +} | ||
53 | + | ||
54 | + | ||
55 | +static int pidfile_check(int fd, const char *pidfile) | ||
56 | +{ | ||
57 | + int len, pid; | ||
58 | + char buf[20]; | ||
59 | + | ||
60 | + if (lseek(fd, 0L, SEEK_SET) < 0) { | ||
61 | + LOG(LOG_ERR, "pidfile_check: lseek %s failed: %m\n", pidfile); | ||
62 | + return (-1); | ||
63 | + } | ||
64 | + | ||
65 | + if ((len = read(fd, buf, sizeof buf - 1)) < 0) { | ||
66 | + LOG(LOG_ERR, "pidfile_check: read %s failed: %m\n", pidfile); | ||
67 | + return (-1); | ||
68 | + } | ||
69 | + | ||
70 | + if (len == 0) | ||
71 | + return (0); | ||
72 | + | ||
73 | + buf[len] = '\0'; | ||
74 | + | ||
75 | + if ((pid = atoi(buf)) <= 1) { | ||
76 | + LOG(LOG_WARNING, | ||
77 | + "pidfile_check: ignoring bogus pid (%s) in %s\n", | ||
78 | + buf, pidfile); | ||
79 | + return (0); | ||
80 | + } | ||
81 | + | ||
82 | + if (kill((pid_t)pid, 0) == 0) { | ||
83 | + LOG(LOG_ERR, "pidfile_check: process %d exists (%s)\n", | ||
84 | + pid, pidfile); | ||
85 | + return (-1); | ||
86 | + } | ||
87 | + | ||
88 | + if (errno != ESRCH) { | ||
89 | + LOG(LOG_ERR, "pidfile_check: kill %d failed (%s): %m\n", | ||
90 | + pid, pidfile); | ||
91 | + return (-1); | ||
92 | + } | ||
93 | + | ||
94 | + return (0); | ||
95 | +} | ||
96 | + | ||
97 | + | ||
98 | +static int pidfile_store(int fd, const char *pidfile, int pid) | ||
99 | +{ | ||
100 | + int len; | ||
101 | + char buf[20]; | ||
102 | + | ||
103 | + if (lseek(fd, 0L, SEEK_SET) < 0) { | ||
104 | + LOG(LOG_ERR, "pidfile_store: lseek %s failed: %m\n", pidfile); | ||
105 | + return (-1); | ||
106 | + } | ||
107 | + | ||
108 | + len = snprintf(buf, sizeof buf - 1, "%d\n", pid); | ||
109 | + buf[len] = '\0'; | ||
110 | + | ||
111 | + if (write(fd, buf, len) < 0) { | ||
112 | + LOG(LOG_ERR, "pidfile_store: write %s failed: %m\n", | ||
113 | + pidfile); | ||
114 | + return (-1); | ||
115 | + } | ||
116 | + | ||
117 | + if (ftruncate(fd, len) < 0) { | ||
118 | + LOG(LOG_ERR, "pidfile_store: ftruncate %d failed (%s): %m\n", | ||
119 | + len, pidfile); | ||
120 | + return (-1); | ||
121 | } | ||
122 | |||
123 | - return pid_fd; | ||
124 | + return (0); | ||
125 | } | ||
126 | |||
127 | |||
128 | -void pidfile_write_release(int pid_fd) | ||
129 | +static void pidfile_close(int fd) | ||
130 | { | ||
131 | - FILE *out; | ||
132 | + (void)lseek(fd, 0L, SEEK_SET); | ||
133 | + (void)lockf(fd, F_ULOCK, 0); | ||
134 | + (void)close(fd); | ||
135 | +} | ||
136 | |||
137 | - if (pid_fd < 0) return; | ||
138 | |||
139 | - if ((out = fdopen(pid_fd, "w")) != NULL) { | ||
140 | - fprintf(out, "%d\n", getpid()); | ||
141 | - fclose(out); | ||
142 | +int pidfile_acquire(const char *pidfile) | ||
143 | +{ | ||
144 | + int fd, result; | ||
145 | + if (!pidfile) return (-1); | ||
146 | + | ||
147 | + if ((fd = pidfile_open(pidfile)) < 0) | ||
148 | + return (-1); | ||
149 | + | ||
150 | + if ((result = pidfile_check(fd, pidfile)) == 0) | ||
151 | + result = pidfile_store(fd, pidfile, getpid()); | ||
152 | + | ||
153 | + pidfile_close(fd); | ||
154 | + | ||
155 | + if (result == 0) { | ||
156 | + saved_pidfile = (char *) pidfile; | ||
157 | + atexit(pidfile_delete); | ||
158 | } | ||
159 | - lockf(pid_fd, F_UNLCK, 0); | ||
160 | - close(pid_fd); | ||
161 | + | ||
162 | + return (result); | ||
163 | } | ||
164 | |||
165 | |||
166 | +/* | ||
167 | + * reassign the pid in a pidfile - used just after a fork so a parent | ||
168 | + * can store the pid of its child into the file without any window | ||
169 | + * where the pid in the file is a dead process (which might let another | ||
170 | + * instance of the program start). Note the parent must use _exit() to | ||
171 | + * avoid triggering the unlink scheduled above in pidfile_acquire() | ||
172 | + */ | ||
173 | +int pidfile_reassign(const char *pidfile, int pid) | ||
174 | +{ | ||
175 | + int fd, result; | ||
176 | + if (!pidfile) return (-1); | ||
177 | + | ||
178 | + if ((fd = pidfile_open(pidfile)) < 0) | ||
179 | + return (-1); | ||
180 | |||
181 | + result = pidfile_store(fd, pidfile, pid); | ||
182 | |||
183 | + pidfile_close(fd); | ||
184 | + | ||
185 | + return (result); | ||
186 | +} | ||
187 | --- busybox-1.00/networking/udhcp/common.c-dist 2004-05-19 19:18:04.000000000 +1000 | ||
188 | +++ busybox-1.00/networking/udhcp/common.c 2004-10-27 19:58:10.000000000 +1000 | ||
189 | @@ -64,16 +64,34 @@ | ||
190 | #ifdef __uClinux__ | ||
191 | LOG(LOG_ERR, "Cannot background in uclinux (yet)"); | ||
192 | #else /* __uClinux__ */ | ||
193 | - int pid_fd; | ||
194 | + int pid, fd; | ||
195 | |||
196 | - /* hold lock during fork. */ | ||
197 | - pid_fd = pidfile_acquire(pidfile); | ||
198 | - if (daemon(0, 0) == -1) { | ||
199 | + /* NOTE: lockf is not inherited by the child after fork */ | ||
200 | + if ((pid = fork()) < 0) { | ||
201 | perror("fork"); | ||
202 | exit(1); | ||
203 | } | ||
204 | + | ||
205 | + if (pid > 0) { | ||
206 | + /* parent */ | ||
207 | + if (pidfile_reassign(pidfile, pid) < 0) { | ||
208 | + (void)kill(pid, SIGKILL); | ||
209 | + exit(1); | ||
210 | + } else | ||
211 | + _exit(0); | ||
212 | + } | ||
213 | + | ||
214 | + /* child */ | ||
215 | + (void)chdir("/"); | ||
216 | + if ((fd = open("/dev/null", O_RDWR)) >= 0) { | ||
217 | + (void)dup2(fd, 0); | ||
218 | + (void)dup2(fd, 1); | ||
219 | + (void)dup2(fd, 2); | ||
220 | + (void)close(fd); | ||
221 | + } | ||
222 | + (void)setsid(); | ||
223 | + | ||
224 | daemonized++; | ||
225 | - pidfile_write_release(pid_fd); | ||
226 | #endif /* __uClinux__ */ | ||
227 | } | ||
228 | |||
229 | @@ -97,14 +115,12 @@ | ||
230 | |||
231 | void start_log_and_pid(const char *client_server, const char *pidfile) | ||
232 | { | ||
233 | - int pid_fd; | ||
234 | - | ||
235 | /* Make sure our syslog fd isn't overwritten */ | ||
236 | sanitize_fds(); | ||
237 | |||
238 | /* do some other misc startup stuff while we are here to save bytes */ | ||
239 | - pid_fd = pidfile_acquire(pidfile); | ||
240 | - pidfile_write_release(pid_fd); | ||
241 | + if (pidfile_acquire(pidfile) < 0) | ||
242 | + exit(1); | ||
243 | |||
244 | /* equivelent of doing a fflush after every \n */ | ||
245 | setlinebuf(stdout); | ||
246 | @@ -150,8 +166,8 @@ | ||
247 | sanitize_fds(); | ||
248 | |||
249 | /* do some other misc startup stuff while we are here to save bytes */ | ||
250 | - pid_fd = pidfile_acquire(pidfile); | ||
251 | - pidfile_write_release(pid_fd); | ||
252 | + if (pidfile_acquire(pidfile) < 0) | ||
253 | + exit(1); | ||
254 | |||
255 | /* equivelent of doing a fflush after every \n */ | ||
256 | setlinebuf(stdout); | ||
257 | --- busybox-1.00/networking/udhcp/common.h-dist 2004-05-19 18:29:05.000000000 +1000 | ||
258 | +++ busybox-1.00/networking/udhcp/common.h 2004-10-27 15:10:16.000000000 +1000 | ||
259 | @@ -42,7 +42,6 @@ | ||
260 | long uptime(void); | ||
261 | void background(const char *pidfile); | ||
262 | void start_log_and_pid(const char *client_server, const char *pidfile); | ||
263 | -void background(const char *pidfile); | ||
264 | void udhcp_logging(int level, const char *fmt, ...); | ||
265 | |||
266 | #define LOG(level, str, args...) udhcp_logging(level, str, ## args) | ||
267 | --- busybox-1.00/networking/udhcp/script.c-dist 2004-05-19 17:45:47.000000000 +1000 | ||
268 | +++ busybox-1.00/networking/udhcp/script.c 2004-10-27 15:54:04.000000000 +1000 | ||
269 | @@ -228,6 +228,6 @@ | ||
270 | execle(client_config.script, client_config.script, | ||
271 | name, NULL, envp); | ||
272 | LOG(LOG_ERR, "script %s failed: %m", client_config.script); | ||
273 | - exit(1); | ||
274 | + _exit(1); | ||
275 | } | ||
276 | } | ||