diff options
-rw-r--r-- | man/start-stop-daemon.8 | 4 | ||||
-rw-r--r-- | src/rc/start-stop-daemon.c | 70 |
2 files changed, 53 insertions, 21 deletions
diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8 index bb541a2e..01755841 100644 --- a/man/start-stop-daemon.8 +++ b/man/start-stop-daemon.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 22, 2009 +.Dd September 4, 2009 .Dt START-STOP-DAEMON 8 SMM .Os OpenRC .Sh NAME @@ -98,6 +98,8 @@ Print the action(s) that would be taken, but don't actually do anything. The return value is set as if the command was taken and worked. .It Fl v , -verbose Print the action(s) that are taken just before doing them. +.It Fl P , -progress +Echo a . to the console for each second elapsed whilst waiting. .El .Pp These options are only used for starting daemons: diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index a005cfde..d0ee93a8 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -370,16 +370,17 @@ do_stop(const char *exec, const char *const *argv, static int run_stop_schedule(const char *exec, const char *const *argv, const char *pidfile, uid_t uid, - bool quiet, bool verbose, bool test) + bool quiet, bool verbose, bool test, bool progress) { SCHEDULEITEM *item = TAILQ_FIRST(&schedule); int nkilled = 0; int tkilled = 0; int nrunning = 0; - long nloops; + long nloops, nsecs; struct timespec ts; pid_t pid = 0; const char *const *p; + bool progressed = false; if (verbose) { if (exec) @@ -417,6 +418,8 @@ run_stop_schedule(const char *exec, const char *const *argv, quiet, verbose, test); if (nkilled == 0) { if (tkilled == 0) { + if (progressed) + printf("\n"); if (! quiet) eerror("%s: no matching " "processes found", applet); @@ -434,30 +437,47 @@ run_stop_schedule(const char *exec, const char *const *argv, break; } - nloops = (ONE_SECOND / POLL_INTERVAL) * item->value; ts.tv_sec = 0; ts.tv_nsec = POLL_INTERVAL; - while (nloops) { - if ((nrunning = do_stop(exec, argv, pid, - uid, 0, true, false, true)) == 0) - return 0; - - if (nanosleep(&ts, NULL) == -1) { - if (errno == EINTR) - eerror("%s: caught an" - " interrupt", applet); - else { - eerror("%s: nanosleep: %s", - applet, strerror(errno)); + for (nsecs = 0; nsecs < item->value; nsecs++) { + for (nloops = 0; + nloops < ONE_SECOND / POLL_INTERVAL; + nloops++) + { + if ((nrunning = do_stop(exec, argv, + pid, uid, 0, true, false, + true)) == 0) return 0; + + + if (nanosleep(&ts, NULL) == -1) { + if (progressed) { + printf("\n"); + progressed = false; + } + if (errno == EINTR) + eerror("%s: caught an" + " interrupt", applet); + else { + eerror("%s: nanosleep: %s", + applet, strerror(errno)); + return 0; + } } } - nloops --; + if (progress) { + printf("."); + fflush(stdout); + progressed = true; + } } break; - default: + if (progressed) { + printf("\n"); + progressed = false; + } eerror("%s: invalid schedule item `%d'", applet, item->type); return 0; @@ -470,6 +490,8 @@ run_stop_schedule(const char *exec, const char *const *argv, if (test || (tkilled > 0 && nrunning == 0)) return nkilled; + if (progressed) + printf("\n"); if (! quiet) { if (nrunning == 1) eerror("%s: %d process refused to stop", @@ -550,7 +572,7 @@ expand_home(const char *home, const char *path) ppath++; if (!home) { - free(opath); + free(opath); return xstrdup(path); } if (!ppath) { @@ -566,7 +588,7 @@ expand_home(const char *home, const char *path) } #include "_usage.h" -#define getoptstring "KN:R:Sbc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" getoptstring_COMMON +#define getoptstring "KN:PR:Sbc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" getoptstring_COMMON static const struct option longopts[] = { { "stop", 0, NULL, 'K'}, { "nicelevel", 1, NULL, 'N'}, @@ -592,6 +614,7 @@ static const struct option longopts[] = { { "exec", 1, NULL, 'x'}, { "stdout", 1, NULL, '1'}, { "stderr", 1, NULL, '2'}, + { "progress", 0, NULL, 'P'}, longopts_COMMON }; static const char * const longopts_help[] = { @@ -619,6 +642,7 @@ static const char * const longopts_help[] = { "Binary to start/stop", "Redirect stdout to file", "Redirect stderr to file", + "Print dots each second while waiting", longopts_help_COMMON }; #include "_usage.c" @@ -654,6 +678,7 @@ start_stop_daemon(int argc, char **argv) bool background = false; bool makepidfile = false; bool interpreted = false; + bool progress = false; uid_t uid = 0; gid_t gid = 0; char *home = NULL; @@ -715,12 +740,17 @@ start_stop_daemon(int argc, char **argv) case 'K': /* --stop */ stop = true; break; + case 'N': /* --nice */ if (sscanf(optarg, "%d", &nicelevel) != 1) eerrorx("%s: invalid nice level `%s'", applet, optarg); break; + case 'P': /* --progress */ + progress = true; + break; + case 'R': /* --retry <schedule>|<timeout> */ retry = optarg; break; @@ -1002,7 +1032,7 @@ start_stop_daemon(int argc, char **argv) else parse_schedule(NULL, sig); i = run_stop_schedule(exec, (const char *const *)margv, - pidfile, uid, quiet, verbose, test); + pidfile, uid, quiet, verbose, test, progress); if (i < 0) /* We failed to stop something */ |