about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-05-22 15:27:32 +0200
committerLeah Neukirchen <leah@vuxu.org>2017-05-22 15:27:32 +0200
commitbd207274add1bd0f8d90e6944bd20cf20bdcfed1 (patch)
treef941e42935c04c85465db0f4dc64fa29f7d2eec8
parent328f70c47e5dcf4eea650ffcc967310353b38d24 (diff)
downloadrwc-bd207274add1bd0f8d90e6944bd20cf20bdcfed1.tar.gz
rwc-bd207274add1bd0f8d90e6944bd20cf20bdcfed1.tar.xz
rwc-bd207274add1bd0f8d90e6944bd20cf20bdcfed1.zip
rwc: add -p to avoid writing into non-empty pipes
-rw-r--r--README8
-rw-r--r--rwc.110
-rw-r--r--rwc.c14
3 files changed, 26 insertions, 6 deletions
diff --git a/README b/README
index b93d8f8..c693be7 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ NAME
      rwc – report when changed
 
 SYNOPSIS
-     rwc [-0d] [path ...]
+     rwc [-0dp] [path ...]
 
 DESCRIPTION
      rwc takes a list of files or directories, watches them using inotify(7),
@@ -22,13 +22,17 @@ DESCRIPTION
      -d      Also detect file deletion.  In this case, deleted files are
              prefixed by ‘- ’ (that is, a dash and a space).
 
+     -p      Pipe mode; don't report changes while the standard output pipe is
+             not empty.  Use this to pipe rwc to programs which read standard
+             input slowly.
+
 EXIT STATUS
      The rwc utility exits 0 on success, and >0 if an error occurs.
 
 EXAMPLES
      Watch all source files and run make(1) when something changes:
 
-           % git ls-files | rwc | xe -v -s make
+           % git ls-files | rwc -p | xe -v -s make
 
      Make a sound when a download is done:
 
diff --git a/rwc.1 b/rwc.1
index b300e98..57c9d22 100644
--- a/rwc.1
+++ b/rwc.1
@@ -6,7 +6,7 @@
 .Nd report when changed
 .Sh SYNOPSIS
 .Nm
-.Op Fl 0d
+.Op Fl 0dp
 .Op Ar path\ ...
 .Sh DESCRIPTION
 .Nm
@@ -34,6 +34,12 @@ Also detect file deletion.
 In this case, deleted files are prefixed by
 .Sq Li "- "
 (that is, a dash and a space).
+.It Fl p
+Pipe mode;
+don't report changes while the standard output pipe is not empty.
+Use this to pipe
+.Nm
+to programs which read standard input slowly.
 .El
 .Sh EXIT STATUS
 .Ex -std
@@ -42,7 +48,7 @@ Watch all source files and run
 .Xr make 1
 when something changes:
 .Pp
-.Dl % git ls-files | rwc | xe -v -s make
+.Dl % git ls-files | rwc -p | xe -v -s make
 .Pp
 Make a sound when a download is done:
 .Pp
diff --git a/rwc.c b/rwc.c
index 1dd293d..a49c53e 100644
--- a/rwc.c
+++ b/rwc.c
@@ -1,13 +1,15 @@
 /*
- * rwc [-0d] [PATH...] - report when changed
+ * rwc [-0dp] [PATH...] - report when changed
  *  -0  use NUL instead of newline for input/output separator
  *  -d  detect deletions too (prefixed with "- ")
+ *  -p  pipe mode, don't generate new events if stdout pipe is not empty
  *
  * To the extent possible under law, Leah Neukirchen <leah@vuxu.org>
  * has waived all copyright and related or neighboring rights to this work.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
+#include <sys/ioctl.h>
 #include <sys/inotify.h>
 #include <sys/stat.h>
 
@@ -25,6 +27,7 @@ char ibuf[8192];
 int ifd;
 
 int dflag;
+int pflag;
 char input_delim = '\n';
 
 static void *root = 0; // tree
@@ -90,10 +93,11 @@ main(int argc, char *argv[])
 
 	argv0 = argv[0];
 
-        while ((c = getopt(argc, argv, "0d")) != -1)
+        while ((c = getopt(argc, argv, "0dp")) != -1)
 		switch(c) {
 		case '0': input_delim = 0; break;
 		case 'd': dflag = IN_DELETE | IN_DELETE_SELF; break;
+		case 'p': pflag++; break;
 		default:
                         fprintf(stderr, "Usage: %s [-0d] [PATH...]\n", argv0);
                         exit(2);
@@ -170,6 +174,12 @@ from_stdin:
 
 			if (tfind(name, &root, order) ||
 			    tfind(dir, &root, order)) {
+				if (pflag) {
+					int n;
+					ioctl(1, FIONREAD, &n);
+					if (n > 0)
+						break;
+				}
 				printf("%s%s%c",
 				    (ev->mask & IN_DELETE ? "- " : ""),
 				    name,