summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-09-04 15:41:08 +0100
committerRoy Marples <roy@marples.name>2009-09-04 15:41:08 +0100
commit44585fea46c81791e15d33b7f8ad939ebbc2cb6c (patch)
treeff6f11653354f7eaaebd282f35ed679c999475ad
parent6e485bde39dcb41e6e6b0874cc3a83027cf2b94e (diff)
downloadopenrc-44585fea46c81791e15d33b7f8ad939ebbc2cb6c.tar.gz
openrc-44585fea46c81791e15d33b7f8ad939ebbc2cb6c.tar.bz2
openrc-44585fea46c81791e15d33b7f8ad939ebbc2cb6c.tar.xz
Add -P to start-stop-daemon to display a . for each second elapsed.
Fixes #197.
-rw-r--r--man/start-stop-daemon.84
-rw-r--r--src/rc/start-stop-daemon.c70
2 files changed, 53 insertions, 21 deletions
diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8
index bb541a2..0175584 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 a005cfd..d0ee93a 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 */