if pidfile turned out to be !regular file, do not unlink it. It's most probably the /dev/null.
No binary (build failed)
—
(log yok)
| @@ -144,7 +144,7 @@ config FEATURE_PIDFILE | |
| bool "Support writing pidfiles" | |
| default n | |
| help | |
| - | This option makes some applets (crond, syslogd and inetd) write |
| + | This option makes some applets (e.g. crond, syslogd, inetd) write |
| a pidfile in /var/run. Some applications rely on them. | |
| config FEATURE_SUID | |
| @@ -622,12 +622,14 @@ llist_t *llist_rev(llist_t *list); | |
| /* start_stop_daemon and udhcpc are special - they want | |
| * to create pidfiles regardless of FEATURE_PIDFILE */ | |
| #if ENABLE_FEATURE_PIDFILE || defined(WANT_PIDFILE) | |
| - | int write_pidfile(const char *path); |
| - | #define remove_pidfile(f) ((void)unlink(f)) |
| + | /* True only if we created pidfile which is *file*, not /dev/null etc */ |
| + | extern smallint wrote_pidfile; |
| + | void write_pidfile(const char *path); |
| + | #define remove_pidfile(path) do { if (wrote_pidfile) unlink(path); } while (0) |
| #else | |
| - | /* Why? #defining it to 1 gives "warning: statement with no effect"... */ |
| - | static ALWAYS_INLINE int write_pidfile(const char *path) { return 1; } |
| - | #define remove_pidfile(f) ((void)0) |
| + | enum { wrote_pidfile = 0 }; |
| + | #define write_pidfile(path) ((void)0) |
| + | #define remove_pidfile(path) ((void)0) |
| #endif | |
| enum { | |
| @@ -11,22 +11,30 @@ | |
| #define WANT_PIDFILE 1 | |
| #include "libbb.h" | |
| - | int write_pidfile(const char *path) |
| + | smallint wrote_pidfile; |
| + | |
| + | void write_pidfile(const char *path) |
| { | |
| int pid_fd; | |
| char *end; | |
| char buf[sizeof(int)*3 + 2]; | |
| + | struct stat sb; |
| if (!path) | |
| - | return 1; |
| + | return; |
| /* we will overwrite stale pidfile */ | |
| pid_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666); | |
| if (pid_fd < 0) | |
| - | return 0; |
| - | /* few bytes larger, but doesn't use stdio */ |
| - | end = utoa_to_buf(getpid(), buf, sizeof(buf)); |
| - | *end = '\n'; |
| - | full_write(pid_fd, buf, end - buf + 1); |
| + | return; |
| + | |
| + | /* path can be "/dev/null"! Test for such cases */ |
| + | wrote_pidfile = (fstat(pid_fd, &sb) == 0) && S_ISREG(sb.st_mode); |
| + | |
| + | if (wrote_pidfile) { |
| + | /* few bytes larger, but doesn't use stdio */ |
| + | end = utoa_to_buf(getpid(), buf, sizeof(buf)); |
| + | *end = '\n'; |
| + | full_write(pid_fd, buf, end - buf + 1); |
| + | } |
| close(pid_fd); | |
| - | return 1; |
| } | |
| @@ -546,7 +546,7 @@ int udhcpc_main(int argc, char **argv) | |
| ret0: | |
| retval = 0; | |
| ret: | |
| - | if (client_config.pidfile) |
| + | /*if (client_config.pidfile) - remove_pidfile has it's own check */ |
| remove_pidfile(client_config.pidfile); | |
| return retval; | |
| } | |