From 587051ec679229632d107b24f61d01191f58bc73 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 3 Jun 2008 11:57:15 +0000 Subject: Add the ewaitfile function so init scripts can wait until sockts are created, Gentoo #175783. --- man/runscript.8 | 15 ++++++++++++--- src/rc/Makefile | 2 +- src/rc/rc-applets.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 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; -- cgit v1.2.3