277 lines
6.7 KiB
Diff
277 lines
6.7 KiB
Diff
--- busybox-1.00/networking/udhcp/pidfile.h-dist 2004-04-15 03:51:26.000000000 +1000
|
|
+++ busybox-1.00/networking/udhcp/pidfile.h 2004-10-27 15:46:38.000000000 +1000
|
|
@@ -21,5 +21,5 @@
|
|
|
|
|
|
int pidfile_acquire(const char *pidfile);
|
|
-void pidfile_write_release(int pid_fd);
|
|
+int pidfile_reassign(const char *pidfile, int newpid);
|
|
|
|
--- busybox-1.00/networking/udhcp/pidfile.c-dist 2004-04-15 03:51:25.000000000 +1000
|
|
+++ busybox-1.00/networking/udhcp/pidfile.c 2004-10-27 19:43:40.000000000 +1000
|
|
@@ -25,6 +25,7 @@
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#include <errno.h>
|
|
|
|
#include "pidfile.h"
|
|
#include "common.h"
|
|
@@ -37,39 +38,146 @@
|
|
}
|
|
|
|
|
|
-int pidfile_acquire(const char *pidfile)
|
|
+static int pidfile_open(const char *pidfile)
|
|
{
|
|
- int pid_fd;
|
|
- if (!pidfile) return -1;
|
|
+ int fd;
|
|
|
|
- pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
|
|
- if (pid_fd < 0) {
|
|
- LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile);
|
|
- } else {
|
|
- lockf(pid_fd, F_LOCK, 0);
|
|
- if (!saved_pidfile)
|
|
- atexit(pidfile_delete);
|
|
- saved_pidfile = (char *) pidfile;
|
|
+ if ((fd = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_open: open %s failed: %m\n", pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ /* NOTE: lockf is not inherited by child after fork */
|
|
+ if (lockf(fd, F_LOCK, 0) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_open: lock %s failed: %m\n", pidfile);
|
|
+ close(fd);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ return (fd);
|
|
+}
|
|
+
|
|
+
|
|
+static int pidfile_check(int fd, const char *pidfile)
|
|
+{
|
|
+ int len, pid;
|
|
+ char buf[20];
|
|
+
|
|
+ if (lseek(fd, 0L, SEEK_SET) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_check: lseek %s failed: %m\n", pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if ((len = read(fd, buf, sizeof buf - 1)) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_check: read %s failed: %m\n", pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (len == 0)
|
|
+ return (0);
|
|
+
|
|
+ buf[len] = '\0';
|
|
+
|
|
+ if ((pid = atoi(buf)) <= 1) {
|
|
+ LOG(LOG_WARNING,
|
|
+ "pidfile_check: ignoring bogus pid (%s) in %s\n",
|
|
+ buf, pidfile);
|
|
+ return (0);
|
|
+ }
|
|
+
|
|
+ if (kill((pid_t)pid, 0) == 0) {
|
|
+ LOG(LOG_ERR, "pidfile_check: process %d exists (%s)\n",
|
|
+ pid, pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (errno != ESRCH) {
|
|
+ LOG(LOG_ERR, "pidfile_check: kill %d failed (%s): %m\n",
|
|
+ pid, pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ return (0);
|
|
+}
|
|
+
|
|
+
|
|
+static int pidfile_store(int fd, const char *pidfile, int pid)
|
|
+{
|
|
+ int len;
|
|
+ char buf[20];
|
|
+
|
|
+ if (lseek(fd, 0L, SEEK_SET) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_store: lseek %s failed: %m\n", pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ len = snprintf(buf, sizeof buf - 1, "%d\n", pid);
|
|
+ buf[len] = '\0';
|
|
+
|
|
+ if (write(fd, buf, len) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_store: write %s failed: %m\n",
|
|
+ pidfile);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (ftruncate(fd, len) < 0) {
|
|
+ LOG(LOG_ERR, "pidfile_store: ftruncate %d failed (%s): %m\n",
|
|
+ len, pidfile);
|
|
+ return (-1);
|
|
}
|
|
|
|
- return pid_fd;
|
|
+ return (0);
|
|
}
|
|
|
|
|
|
-void pidfile_write_release(int pid_fd)
|
|
+static void pidfile_close(int fd)
|
|
{
|
|
- FILE *out;
|
|
+ (void)lseek(fd, 0L, SEEK_SET);
|
|
+ (void)lockf(fd, F_ULOCK, 0);
|
|
+ (void)close(fd);
|
|
+}
|
|
|
|
- if (pid_fd < 0) return;
|
|
|
|
- if ((out = fdopen(pid_fd, "w")) != NULL) {
|
|
- fprintf(out, "%d\n", getpid());
|
|
- fclose(out);
|
|
+int pidfile_acquire(const char *pidfile)
|
|
+{
|
|
+ int fd, result;
|
|
+ if (!pidfile) return (-1);
|
|
+
|
|
+ if ((fd = pidfile_open(pidfile)) < 0)
|
|
+ return (-1);
|
|
+
|
|
+ if ((result = pidfile_check(fd, pidfile)) == 0)
|
|
+ result = pidfile_store(fd, pidfile, getpid());
|
|
+
|
|
+ pidfile_close(fd);
|
|
+
|
|
+ if (result == 0) {
|
|
+ saved_pidfile = (char *) pidfile;
|
|
+ atexit(pidfile_delete);
|
|
}
|
|
- lockf(pid_fd, F_UNLCK, 0);
|
|
- close(pid_fd);
|
|
+
|
|
+ return (result);
|
|
}
|
|
|
|
|
|
+/*
|
|
+ * reassign the pid in a pidfile - used just after a fork so a parent
|
|
+ * can store the pid of its child into the file without any window
|
|
+ * where the pid in the file is a dead process (which might let another
|
|
+ * instance of the program start). Note the parent must use _exit() to
|
|
+ * avoid triggering the unlink scheduled above in pidfile_acquire()
|
|
+ */
|
|
+int pidfile_reassign(const char *pidfile, int pid)
|
|
+{
|
|
+ int fd, result;
|
|
+ if (!pidfile) return (-1);
|
|
+
|
|
+ if ((fd = pidfile_open(pidfile)) < 0)
|
|
+ return (-1);
|
|
|
|
+ result = pidfile_store(fd, pidfile, pid);
|
|
|
|
+ pidfile_close(fd);
|
|
+
|
|
+ return (result);
|
|
+}
|
|
--- busybox-1.00/networking/udhcp/common.c-dist 2004-05-19 19:18:04.000000000 +1000
|
|
+++ busybox-1.00/networking/udhcp/common.c 2004-10-27 19:58:10.000000000 +1000
|
|
@@ -64,16 +64,34 @@
|
|
#ifdef __uClinux__
|
|
LOG(LOG_ERR, "Cannot background in uclinux (yet)");
|
|
#else /* __uClinux__ */
|
|
- int pid_fd;
|
|
+ int pid, fd;
|
|
|
|
- /* hold lock during fork. */
|
|
- pid_fd = pidfile_acquire(pidfile);
|
|
- if (daemon(0, 0) == -1) {
|
|
+ /* NOTE: lockf is not inherited by the child after fork */
|
|
+ if ((pid = fork()) < 0) {
|
|
perror("fork");
|
|
exit(1);
|
|
}
|
|
+
|
|
+ if (pid > 0) {
|
|
+ /* parent */
|
|
+ if (pidfile_reassign(pidfile, pid) < 0) {
|
|
+ (void)kill(pid, SIGKILL);
|
|
+ exit(1);
|
|
+ } else
|
|
+ _exit(0);
|
|
+ }
|
|
+
|
|
+ /* child */
|
|
+ (void)chdir("/");
|
|
+ if ((fd = open("/dev/null", O_RDWR)) >= 0) {
|
|
+ (void)dup2(fd, 0);
|
|
+ (void)dup2(fd, 1);
|
|
+ (void)dup2(fd, 2);
|
|
+ (void)close(fd);
|
|
+ }
|
|
+ (void)setsid();
|
|
+
|
|
daemonized++;
|
|
- pidfile_write_release(pid_fd);
|
|
#endif /* __uClinux__ */
|
|
}
|
|
|
|
@@ -97,14 +115,12 @@
|
|
|
|
void start_log_and_pid(const char *client_server, const char *pidfile)
|
|
{
|
|
- int pid_fd;
|
|
-
|
|
/* Make sure our syslog fd isn't overwritten */
|
|
sanitize_fds();
|
|
|
|
/* do some other misc startup stuff while we are here to save bytes */
|
|
- pid_fd = pidfile_acquire(pidfile);
|
|
- pidfile_write_release(pid_fd);
|
|
+ if (pidfile_acquire(pidfile) < 0)
|
|
+ exit(1);
|
|
|
|
/* equivelent of doing a fflush after every \n */
|
|
setlinebuf(stdout);
|
|
@@ -150,8 +166,8 @@
|
|
sanitize_fds();
|
|
|
|
/* do some other misc startup stuff while we are here to save bytes */
|
|
- pid_fd = pidfile_acquire(pidfile);
|
|
- pidfile_write_release(pid_fd);
|
|
+ if (pidfile_acquire(pidfile) < 0)
|
|
+ exit(1);
|
|
|
|
/* equivelent of doing a fflush after every \n */
|
|
setlinebuf(stdout);
|
|
--- busybox-1.00/networking/udhcp/common.h-dist 2004-05-19 18:29:05.000000000 +1000
|
|
+++ busybox-1.00/networking/udhcp/common.h 2004-10-27 15:10:16.000000000 +1000
|
|
@@ -42,7 +42,6 @@
|
|
long uptime(void);
|
|
void background(const char *pidfile);
|
|
void start_log_and_pid(const char *client_server, const char *pidfile);
|
|
-void background(const char *pidfile);
|
|
void udhcp_logging(int level, const char *fmt, ...);
|
|
|
|
#define LOG(level, str, args...) udhcp_logging(level, str, ## args)
|
|
--- busybox-1.00/networking/udhcp/script.c-dist 2004-05-19 17:45:47.000000000 +1000
|
|
+++ busybox-1.00/networking/udhcp/script.c 2004-10-27 15:54:04.000000000 +1000
|
|
@@ -228,6 +228,6 @@
|
|
execle(client_config.script, client_config.script,
|
|
name, NULL, envp);
|
|
LOG(LOG_ERR, "script %s failed: %m", client_config.script);
|
|
- exit(1);
|
|
+ _exit(1);
|
|
}
|
|
}
|