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 | } | ||
