start_stop_daemon: NOMMU fix; smaller fixes
This commit is contained in:
parent
f1f1b69dc1
commit
a1b16f4d5c
@ -8,6 +8,9 @@
|
|||||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* NB: we have a problem here with /proc/NN/exe usage, similar to
|
||||||
|
* one fixed in killall/pidof */
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
@ -28,33 +31,22 @@ struct pid_list {
|
|||||||
|
|
||||||
static struct pid_list *found;
|
static struct pid_list *found;
|
||||||
|
|
||||||
static inline void push(pid_t pid)
|
|
||||||
{
|
|
||||||
struct pid_list *p;
|
|
||||||
|
|
||||||
p = xmalloc(sizeof(*p));
|
|
||||||
p->next = found;
|
|
||||||
p->pid = pid;
|
|
||||||
found = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pid_is_exec(pid_t pid, const char *name)
|
static int pid_is_exec(pid_t pid, const char *name)
|
||||||
{
|
{
|
||||||
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
char buf[sizeof("/proc//exe") + sizeof(int)*3];
|
||||||
char *execbuf;
|
char *execbuf;
|
||||||
int sz;
|
int n;
|
||||||
int equal;
|
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d/exe", pid);
|
sprintf(buf, "/proc/%u/exe", pid);
|
||||||
sz = strlen(name) + 1;
|
n = strlen(name) + 1;
|
||||||
execbuf = xzalloc(sz);
|
execbuf = xzalloc(n + 1);
|
||||||
readlink(buf, execbuf, sz);
|
readlink(buf, execbuf, n);
|
||||||
|
|
||||||
/* if readlink fails, execbuf still contains "" */
|
/* if readlink fails, execbuf still contains "" */
|
||||||
equal = !strcmp(execbuf, name);
|
n = strcmp(execbuf, name);
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
free(execbuf);
|
free(execbuf);
|
||||||
return equal;
|
return ~n; /* nonzero (true) if execbuf == name */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pid_is_user(int pid, int uid)
|
static int pid_is_user(int pid, int uid)
|
||||||
@ -90,9 +82,10 @@ static int pid_is_cmd(pid_t pid, const char *name)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void check(int pid)
|
static void check(int pid)
|
||||||
{
|
{
|
||||||
|
struct pid_list *p;
|
||||||
|
|
||||||
if (execname && !pid_is_exec(pid, execname)) {
|
if (execname && !pid_is_exec(pid, execname)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -102,14 +95,16 @@ static void check(int pid)
|
|||||||
if (cmdname && !pid_is_cmd(pid, cmdname)) {
|
if (cmdname && !pid_is_cmd(pid, cmdname)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
push(pid);
|
p = xmalloc(sizeof(*p));
|
||||||
|
p->next = found;
|
||||||
|
p->pid = pid;
|
||||||
|
found = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_pidfile(void)
|
static void do_pidfile(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
pid_t pid;
|
unsigned pid;
|
||||||
|
|
||||||
f = fopen(pidfile, "r");
|
f = fopen(pidfile, "r");
|
||||||
if (f) {
|
if (f) {
|
||||||
@ -143,10 +138,9 @@ static void do_procinit(void)
|
|||||||
}
|
}
|
||||||
closedir(procdir);
|
closedir(procdir);
|
||||||
if (!foundany)
|
if (!foundany)
|
||||||
bb_error_msg_and_die ("nothing in /proc - not mounted?");
|
bb_error_msg_and_die("nothing in /proc - not mounted?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_stop(void)
|
static int do_stop(void)
|
||||||
{
|
{
|
||||||
char *what;
|
char *what;
|
||||||
@ -155,11 +149,13 @@ static int do_stop(void)
|
|||||||
|
|
||||||
do_procinit();
|
do_procinit();
|
||||||
|
|
||||||
if (cmdname)
|
if (cmdname) {
|
||||||
what = xstrdup(cmdname);
|
if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname);
|
||||||
else if (execname)
|
if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname;
|
||||||
what = xstrdup(execname);
|
} else if (execname) {
|
||||||
else if (pidfile)
|
if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(execname);
|
||||||
|
if (!ENABLE_FEATURE_CLEAN_UP) what = execname;
|
||||||
|
} else if (pidfile)
|
||||||
what = xasprintf("process in pidfile '%s'", pidfile);
|
what = xasprintf("process in pidfile '%s'", pidfile);
|
||||||
else if (userspec)
|
else if (userspec)
|
||||||
what = xasprintf("process(es) owned by '%s'", userspec);
|
what = xasprintf("process(es) owned by '%s'", userspec);
|
||||||
@ -169,25 +165,25 @@ static int do_stop(void)
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("no %s found; none killed\n", what);
|
printf("no %s found; none killed\n", what);
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
killed = -1;
|
||||||
free(what);
|
goto ret;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
for (p = found; p; p = p->next) {
|
for (p = found; p; p = p->next) {
|
||||||
if (kill(p->pid, signal_nr) == 0) {
|
if (kill(p->pid, signal_nr) == 0) {
|
||||||
p->pid = -p->pid;
|
p->pid = - p->pid;
|
||||||
killed++;
|
killed++;
|
||||||
} else {
|
} else {
|
||||||
bb_perror_msg("warning: failed to kill %d", p->pid);
|
bb_perror_msg("warning: killing process %u", p->pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!quiet && killed) {
|
if (!quiet && killed) {
|
||||||
printf("stopped %s (pid", what);
|
printf("stopped %s (pid", what);
|
||||||
for (p = found; p; p = p->next)
|
for (p = found; p; p = p->next)
|
||||||
if (p->pid < 0)
|
if (p->pid < 0)
|
||||||
printf(" %d", -p->pid);
|
printf(" %u", - p->pid);
|
||||||
puts(")");
|
puts(")");
|
||||||
}
|
}
|
||||||
|
ret:
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
free(what);
|
free(what);
|
||||||
return killed;
|
return killed;
|
||||||
@ -287,7 +283,7 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (opt & CTX_STOP) {
|
if (opt & CTX_STOP) {
|
||||||
int i = do_stop();
|
int i = do_stop();
|
||||||
return (opt & OPT_OKNODO) ? 0 : (i<=0);
|
return (opt & OPT_OKNODO) ? 0 : (i <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_procinit();
|
do_procinit();
|
||||||
@ -299,7 +295,24 @@ int start_stop_daemon_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
*--argv = startas;
|
*--argv = startas;
|
||||||
if (opt & OPT_BACKGROUND) {
|
if (opt & OPT_BACKGROUND) {
|
||||||
|
#if BB_MMU
|
||||||
bb_daemonize(0);
|
bb_daemonize(0);
|
||||||
|
#else
|
||||||
|
pid_t pid = vfork();
|
||||||
|
if (pid < 0) /* error */
|
||||||
|
bb_perror_msg_and_die("vfork");
|
||||||
|
if (pid == 0) /* parent */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* child */
|
||||||
|
/* Redirect stdio to /dev/null, close extra FDs.
|
||||||
|
* We do not actually daemonize because of DAEMON_ONLY_SANITIZE */
|
||||||
|
bb_daemonize_or_rexec(
|
||||||
|
DAEMON_DEVNULL_STDIO
|
||||||
|
+ DAEMON_CLOSE_EXTRA_FDS
|
||||||
|
+ DAEMON_ONLY_SANITIZE,
|
||||||
|
NULL /* argv, unused */ );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (opt & OPT_MAKEPID) {
|
if (opt & OPT_MAKEPID) {
|
||||||
/* user wants _us_ to make the pidfile */
|
/* user wants _us_ to make the pidfile */
|
||||||
|
@ -573,7 +573,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet
|
|||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
DAEMON_CHDIR_ROOT = 1,
|
DAEMON_CHDIR_ROOT = 1,
|
||||||
DAEMON_DEVNULL_STDIO = /* 2 */ 0, /* no users so far */
|
DAEMON_DEVNULL_STDIO = 2,
|
||||||
DAEMON_CLOSE_EXTRA_FDS = 4,
|
DAEMON_CLOSE_EXTRA_FDS = 4,
|
||||||
DAEMON_ONLY_SANITIZE = 8, /* internal use */
|
DAEMON_ONLY_SANITIZE = 8, /* internal use */
|
||||||
};
|
};
|
||||||
|
@ -244,8 +244,6 @@ void bb_daemonize_or_rexec(int flags, char **argv)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = xopen(bb_dev_null, O_RDWR);
|
|
||||||
|
|
||||||
if (flags & DAEMON_CHDIR_ROOT)
|
if (flags & DAEMON_CHDIR_ROOT)
|
||||||
xchdir("/");
|
xchdir("/");
|
||||||
|
|
||||||
@ -255,6 +253,8 @@ void bb_daemonize_or_rexec(int flags, char **argv)
|
|||||||
close(2);
|
close(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd = xopen(bb_dev_null, O_RDWR);
|
||||||
|
|
||||||
while ((unsigned)fd < 2)
|
while ((unsigned)fd < 2)
|
||||||
fd = dup(fd); /* have 0,1,2 open at least to /dev/null */
|
fd = dup(fd); /* have 0,1,2 open at least to /dev/null */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user