188 lines
4.5 KiB
Diff
188 lines
4.5 KiB
Diff
--- busybox-1.10.1/debianutils/start_stop_daemon.c Sat Apr 19 05:50:30 2008
|
|
+++ busybox-1.10.1-ssd/debianutils/start_stop_daemon.c Tue Apr 22 03:13:13 2008
|
|
@@ -11,7 +11,6 @@
|
|
/* NB: we have a problem here with /proc/NN/exe usage, similar to
|
|
* one fixed in killall/pidof */
|
|
|
|
-#include <getopt.h>
|
|
#include <sys/resource.h>
|
|
|
|
/* Override ENABLE_FEATURE_PIDFILE */
|
|
@@ -33,6 +32,7 @@
|
|
int user_id;
|
|
smallint quiet;
|
|
smallint signal_nr;
|
|
+ struct stat execstat;
|
|
};
|
|
#define G (*(struct globals*)&bb_common_bufsiz1)
|
|
#define found (G.found )
|
|
@@ -43,6 +43,7 @@
|
|
#define user_id (G.user_id )
|
|
#define quiet (G.quiet )
|
|
#define signal_nr (G.signal_nr )
|
|
+#define execstat (G.execstat )
|
|
#define INIT_G() \
|
|
do { \
|
|
user_id = -1; \
|
|
@@ -50,25 +51,21 @@
|
|
} while (0)
|
|
|
|
|
|
-static int pid_is_exec(pid_t pid, const char *name)
|
|
+static int pid_is_exec(pid_t pid)
|
|
{
|
|
+ struct stat st;
|
|
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
|
- char *execbuf;
|
|
- int n;
|
|
|
|
sprintf(buf, "/proc/%u/exe", pid);
|
|
- n = strlen(name) + 1;
|
|
- execbuf = xzalloc(n + 1);
|
|
- readlink(buf, execbuf, n);
|
|
- /* if readlink fails because link target is longer than strlen(name),
|
|
- * execbuf still contains "", and strcmp will return !0. */
|
|
- n = strcmp(execbuf, name);
|
|
- if (ENABLE_FEATURE_CLEAN_UP)
|
|
- free(execbuf);
|
|
- return !n; /* nonzero (true) if execbuf == name */
|
|
+ if (stat(buf, &st) < 0)
|
|
+ return 0;
|
|
+ if (st.st_dev == execstat.st_dev
|
|
+ && st.st_ino == execstat.st_ino)
|
|
+ return 1;
|
|
+ return 0;
|
|
}
|
|
|
|
-static int pid_is_user(int pid, int uid)
|
|
+static int pid_is_user(int pid)
|
|
{
|
|
struct stat sb;
|
|
char buf[sizeof("/proc/") + sizeof(int)*3];
|
|
@@ -76,42 +73,39 @@
|
|
sprintf(buf, "/proc/%u", pid);
|
|
if (stat(buf, &sb) != 0)
|
|
return 0;
|
|
- return (sb.st_uid == uid);
|
|
+ return (sb.st_uid == user_id);
|
|
}
|
|
|
|
-static int pid_is_cmd(pid_t pid, const char *name)
|
|
+static int pid_is_cmd(pid_t pid)
|
|
{
|
|
- char fname[sizeof("/proc//stat") + sizeof(int)*3];
|
|
- char *buf;
|
|
- int r = 0;
|
|
+ char buf[256]; /* is it big enough? */
|
|
+ char *p, *pe;
|
|
|
|
- sprintf(fname, "/proc/%u/stat", pid);
|
|
- buf = xmalloc_open_read_close(fname, NULL);
|
|
- if (buf) {
|
|
- char *p = strchr(buf, '(');
|
|
- if (p) {
|
|
- char *pe = strrchr(++p, ')');
|
|
- if (pe) {
|
|
- *pe = '\0';
|
|
- r = !strcmp(p, name);
|
|
- }
|
|
- }
|
|
- free(buf);
|
|
- }
|
|
- return r;
|
|
+ sprintf(buf, "/proc/%u/stat", pid);
|
|
+ if (open_read_close(buf, buf, sizeof(buf) - 1) < 0)
|
|
+ return 0;
|
|
+ buf[sizeof(buf) - 1] = '\0'; /* paranoia */
|
|
+ p = strchr(buf, '(');
|
|
+ if (!p)
|
|
+ return 0;
|
|
+ pe = strrchr(++p, ')');
|
|
+ if (!pe)
|
|
+ return 0;
|
|
+ *pe = '\0';
|
|
+ return !strcmp(p, cmdname);
|
|
}
|
|
|
|
static void check(int pid)
|
|
{
|
|
struct pid_list *p;
|
|
|
|
- if (execname && !pid_is_exec(pid, execname)) {
|
|
+ if (execname && !pid_is_exec(pid)) {
|
|
return;
|
|
}
|
|
- if (userspec && !pid_is_user(pid, user_id)) {
|
|
+ if (userspec && !pid_is_user(pid)) {
|
|
return;
|
|
}
|
|
- if (cmdname && !pid_is_cmd(pid, cmdname)) {
|
|
+ if (cmdname && !pid_is_cmd(pid)) {
|
|
return;
|
|
}
|
|
p = xmalloc(sizeof(*p));
|
|
@@ -148,9 +142,16 @@
|
|
procdir = xopendir("/proc");
|
|
|
|
pid = 0;
|
|
- while ((entry = readdir(procdir)) != NULL) {
|
|
+ while(1) {
|
|
+ errno = 0; /* clear any previous error */
|
|
+ entry = readdir(procdir);
|
|
+// TODO: check for exact errno(s) which mean that we got stale entry
|
|
+ if (errno) /* Stale entry, process has died after opendir */
|
|
+ continue;
|
|
+ if (!entry) /* EOF, no more entries */
|
|
+ break;
|
|
pid = bb_strtou(entry->d_name, NULL, 10);
|
|
- if (errno)
|
|
+ if (errno) /* NaN */
|
|
continue;
|
|
check(pid);
|
|
}
|
|
@@ -165,8 +166,6 @@
|
|
struct pid_list *p;
|
|
int killed = 0;
|
|
|
|
- do_procinit();
|
|
-
|
|
if (cmdname) {
|
|
if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname);
|
|
if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname;
|
|
@@ -251,7 +250,7 @@
|
|
};
|
|
|
|
int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|
-int start_stop_daemon_main(int argc, char **argv)
|
|
+int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|
{
|
|
unsigned opt;
|
|
char *signame;
|
|
@@ -293,7 +292,7 @@
|
|
// if (retry_arg)
|
|
// retries = xatoi_u(retry_arg);
|
|
// )
|
|
- argc -= optind;
|
|
+ //argc -= optind;
|
|
argv += optind;
|
|
|
|
if (userspec) {
|
|
@@ -301,13 +300,15 @@
|
|
if (errno)
|
|
user_id = xuname2uid(userspec);
|
|
}
|
|
+ if (execname)
|
|
+ xstat(execname, &execstat);
|
|
|
|
+ do_procinit(); /* Both start and stop needs to know current processes */
|
|
+
|
|
if (opt & CTX_STOP) {
|
|
int i = do_stop();
|
|
return (opt & OPT_OKNODO) ? 0 : (i <= 0);
|
|
}
|
|
-
|
|
- do_procinit();
|
|
|
|
if (found) {
|
|
if (!quiet)
|