Update docs for start_stop_daemon to match reality. Update

the reality a bit to better match debian behavior.
This commit is contained in:
Eric Andersen 2004-03-13 08:33:10 +00:00
parent 55c704c119
commit 63a1a7aaa5
3 changed files with 80 additions and 54 deletions

View File

@ -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 0;
return (sb.st_dev == exec_stat.st_dev && sb.st_ino == exec_stat.st_ino);
} }
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,6 +177,7 @@ 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) {
if (!quiet)
printf("no %s found; none killed.\n", what); printf("no %s found; none killed.\n", what);
return; return;
} }
@ -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,6 +263,7 @@ start_stop_daemon_main(int argc, char **argv)
} }
if (found) { if (found) {
if (!quiet)
printf("%s already running.\n%d\n", execname ,found->pid); printf("%s already running.\n%d\n", execname ,found->pid);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -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 ... ]"