aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debianutils/start_stop_daemon.c82
-rw-r--r--include/applets.h2
-rw-r--r--include/usage.h52
3 files changed, 81 insertions, 55 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index dfa33e1f9..6bc259fb3 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -23,21 +23,23 @@
23 23
24static int signal_nr = 15; 24static int signal_nr = 15;
25static int user_id = -1; 25static int user_id = -1;
26static int quiet = 0;
26static char *userspec = NULL; 27static char *userspec = NULL;
27static char *cmdname = NULL; 28static char *cmdname = NULL;
28static char *execname = NULL; 29static char *execname = NULL;
30static char *pidfile = NULL;
29 31
30typedef struct pid_list { 32struct pid_list {
31 struct pid_list *next; 33 struct pid_list *next;
32 int pid; 34 pid_t pid;
33} pid_list; 35};
34 36
35static pid_list *found = NULL; 37static struct pid_list *found = NULL;
36 38
37static inline void 39static inline void
38push(int pid) 40push(pid_t pid)
39{ 41{
40 pid_list *p; 42 struct pid_list *p;
41 43
42 p = xmalloc(sizeof(*p)); 44 p = xmalloc(sizeof(*p));
43 p->next = found; 45 p->next = found;
@@ -46,21 +48,19 @@ push(int pid)
46} 48}
47 49
48static int 50static int
49pid_is_exec(int pid, const char *exec) 51pid_is_exec(pid_t pid, const char *name)
50{ 52{
51 char buf[PATH_MAX]; 53 char buf[32];
52 FILE *fp; 54 struct stat sb, exec_stat;
53
54 sprintf(buf, "/proc/%d/cmdline", pid);
55 fp = fopen(buf, "r");
56 if (fp && fgets (buf, sizeof (buf), fp) ) {
57 fclose(fp);
58 if (strncmp (buf, exec, strlen(exec)) == 0)
59 return 1;
60 }
61 return 0;
62}
63 55
56 if (name && stat(name, &exec_stat))
57 bb_perror_msg_and_die("stat %s", name);
58
59 sprintf(buf, "/proc/%d/exe", pid);
60 if (stat(buf, &sb) != 0)
61 return 0;
62 return (sb.st_dev == exec_stat.st_dev && sb.st_ino == exec_stat.st_ino);
63}
64 64
65static int 65static int
66pid_is_user(int pid, int uid) 66pid_is_user(int pid, int uid)
@@ -74,9 +74,8 @@ pid_is_user(int pid, int uid)
74 return (sb.st_uid == uid); 74 return (sb.st_uid == uid);
75} 75}
76 76
77
78static int 77static int
79pid_is_cmd(int pid, const char *name) 78pid_is_cmd(pid_t pid, const char *name)
80{ 79{
81 char buf[32]; 80 char buf[32];
82 FILE *f; 81 FILE *f;
@@ -116,9 +115,24 @@ check(int pid)
116} 115}
117 116
118 117
118static void
119do_pidfile(const char *name)
120{
121 FILE *f;
122 pid_t pid;
123
124 f = fopen(name, "r");
125 if (f) {
126 if (fscanf(f, "%d", &pid) == 1)
127 check(pid);
128 fclose(f);
129 } else if (errno != ENOENT)
130 bb_perror_msg_and_die("open pidfile %s", name);
131
132}
119 133
120static void 134static void
121do_procfs(void) 135do_procinit(void)
122{ 136{
123 DIR *procdir; 137 DIR *procdir;
124 struct dirent *entry; 138 struct dirent *entry;
@@ -145,9 +159,14 @@ static void
145do_stop(void) 159do_stop(void)
146{ 160{
147 char what[1024]; 161 char what[1024];
148 pid_list *p; 162 struct pid_list *p;
149 int killed = 0; 163 int killed = 0;
150 164
165 if (pidfile)
166 do_pidfile(pidfile);
167 else
168 do_procinit();
169
151 if (cmdname) 170 if (cmdname)
152 strcpy(what, cmdname); 171 strcpy(what, cmdname);
153 else if (execname) 172 else if (execname)
@@ -158,7 +177,8 @@ do_stop(void)
158 bb_error_msg_and_die ("internal error, please report"); 177 bb_error_msg_and_die ("internal error, please report");
159 178
160 if (!found) { 179 if (!found) {
161 printf("no %s found; none killed.\n", what); 180 if (!quiet)
181 printf("no %s found; none killed.\n", what);
162 return; 182 return;
163 } 183 }
164 for (p = found; p; p = p->next) { 184 for (p = found; p; p = p->next) {
@@ -169,7 +189,7 @@ do_stop(void)
169 bb_perror_msg("warning: failed to kill %d:", p->pid); 189 bb_perror_msg("warning: failed to kill %d:", p->pid);
170 } 190 }
171 } 191 }
172 if (killed) { 192 if (!quiet && killed) {
173 printf("stopped %s (pid", what); 193 printf("stopped %s (pid", what);
174 for (p = found; p; p = p->next) 194 for (p = found; p; p = p->next)
175 if(p->pid < 0) 195 if(p->pid < 0)
@@ -183,17 +203,20 @@ static const struct option ssd_long_options[] = {
183 { "stop", 0, NULL, 'K' }, 203 { "stop", 0, NULL, 'K' },
184 { "start", 0, NULL, 'S' }, 204 { "start", 0, NULL, 'S' },
185 { "background", 0, NULL, 'b' }, 205 { "background", 0, NULL, 'b' },
206 { "quiet", 0, NULL, 'q' },
186 { "startas", 1, NULL, 'a' }, 207 { "startas", 1, NULL, 'a' },
187 { "name", 1, NULL, 'n' }, 208 { "name", 1, NULL, 'n' },
188 { "signal", 1, NULL, 's' }, 209 { "signal", 1, NULL, 's' },
189 { "user", 1, NULL, 'u' }, 210 { "user", 1, NULL, 'u' },
190 { "exec", 1, NULL, 'x' }, 211 { "exec", 1, NULL, 'x' },
212 { "pidfile", 1, NULL, 'p' },
191 { 0, 0, 0, 0 } 213 { 0, 0, 0, 0 }
192}; 214};
193 215
194#define SSD_CTX_STOP 1 216#define SSD_CTX_STOP 1
195#define SSD_CTX_START 2 217#define SSD_CTX_START 2
196#define SSD_OPT_BACKGROUND 4 218#define SSD_OPT_BACKGROUND 4
219#define SSD_OPT_QUIET 8
197 220
198int 221int
199start_stop_daemon_main(int argc, char **argv) 222start_stop_daemon_main(int argc, char **argv)
@@ -205,8 +228,8 @@ start_stop_daemon_main(int argc, char **argv)
205 bb_applet_long_options = ssd_long_options; 228 bb_applet_long_options = ssd_long_options;
206 229
207 bb_opt_complementaly = "K~S:S~K"; 230 bb_opt_complementaly = "K~S:S~K";
208 opt = bb_getopt_ulflags(argc, argv, "KSba:n:s:u:x:", 231 opt = bb_getopt_ulflags(argc, argv, "KSbqa:n:s:u:x:p:",
209 &startas, &cmdname, &signame, &userspec, &execname); 232 &startas, &cmdname, &signame, &userspec, &execname, &pidfile);
210 233
211 /* Check one and only one context option was given */ 234 /* Check one and only one context option was given */
212 if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) { 235 if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
@@ -232,7 +255,7 @@ start_stop_daemon_main(int argc, char **argv)
232 if (userspec && sscanf(userspec, "%d", &user_id) != 1) 255 if (userspec && sscanf(userspec, "%d", &user_id) != 1)
233 user_id = my_getpwnam(userspec); 256 user_id = my_getpwnam(userspec);
234 257
235 do_procfs(); 258 do_procinit();
236 259
237 if (opt & SSD_CTX_STOP) { 260 if (opt & SSD_CTX_STOP) {
238 do_stop(); 261 do_stop();
@@ -240,7 +263,8 @@ start_stop_daemon_main(int argc, char **argv)
240 } 263 }
241 264
242 if (found) { 265 if (found) {
243 printf("%s already running.\n%d\n", execname ,found->pid); 266 if (!quiet)
267 printf("%s already running.\n%d\n", execname ,found->pid);
244 return EXIT_SUCCESS; 268 return EXIT_SUCCESS;
245 } 269 }
246 *--argv = startas; 270 *--argv = startas;
diff --git a/include/applets.h b/include/applets.h
index f3b5f3d1c..585ea1f68 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -501,7 +501,7 @@
501#endif 501#endif
502#ifdef CONFIG_RUN_PARTS 502#ifdef CONFIG_RUN_PARTS
503 APPLET_ODDNAME("run-parts", run_parts_main, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts) 503 APPLET_ODDNAME("run-parts", run_parts_main, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)
504#endif 504#endif
505#ifdef CONFIG_RX 505#ifdef CONFIG_RX
506 APPLET(rx, rx_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) 506 APPLET(rx, rx_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
507#endif 507#endif
diff --git a/include/usage.h b/include/usage.h
index ec8f3c808..272c3d055 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -1156,7 +1156,7 @@
1156"\n" \ 1156"\n" \
1157" <id>:<runlevels>:<action>:<process>\n" \ 1157" <id>:<runlevels>:<action>:<process>\n" \
1158"\n" \ 1158"\n" \
1159" <id>: \n" \ 1159" <id>:\n" \
1160"\n" \ 1160"\n" \
1161" WARNING: This field has a non-traditional meaning for BusyBox init!\n" \ 1161" WARNING: This field has a non-traditional meaning for BusyBox init!\n" \
1162" The id field is used by BusyBox init to specify the controlling tty for\n" \ 1162" The id field is used by BusyBox init to specify the controlling tty for\n" \
@@ -1169,13 +1169,13 @@
1169" will be run. BusyBox init does nothing with utmp. We don't need no\n" \ 1169" will be run. BusyBox init does nothing with utmp. We don't need no\n" \
1170" stinkin' utmp.\n" \ 1170" stinkin' utmp.\n" \
1171"\n" \ 1171"\n" \
1172" <runlevels>: \n" \ 1172" <runlevels>:\n" \
1173"\n" \ 1173"\n" \
1174" The runlevels field is completely ignored.\n" \ 1174" The runlevels field is completely ignored.\n" \
1175"\n" \ 1175"\n" \
1176" <action>: \n" \ 1176" <action>:\n" \
1177"\n" \ 1177"\n" \
1178" Valid actions include: sysinit, respawn, askfirst, wait, \n" \ 1178" Valid actions include: sysinit, respawn, askfirst, wait,\n" \
1179" once, restart, ctrlaltdel, and shutdown.\n" \ 1179" once, restart, ctrlaltdel, and shutdown.\n" \
1180"\n" \ 1180"\n" \
1181" The available actions can be classified into two groups: actions\n" \ 1181" The available actions can be classified into two groups: actions\n" \
@@ -1209,13 +1209,13 @@
1209" respawn, except that before running the specified process it\n" \ 1209" respawn, except that before running the specified process it\n" \
1210" displays the line "Please press Enter to activate this console."\n" \ 1210" displays the line "Please press Enter to activate this console."\n" \
1211" and then waits for the user to press enter before starting the\n" \ 1211" and then waits for the user to press enter before starting the\n" \
1212" specified process. \n" \ 1212" specified process.\n" \
1213"\n" \ 1213"\n" \
1214" Unrecognized actions (like initdefault) will cause init to emit an\n" \ 1214" Unrecognized actions (like initdefault) will cause init to emit an\n" \
1215" error message, and then go along with its business. All actions are\n" \ 1215" error message, and then go along with its business. All actions are\n" \
1216" run in the order they appear in /etc/inittab.\n" \ 1216" run in the order they appear in /etc/inittab.\n" \
1217"\n" \ 1217"\n" \
1218" <process>: \n" \ 1218" <process>:\n" \
1219"\n" \ 1219"\n" \
1220" Specifies the process to be executed and it's command line.\n" \ 1220" Specifies the process to be executed and it's command line.\n" \
1221"\n" \ 1221"\n" \
@@ -1651,7 +1651,7 @@
1651 "\tc or u:\tMake a character (un-buffered) device.\n" \ 1651 "\tc or u:\tMake a character (un-buffered) device.\n" \
1652 "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes." 1652 "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes."
1653#define mknod_example_usage \ 1653#define mknod_example_usage \
1654 "$ mknod /dev/fd0 b 2 0 \n" \ 1654 "$ mknod /dev/fd0 b 2 0\n" \
1655 "$ mknod -m 644 /tmp/pipe p\n" 1655 "$ mknod -m 644 /tmp/pipe p\n"
1656 1656
1657#define mkswap_trivial_usage \ 1657#define mkswap_trivial_usage \
@@ -2212,18 +2212,20 @@
2212 "f\n" 2212 "f\n"
2213 2213
2214#define start_stop_daemon_trivial_usage \ 2214#define start_stop_daemon_trivial_usage \
2215 "[OPTIONS]" 2215 "[OPTIONS] [-S|--start|-K|--stop] ... [-- arguments...]\n"
2216#define start_stop_daemon_full_usage \ 2216#define start_stop_daemon_full_usage \
2217 "Program to start and stop services.\n"\ 2217 "Program to start and stop services."\
2218 "Options:\n" \ 2218 "\n\nOptions:"\
2219 "-S\t\t\tstart\n"\ 2219 "\n\t-S|--start\t\t\tstart"\
2220 "-K\t\t\tstop\n"\ 2220 "\n\t-K|--stop\t\t\tstop"\
2221 "-b\t\t\tforce process into background (daemonize)\n"\ 2221 "\n\t-a|--startas <pathname>\t\tstart the process specified by pathname"\
2222 "-x <executable>\t\tprogram to start/check if it is running\n"\ 2222 "\n\t-b|--background\t\t\tforce process into background"\
2223 "-u <username>|<uid>\tstop this user's processes\n"\ 2223 "\n\t-u|--user <username>|<uid>\tstop this user's processes"\
2224 "-n <process-name>\tstop processes with this name\n"\ 2224 "\n\t-x|--exec <executable>\t\tprogram to start/check if it is running"\
2225 "-s <signal>\t\tsignal to send (default 15)\n"\ 2225 "\n\t-n|--name <process-name>\tstop processes with this name"\
2226 "-a <pathname>\t\tprogram to start (default <executable>)\n" 2226 "\n\t-p|--pidfile <pid-file>\t\tsave or load pid using a pid-file"\
2227 "\n\t-q|--quiet\t\t\tbe quiet" \
2228 "\n\t-s|--signal <signal>\t\tsignal to send (default TERM)\n"
2227 2229
2228#define strings_trivial_usage \ 2230#define strings_trivial_usage \
2229 "[-afo] [-n length] [file ... ]" 2231 "[-afo] [-n length] [file ... ]"
@@ -2478,7 +2480,7 @@
2478 "$ echo $?\n" \ 2480 "$ echo $?\n" \
2479 "1\n" \ 2481 "1\n" \
2480 "$ test 1 -eq 1\n" \ 2482 "$ test 1 -eq 1\n" \
2481 "$ echo $? \n" \ 2483 "$ echo $?\n" \
2482 "0\n" \ 2484 "0\n" \
2483 "$ [ -d /etc ]\n" \ 2485 "$ [ -d /etc ]\n" \
2484 "$ echo $?\n" \ 2486 "$ echo $?\n" \
@@ -2750,12 +2752,12 @@
2750 "COMMAND [OPTIONS] ..." 2752 "COMMAND [OPTIONS] ..."
2751 2753
2752#define vconfig_full_usage \ 2754#define vconfig_full_usage \
2753"Usage: add [interface-name] [vlan_id] \n" \ 2755"Usage: add [interface-name] [vlan_id]\n" \
2754" rem [vlan-name] \n" \ 2756" rem [vlan-name]\n" \
2755" set_flag [interface-name] [flag-num] [0 | 1] \n" \ 2757" set_flag [interface-name] [flag-num] [0 | 1]\n" \
2756" set_egress_map [vlan-name] [skb_priority] [vlan_qos] \n" \ 2758" set_egress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
2757" set_ingress_map [vlan-name] [skb_priority] [vlan_qos] \n" \ 2759" set_ingress_map [vlan-name] [skb_priority] [vlan_qos]\n" \
2758" set_name_type [name-type] \n" 2760" set_name_type [name-type]\n"
2759 2761
2760#define vi_trivial_usage \ 2762#define vi_trivial_usage \
2761 "[OPTION] [FILE]..." 2763 "[OPTION] [FILE]..."