summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/runscript.815
-rw-r--r--src/rc/Makefile2
-rw-r--r--src/rc/rc-applets.c47
3 files changed, 57 insertions, 7 deletions
diff --git a/man/runscript.8 b/man/runscript.8
index 6f3bd43..b219e52 100644
--- a/man/runscript.8
+++ b/man/runscript.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Mar 19, 2008
+.Dd Jun 03, 2008
.Dt RUNSCRIPT 8 SMM
.Os OpenRC
.Sh NAME
@@ -173,8 +173,9 @@ If
does not equal 0 then output the string using
.Ic eerror
and !! in square brackets
-at the end of the line. Otherwise output ok in square brackets at the end of
-the line. The value of
+at the end of the line.
+Otherwise output ok in square brackets at the end of the line.
+The value of
.Ar retval
is returned.
.It Ic ewend Ar retval Op Ar string
@@ -193,6 +194,14 @@ output when the environment variable
.Va EINFO_VERBOSE
is true.
.Bl -tag -width indent
+.It Ic ewaitfile Ar timeout Ar file1 Ar file2 ...
+Wait for
+.Ar timeout
+seconds until all files exist.
+Returns 0 if all files exist, otherwise non zero.
+If
+.Ar timeout
+is less then 1 then we wait indefinitely.
.It Ic is_newer_than Ar file1 Ar file2 ...
If
.Ar file1
diff --git a/src/rc/Makefile b/src/rc/Makefile
index 17d6330..206d66b 100644
--- a/src/rc/Makefile
+++ b/src/rc/Makefile
@@ -13,7 +13,7 @@ LINKDIR= ${PREFIX}/${LIBNAME}/${PROG}
BINLINKS= rc-status
SBINLINKS= rc-service rc-update runscript start-stop-daemon
RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
- eindent eoutdent esyslog eval_ecolors \
+ eindent eoutdent esyslog eval_ecolors ewaitfile \
veinfo vewarn vebegin veend vewend veindent veoutdent \
service_starting service_started \
service_stopping service_stopped \
diff --git a/src/rc/rc-applets.c b/src/rc/rc-applets.c
index 60c0c27..1649fb8 100644
--- a/src/rc/rc-applets.c
+++ b/src/rc/rc-applets.c
@@ -51,6 +51,10 @@
#include "einfo.h"
#include "rc-misc.h"
+/* usecs to wait while we poll the file existance */
+#define WAIT_INTERVAL 20000000
+#define ONE_SECOND 690000000
+
/* Applet is first parsed in rc.c - no point in doing it again */
extern const char *applet;
@@ -77,6 +81,8 @@ static int do_e(int argc, char **argv)
char *p;
int level = 0;
const char *fmt = "%s";
+ struct timespec ts;
+ struct timeval stop, now;
/* Punt applet */
argc--;
@@ -97,11 +103,14 @@ static int do_e(int argc, char **argv)
if (strcmp(applet, "eend") == 0 ||
strcmp(applet, "ewend") == 0 ||
strcmp(applet, "veend") == 0 ||
- strcmp(applet, "vweend") == 0)
+ strcmp(applet, "vweend") == 0 ||
+ strcmp(applet, "ewaitfile") == 0)
{
errno = 0;
- retval = (int) strtoimax(argv[0], NULL, 0);
- if (errno != 0)
+ retval = (int)strtoimax(argv[0], &p, 0);
+ if (!p || *p != '\0')
+ errno = EINVAL;
+ if (errno)
retval = EXIT_FAILURE;
else {
argc--;
@@ -124,6 +133,38 @@ static int do_e(int argc, char **argv)
}
}
+ if (strcmp(applet, "ewaitfile") == 0) {
+ if (errno)
+ eerrorx("%s: invalid timeout", applet);
+ if (argc == 0)
+ eerrorx("%s: not enough arguments", applet);
+
+ gettimeofday(&stop, NULL);
+ /* retval stores the timeout */
+ stop.tv_sec += retval;
+ ts.tv_sec = 0;
+ ts.tv_nsec = WAIT_INTERVAL;
+ for (i = 0; i < argc; i++) {
+ ebeginv("Waiting for %s", argv[i]);
+ for (;;){
+ if (exists(argv[i]))
+ break;
+ if (nanosleep(&ts, NULL) == -1)
+ return EXIT_FAILURE;
+ gettimeofday(&now, NULL);
+ if (retval <= 0)
+ continue;
+ if (timercmp(&now, &stop, <))
+ continue;
+ eendv(EXIT_FAILURE,
+ "timed out waiting for %s", argv[i]);
+ return EXIT_FAILURE;
+ }
+ eendv(EXIT_SUCCESS, NULL);
+ }
+ return EXIT_SUCCESS;
+ }
+
if (argc > 0) {
for (i = 0; i < argc; i++)
l += strlen(argv[i]) + 1;