Update docs for start_stop_daemon to match reality. Update
the reality a bit to better match debian behavior.
This commit is contained in:
parent
55c704c119
commit
63a1a7aaa5
@ -23,21 +23,23 @@
|
|||||||
|
|
||||||
static int signal_nr = 15;
|
static int signal_nr = 15;
|
||||||
static int user_id = -1;
|
static int user_id = -1;
|
||||||
|
static int quiet = 0;
|
||||||
static char *userspec = NULL;
|
static char *userspec = NULL;
|
||||||
static char *cmdname = NULL;
|
static char *cmdname = NULL;
|
||||||
static char *execname = NULL;
|
static char *execname = NULL;
|
||||||
|
static char *pidfile = NULL;
|
||||||
|
|
||||||
typedef struct pid_list {
|
struct pid_list {
|
||||||
struct pid_list *next;
|
struct pid_list *next;
|
||||||
int pid;
|
pid_t pid;
|
||||||
} pid_list;
|
};
|
||||||
|
|
||||||
static pid_list *found = NULL;
|
static struct pid_list *found = NULL;
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
push(int pid)
|
push(pid_t pid)
|
||||||
{
|
{
|
||||||
pid_list *p;
|
struct pid_list *p;
|
||||||
|
|
||||||
p = xmalloc(sizeof(*p));
|
p = xmalloc(sizeof(*p));
|
||||||
p->next = found;
|
p->next = found;
|
||||||
@ -46,22 +48,20 @@ push(int pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pid_is_exec(int pid, const char *exec)
|
pid_is_exec(pid_t pid, const char *name)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[32];
|
||||||
FILE *fp;
|
struct stat sb, exec_stat;
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d/cmdline", pid);
|
if (name && stat(name, &exec_stat))
|
||||||
fp = fopen(buf, "r");
|
bb_perror_msg_and_die("stat %s", name);
|
||||||
if (fp && fgets (buf, sizeof (buf), fp) ) {
|
|
||||||
fclose(fp);
|
sprintf(buf, "/proc/%d/exe", pid);
|
||||||
if (strncmp (buf, exec, strlen(exec)) == 0)
|
if (stat(buf, &sb) != 0)
|
||||||
return 1;
|
return 0;
|
||||||
}
|
return (sb.st_dev == exec_stat.st_dev && sb.st_ino == exec_stat.st_ino);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pid_is_user(int pid, int uid)
|
pid_is_user(int pid, int uid)
|
||||||
{
|
{
|
||||||
@ -74,9 +74,8 @@ pid_is_user(int pid, int uid)
|
|||||||
return (sb.st_uid == uid);
|
return (sb.st_uid == uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pid_is_cmd(int pid, const char *name)
|
pid_is_cmd(pid_t pid, const char *name)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@ -116,9 +115,24 @@ check(int pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_pidfile(const char *name)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
f = fopen(name, "r");
|
||||||
|
if (f) {
|
||||||
|
if (fscanf(f, "%d", &pid) == 1)
|
||||||
|
check(pid);
|
||||||
|
fclose(f);
|
||||||
|
} else if (errno != ENOENT)
|
||||||
|
bb_perror_msg_and_die("open pidfile %s", name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_procfs(void)
|
do_procinit(void)
|
||||||
{
|
{
|
||||||
DIR *procdir;
|
DIR *procdir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
@ -145,9 +159,14 @@ static void
|
|||||||
do_stop(void)
|
do_stop(void)
|
||||||
{
|
{
|
||||||
char what[1024];
|
char what[1024];
|
||||||
pid_list *p;
|
struct pid_list *p;
|
||||||
int killed = 0;
|
int killed = 0;
|
||||||
|
|
||||||
|
if (pidfile)
|
||||||
|
do_pidfile(pidfile);
|
||||||
|
else
|
||||||
|
do_procinit();
|
||||||
|
|
||||||
if (cmdname)
|
if (cmdname)
|
||||||
strcpy(what, cmdname);
|
strcpy(what, cmdname);
|
||||||
else if (execname)
|
else if (execname)
|
||||||
@ -158,7 +177,8 @@ do_stop(void)
|
|||||||
bb_error_msg_and_die ("internal error, please report");
|
bb_error_msg_and_die ("internal error, please report");
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
printf("no %s found; none killed.\n", what);
|
if (!quiet)
|
||||||
|
printf("no %s found; none killed.\n", what);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (p = found; p; p = p->next) {
|
for (p = found; p; p = p->next) {
|
||||||
@ -169,7 +189,7 @@ do_stop(void)
|
|||||||
bb_perror_msg("warning: failed to kill %d:", p->pid);
|
bb_perror_msg("warning: failed to kill %d:", p->pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (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)
|
||||||
@ -183,17 +203,20 @@ static const struct option ssd_long_options[] = {
|
|||||||
{ "stop", 0, NULL, 'K' },
|
{ "stop", 0, NULL, 'K' },
|
||||||
{ "start", 0, NULL, 'S' },
|
{ "start", 0, NULL, 'S' },
|
||||||
{ "background", 0, NULL, 'b' },
|
{ "background", 0, NULL, 'b' },
|
||||||
|
{ "quiet", 0, NULL, 'q' },
|
||||||
{ "startas", 1, NULL, 'a' },
|
{ "startas", 1, NULL, 'a' },
|
||||||
{ "name", 1, NULL, 'n' },
|
{ "name", 1, NULL, 'n' },
|
||||||
{ "signal", 1, NULL, 's' },
|
{ "signal", 1, NULL, 's' },
|
||||||
{ "user", 1, NULL, 'u' },
|
{ "user", 1, NULL, 'u' },
|
||||||
{ "exec", 1, NULL, 'x' },
|
{ "exec", 1, NULL, 'x' },
|
||||||
|
{ "pidfile", 1, NULL, 'p' },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SSD_CTX_STOP 1
|
#define SSD_CTX_STOP 1
|
||||||
#define SSD_CTX_START 2
|
#define SSD_CTX_START 2
|
||||||
#define SSD_OPT_BACKGROUND 4
|
#define SSD_OPT_BACKGROUND 4
|
||||||
|
#define SSD_OPT_QUIET 8
|
||||||
|
|
||||||
int
|
int
|
||||||
start_stop_daemon_main(int argc, char **argv)
|
start_stop_daemon_main(int argc, char **argv)
|
||||||
@ -205,8 +228,8 @@ start_stop_daemon_main(int argc, char **argv)
|
|||||||
bb_applet_long_options = ssd_long_options;
|
bb_applet_long_options = ssd_long_options;
|
||||||
|
|
||||||
bb_opt_complementaly = "K~S:S~K";
|
bb_opt_complementaly = "K~S:S~K";
|
||||||
opt = bb_getopt_ulflags(argc, argv, "KSba:n:s:u:x:",
|
opt = bb_getopt_ulflags(argc, argv, "KSbqa:n:s:u:x:p:",
|
||||||
&startas, &cmdname, &signame, &userspec, &execname);
|
&startas, &cmdname, &signame, &userspec, &execname, &pidfile);
|
||||||
|
|
||||||
/* Check one and only one context option was given */
|
/* Check one and only one context option was given */
|
||||||
if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
|
if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
|
||||||
@ -232,7 +255,7 @@ start_stop_daemon_main(int argc, char **argv)
|
|||||||
if (userspec && sscanf(userspec, "%d", &user_id) != 1)
|
if (userspec && sscanf(userspec, "%d", &user_id) != 1)
|
||||||
user_id = my_getpwnam(userspec);
|
user_id = my_getpwnam(userspec);
|
||||||
|
|
||||||
do_procfs();
|
do_procinit();
|
||||||
|
|
||||||
if (opt & SSD_CTX_STOP) {
|
if (opt & SSD_CTX_STOP) {
|
||||||
do_stop();
|
do_stop();
|
||||||
@ -240,7 +263,8 @@ start_stop_daemon_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
printf("%s already running.\n%d\n", execname ,found->pid);
|
if (!quiet)
|
||||||
|
printf("%s already running.\n%d\n", execname ,found->pid);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
*--argv = startas;
|
*--argv = startas;
|
||||||
|
@ -501,7 +501,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_RUN_PARTS
|
#ifdef CONFIG_RUN_PARTS
|
||||||
APPLET_ODDNAME("run-parts", run_parts_main, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)
|
APPLET_ODDNAME("run-parts", run_parts_main, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_RX
|
#ifdef CONFIG_RX
|
||||||
APPLET(rx, rx_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
APPLET(rx, rx_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1156,7 +1156,7 @@
|
|||||||
"\n" \
|
"\n" \
|
||||||
" <id>:<runlevels>:<action>:<process>\n" \
|
" <id>:<runlevels>:<action>:<process>\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" <id>: \n" \
|
" <id>:\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" WARNING: This field has a non-traditional meaning for BusyBox init!\n" \
|
" WARNING: This field has a non-traditional meaning for BusyBox init!\n" \
|
||||||
" The id field is used by BusyBox init to specify the controlling tty for\n" \
|
" The id field is used by BusyBox init to specify the controlling tty for\n" \
|
||||||
@ -1169,13 +1169,13 @@
|
|||||||
" will be run. BusyBox init does nothing with utmp. We don't need no\n" \
|
" will be run. BusyBox init does nothing with utmp. We don't need no\n" \
|
||||||
" stinkin' utmp.\n" \
|
" stinkin' utmp.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" <runlevels>: \n" \
|
" <runlevels>:\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" The runlevels field is completely ignored.\n" \
|
" The runlevels field is completely ignored.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" <action>: \n" \
|
" <action>:\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" Valid actions include: sysinit, respawn, askfirst, wait, \n" \
|
" Valid actions include: sysinit, respawn, askfirst, wait,\n" \
|
||||||
" once, restart, ctrlaltdel, and shutdown.\n" \
|
" once, restart, ctrlaltdel, and shutdown.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" The available actions can be classified into two groups: actions\n" \
|
" The available actions can be classified into two groups: actions\n" \
|
||||||
@ -1209,13 +1209,13 @@
|
|||||||
" respawn, except that before running the specified process it\n" \
|
" respawn, except that before running the specified process it\n" \
|
||||||
" displays the line "Please press Enter to activate this console."\n" \
|
" displays the line "Please press Enter to activate this console."\n" \
|
||||||
" and then waits for the user to press enter before starting the\n" \
|
" and then waits for the user to press enter before starting the\n" \
|
||||||
" specified process. \n" \
|
" specified process.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" Unrecognized actions (like initdefault) will cause init to emit an\n" \
|
" Unrecognized actions (like initdefault) will cause init to emit an\n" \
|
||||||
" error message, and then go along with its business. All actions are\n" \
|
" error message, and then go along with its business. All actions are\n" \
|
||||||
" run in the order they appear in /etc/inittab.\n" \
|
" run in the order they appear in /etc/inittab.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" <process>: \n" \
|
" <process>:\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
" Specifies the process to be executed and it's command line.\n" \
|
" Specifies the process to be executed and it's command line.\n" \
|
||||||
"\n" \
|
"\n" \
|
||||||
@ -1651,7 +1651,7 @@
|
|||||||
"\tc or u:\tMake a character (un-buffered) device.\n" \
|
"\tc or u:\tMake a character (un-buffered) device.\n" \
|
||||||
"\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes."
|
"\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes."
|
||||||
#define mknod_example_usage \
|
#define mknod_example_usage \
|
||||||
"$ mknod /dev/fd0 b 2 0 \n" \
|
"$ mknod /dev/fd0 b 2 0\n" \
|
||||||
"$ mknod -m 644 /tmp/pipe p\n"
|
"$ mknod -m 644 /tmp/pipe p\n"
|
||||||
|
|
||||||
#define mkswap_trivial_usage \
|
#define mkswap_trivial_usage \
|
||||||
@ -2212,18 +2212,20 @@
|
|||||||
"f\n"
|
"f\n"
|
||||||
|
|
||||||
#define start_stop_daemon_trivial_usage \
|
#define start_stop_daemon_trivial_usage \
|
||||||
"[OPTIONS]"
|
"[OPTIONS] [-S|--start|-K|--stop] ... [-- arguments...]\n"
|
||||||
#define start_stop_daemon_full_usage \
|
#define start_stop_daemon_full_usage \
|
||||||
"Program to start and stop services.\n"\
|
"Program to start and stop services."\
|
||||||
"Options:\n" \
|
"\n\nOptions:"\
|
||||||
"-S\t\t\tstart\n"\
|
"\n\t-S|--start\t\t\tstart"\
|
||||||
"-K\t\t\tstop\n"\
|
"\n\t-K|--stop\t\t\tstop"\
|
||||||
"-b\t\t\tforce process into background (daemonize)\n"\
|
"\n\t-a|--startas <pathname>\t\tstart the process specified by pathname"\
|
||||||
"-x <executable>\t\tprogram to start/check if it is running\n"\
|
"\n\t-b|--background\t\t\tforce process into background"\
|
||||||
"-u <username>|<uid>\tstop this user's processes\n"\
|
"\n\t-u|--user <username>|<uid>\tstop this user's processes"\
|
||||||
"-n <process-name>\tstop processes with this name\n"\
|
"\n\t-x|--exec <executable>\t\tprogram to start/check if it is running"\
|
||||||
"-s <signal>\t\tsignal to send (default 15)\n"\
|
"\n\t-n|--name <process-name>\tstop processes with this name"\
|
||||||
"-a <pathname>\t\tprogram to start (default <executable>)\n"
|
"\n\t-p|--pidfile <pid-file>\t\tsave or load pid using a pid-file"\
|
||||||
|
"\n\t-q|--quiet\t\t\tbe quiet" \
|
||||||
|
"\n\t-s|--signal <signal>\t\tsignal to send (default TERM)\n"
|
||||||
|
|
||||||
#define strings_trivial_usage \
|
#define strings_trivial_usage \
|
||||||
"[-afo] [-n length] [file ... ]"
|
"[-afo] [-n length] [file ... ]"
|
||||||
@ -2478,7 +2480,7 @@
|
|||||||
"$ echo $?\n" \
|
"$ echo $?\n" \
|
||||||
"1\n" \
|
"1\n" \
|
||||||
"$ test 1 -eq 1\n" \
|
"$ test 1 -eq 1\n" \
|
||||||
"$ echo $? \n" \
|
"$ echo $?\n" \
|
||||||
"0\n" \
|
"0\n" \
|
||||||
"$ [ -d /etc ]\n" \
|
"$ [ -d /etc ]\n" \
|
||||||
"$ echo $?\n" \
|
"$ echo $?\n" \
|
||||||
@ -2750,12 +2752,12 @@
|
|||||||
"COMMAND [OPTIONS] ..."
|
"COMMAND [OPTIONS] ..."
|
||||||
|
|
||||||
#define vconfig_full_usage \
|
#define vconfig_full_usage \
|
||||||
"Usage: add [interface-name] [vlan_id] \n" \
|
"Usage: add [interface-name] [vlan_id]\n" \
|
||||||
" rem [vlan-name] \n" \
|
" rem [vlan-name]\n" \
|
||||||
" set_flag [interface-name] [flag-num] [0 | 1] \n" \
|
" set_flag [interface-name] [flag-num] [0 | 1]\n" \
|
||||||
" set_egress_map [vlan-name] [skb_priority] [vlan_qos] \n" \
|
" set_egress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
|
||||||
" set_ingress_map [vlan-name] [skb_priority] [vlan_qos] \n" \
|
" set_ingress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
|
||||||
" set_name_type [name-type] \n"
|
" set_name_type [name-type]\n"
|
||||||
|
|
||||||
#define vi_trivial_usage \
|
#define vi_trivial_usage \
|
||||||
"[OPTION] [FILE]..."
|
"[OPTION] [FILE]..."
|
||||||
|
Loading…
Reference in New Issue
Block a user