Add -P to start-stop-daemon to display a . for each second elapsed.
Fixes #197.
This commit is contained in:
parent
6e485bde39
commit
44585fea46
@ -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:
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user