Add -P to start-stop-daemon to display a . for each second elapsed.

Fixes #197.
This commit is contained in:
Roy Marples 2009-09-04 15:41:08 +01:00
parent 6e485bde39
commit 44585fea46
2 changed files with 53 additions and 21 deletions

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd April 22, 2009 .Dd September 4, 2009
.Dt START-STOP-DAEMON 8 SMM .Dt START-STOP-DAEMON 8 SMM
.Os OpenRC .Os OpenRC
.Sh NAME .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. The return value is set as if the command was taken and worked.
.It Fl v , -verbose .It Fl v , -verbose
Print the action(s) that are taken just before doing them. 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 .El
.Pp .Pp
These options are only used for starting daemons: These options are only used for starting daemons:

View File

@ -370,16 +370,17 @@ do_stop(const char *exec, const char *const *argv,
static int static int
run_stop_schedule(const char *exec, const char *const *argv, run_stop_schedule(const char *exec, const char *const *argv,
const char *pidfile, uid_t uid, 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); SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
int nkilled = 0; int nkilled = 0;
int tkilled = 0; int tkilled = 0;
int nrunning = 0; int nrunning = 0;
long nloops; long nloops, nsecs;
struct timespec ts; struct timespec ts;
pid_t pid = 0; pid_t pid = 0;
const char *const *p; const char *const *p;
bool progressed = false;
if (verbose) { if (verbose) {
if (exec) if (exec)
@ -417,6 +418,8 @@ run_stop_schedule(const char *exec, const char *const *argv,
quiet, verbose, test); quiet, verbose, test);
if (nkilled == 0) { if (nkilled == 0) {
if (tkilled == 0) { if (tkilled == 0) {
if (progressed)
printf("\n");
if (! quiet) if (! quiet)
eerror("%s: no matching " eerror("%s: no matching "
"processes found", applet); "processes found", applet);
@ -434,30 +437,47 @@ run_stop_schedule(const char *exec, const char *const *argv,
break; break;
} }
nloops = (ONE_SECOND / POLL_INTERVAL) * item->value;
ts.tv_sec = 0; ts.tv_sec = 0;
ts.tv_nsec = POLL_INTERVAL; ts.tv_nsec = POLL_INTERVAL;
while (nloops) { for (nsecs = 0; nsecs < item->value; nsecs++) {
if ((nrunning = do_stop(exec, argv, pid, for (nloops = 0;
uid, 0, true, false, true)) == 0) nloops < ONE_SECOND / POLL_INTERVAL;
return 0; nloops++)
{
if (nanosleep(&ts, NULL) == -1) { if ((nrunning = do_stop(exec, argv,
if (errno == EINTR) pid, uid, 0, true, false,
eerror("%s: caught an" true)) == 0)
" interrupt", applet);
else {
eerror("%s: nanosleep: %s",
applet, strerror(errno));
return 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; break;
default: default:
if (progressed) {
printf("\n");
progressed = false;
}
eerror("%s: invalid schedule item `%d'", eerror("%s: invalid schedule item `%d'",
applet, item->type); applet, item->type);
return 0; return 0;
@ -470,6 +490,8 @@ run_stop_schedule(const char *exec, const char *const *argv,
if (test || (tkilled > 0 && nrunning == 0)) if (test || (tkilled > 0 && nrunning == 0))
return nkilled; return nkilled;
if (progressed)
printf("\n");
if (! quiet) { if (! quiet) {
if (nrunning == 1) if (nrunning == 1)
eerror("%s: %d process refused to stop", eerror("%s: %d process refused to stop",
@ -550,7 +572,7 @@ expand_home(const char *home, const char *path)
ppath++; ppath++;
if (!home) { if (!home) {
free(opath); free(opath);
return xstrdup(path); return xstrdup(path);
} }
if (!ppath) { if (!ppath) {
@ -566,7 +588,7 @@ expand_home(const char *home, const char *path)
} }
#include "_usage.h" #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[] = { static const struct option longopts[] = {
{ "stop", 0, NULL, 'K'}, { "stop", 0, NULL, 'K'},
{ "nicelevel", 1, NULL, 'N'}, { "nicelevel", 1, NULL, 'N'},
@ -592,6 +614,7 @@ static const struct option longopts[] = {
{ "exec", 1, NULL, 'x'}, { "exec", 1, NULL, 'x'},
{ "stdout", 1, NULL, '1'}, { "stdout", 1, NULL, '1'},
{ "stderr", 1, NULL, '2'}, { "stderr", 1, NULL, '2'},
{ "progress", 0, NULL, 'P'},
longopts_COMMON longopts_COMMON
}; };
static const char * const longopts_help[] = { static const char * const longopts_help[] = {
@ -619,6 +642,7 @@ static const char * const longopts_help[] = {
"Binary to start/stop", "Binary to start/stop",
"Redirect stdout to file", "Redirect stdout to file",
"Redirect stderr to file", "Redirect stderr to file",
"Print dots each second while waiting",
longopts_help_COMMON longopts_help_COMMON
}; };
#include "_usage.c" #include "_usage.c"
@ -654,6 +678,7 @@ start_stop_daemon(int argc, char **argv)
bool background = false; bool background = false;
bool makepidfile = false; bool makepidfile = false;
bool interpreted = false; bool interpreted = false;
bool progress = false;
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
char *home = NULL; char *home = NULL;
@ -715,12 +740,17 @@ start_stop_daemon(int argc, char **argv)
case 'K': /* --stop */ case 'K': /* --stop */
stop = true; stop = true;
break; break;
case 'N': /* --nice */ case 'N': /* --nice */
if (sscanf(optarg, "%d", &nicelevel) != 1) if (sscanf(optarg, "%d", &nicelevel) != 1)
eerrorx("%s: invalid nice level `%s'", eerrorx("%s: invalid nice level `%s'",
applet, optarg); applet, optarg);
break; break;
case 'P': /* --progress */
progress = true;
break;
case 'R': /* --retry <schedule>|<timeout> */ case 'R': /* --retry <schedule>|<timeout> */
retry = optarg; retry = optarg;
break; break;
@ -1002,7 +1032,7 @@ start_stop_daemon(int argc, char **argv)
else else
parse_schedule(NULL, sig); parse_schedule(NULL, sig);
i = run_stop_schedule(exec, (const char *const *)margv, i = run_stop_schedule(exec, (const char *const *)margv,
pidfile, uid, quiet, verbose, test); pidfile, uid, quiet, verbose, test, progress);
if (i < 0) if (i < 0)
/* We failed to stop something */ /* We failed to stop something */