Add -x option which allows to specify the exit status of PROG for which
inotifyd should exit.

An example use case for this change is writing parallel system startup
scripts with busybox' runit: inotifyd can be used to wait for a specific
pid-file to appear in /var/run and then exit, allowing the blocked script
to proceed.

function                                             old     new   delta
inotifyd_main                                        653     741     +88
.rodata                                           157453  157517     +64
packed_usage                                       30506   30556     +50
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 202/0)             Total: 202 bytes
   text    data     bss     dec     hex filename
 828021    4196    9584  841801   cd849 busybox_old
 828165    4196    9584  841945   cd8d9 busybox_unstripped

Signed-off-by: Bartosz Golaszewski <[email protected]>
---
NOTE: I don't quite understand where the increase in size of .rodata
comes from. Looking at objdump output I can see some strings generated
for xstrtol_range() and then some additional non-readable bytes which
are not there when compiling the master branch:

 (...)
 35  404fa0 2f002f64 65762f6e 756c6c00 6e756d62  /./dev/null.numb
 36  404fb0 65722025 73206973 206e6f74 20696e20  er %s is not in
 37  404fc0 256c6c75 2e2e256c 6c752072 616e6765  %llu..%llu range
 38  404fd0 00696e76 616c6964 206e756d 62657220  .invalid number
 39  404fe0 27257327 006e756d 62657220 25732069  '%s'.number %s i
 40  404ff0 73206e6f 7420696e 20256c6c 642e2e25  s not in %lld..%
 41  405000 6c6c6420 72616e67 65000000 00000000  lld range.......
 42  405010 00000000 00000000 00000000 00000000  ................
 43  405020 00000000 00000000 00000000 00000000  ................
 44  405030 00000000 00000000 00000000 00000000  ................
 45  405040 63000000 01000000 77000000 02000000  c.......w.......
 46  405050 62000000 00020000 6b420000 e8030000  b.......kB......
 47  405060 6b440000 e8030000 6b000000 00040000  kD......k.......
 48  405070 4b420000 e8030000 4b440000 e8030000  KB......KD......
 49  405080 4b000000 00040000 4d420000 40420f00  K.......MB..@B..
 50  405090 4d440000 40420f00 4d000000 00001000  [email protected].......
 51  4050a0 47420000 00ca9a3b 47440000 00ca9a3b  GB.....;GD.....;
 52  4050b0 47000000 00000040 00000000 00000000  G......@........
 53  4050c0 62000000 00020000 6b000000 00040000  b.......k.......
 54  4050d0 6d000000 00001000 00000000 00000000  m...............
 (...)

Any ideas?

 miscutils/inotifyd.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c
index 7a1a6a2..97f67ab 100644
--- a/miscutils/inotifyd.c
+++ b/miscutils/inotifyd.c
@@ -28,7 +28,7 @@
  */
 
 //usage:#define inotifyd_trivial_usage
-//usage:       "PROG FILE1[:MASK]..."
+//usage:       "[OPTS] PROG FILE1[:MASK]..."
 //usage:#define inotifyd_full_usage "\n\n"
 //usage:       "Run PROG on filesystem changes."
 //usage:     "\nWhen a filesystem event matching MASK occurs on FILEn,"
@@ -52,12 +52,17 @@
 //usage:     "\n       n       Subfile is created"
 //usage:     "\n       d       Subfile is deleted"
 //usage:     "\n"
+//usage:     "\nOptions:"
+//usage:     "\n       -x STATUS       Exit if PROG returns STATUS"
+//usage:     "\n"
 //usage:     "\ninotifyd waits for PROG to exit."
 //usage:     "\nWhen x event happens for all FILEs, inotifyd exits."
 
 #include "libbb.h"
 #include <sys/inotify.h>
 
+#define OPT_x (1 << 0)
+
 static const char mask_names[] ALIGN1 =
        "a"     // 0x00000001   File was accessed
        "c"     // 0x00000002   File was modified
@@ -84,17 +89,22 @@ enum {
 int inotifyd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int inotifyd_main(int argc, char **argv)
 {
-       int n;
-       unsigned mask;
+       int n, exp_st, st;
+       unsigned mask, opts;
        struct pollfd pfd;
        char **watches; // names of files being watched
        const char *args[5];
+       char *opt_x_str;
+
+       opts = getopt32(argv, "x:", &opt_x_str);
+       argc -= optind;
+       argv += optind;
+       exp_st = xstrtol_range(opt_x_str, 10, 0, 255);
 
        // sanity check: agent and at least one watch must be given
-       if (!argv[1] || !argv[2])
+       if (!argv[0] || !argv[1])
                bb_show_usage();
 
-       argv++;
        // inotify_add_watch will number watched files
        // starting from 1, thus watches[0] is unimportant,
        // and 1st file name is watches[1].
@@ -190,7 +200,9 @@ int inotifyd_main(int argc, char **argv)
                                        args[1] = events;
                                        args[2] = watches[ie->wd];
                                        args[3] = ie->len ? ie->name : NULL;
-                                       spawn_and_wait((char **)args);
+                                       st = spawn_and_wait((char **)args);
+                                       if ((opts & OPT_x) && st == exp_st)
+                                               goto done;
                                }
                                // we are done if all files got final x event
                                if (ie->mask & 0x8000) {
-- 
2.1.4

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to