]> err.no Git - moreutils/commitdiff
Added -n option to ifne.
authorVicho <cibervicho@gmail.com>
Thu, 1 May 2008 10:17:45 +0000 (12:17 +0200)
committerJoey Hess <joey@kodama.kitenet.net>
Mon, 12 May 2008 20:00:31 +0000 (16:00 -0400)
With -n, ifne runs the command if the standard input is empty and does
nothing otherwise.

ifne.c
ifne.docbook

diff --git a/ifne.c b/ifne.c
index 817b1c510c92e581233bc19dc3c920b6c2c17181..a7abd21f18fae0d856226e8259c64165008876c7 100644 (file)
--- a/ifne.c
+++ b/ifne.c
 #include <unistd.h>
 #include <sys/wait.h>
 #include <sys/types.h>
+#include <string.h>
+#define streq(a, b) (!strcmp((a), (b)))
+
+static void stdin_to_stream(char *buf, ssize_t r, FILE *outf) {
+       while (r > 0) {
+               if (fwrite(buf, r*sizeof(char), 1, outf) < 1) {
+                       fprintf(stderr, "Write error\n");
+                       exit(EXIT_FAILURE);
+               }
+               r = read(0, buf, BUFSIZ*sizeof(char));
+       }
+       if (r == -1) {
+               perror("read");
+               exit(EXIT_FAILURE);
+       }
+}
 
 int main(int argc, char **argv) {
        ssize_t r;
+       int run_if_empty;
+       char **argv_exec;
        int fds[2];
        int child_status;
        pid_t child_pid;
        char buf[BUFSIZ];
        FILE *outf;
 
-       if (argc < 2) {
+       if ((argc < 2) || ((argc == 2) && streq(argv[1], "-n"))) {
                /* Noop */
                return EXIT_SUCCESS;
        }
 
+       if (streq(argv[1], "-n")) {
+               run_if_empty = 1;
+               argv_exec = &argv[2];
+       } else {
+               run_if_empty = 0;
+               argv_exec = &argv[1];
+       }
+
        r = read(0, buf, BUFSIZ*sizeof(char));
 
-       if (r == 0)
+       if ((r == 0) && !run_if_empty)
                return EXIT_SUCCESS;
        else if (r == -1) {
                perror("read");
@@ -50,6 +76,13 @@ int main(int argc, char **argv) {
                return EXIT_FAILURE;
        }
 
+       if (r && run_if_empty) {
+               /* don't run the subcommand if we read something from stdin and -n was set */
+               /* But write stdin to stdout so ifne -n can be piped without sucking the stream */
+               stdin_to_stream(buf, r, stdout);
+               return EXIT_SUCCESS;
+       }
+
        child_pid = fork();
        if (!child_pid) {
                /* child process: rebind stdin and exec the subcommand */
@@ -57,10 +90,10 @@ int main(int argc, char **argv) {
                if (dup2(fds[0], 0)) {
                        perror("dup2");
                        return EXIT_FAILURE;
-                }
+               }
 
-               execvp(argv[1], &argv[1]);
-               perror(argv[1]);
+               execvp(*argv_exec, argv_exec);
+               perror(*argv_exec);
                close(fds[0]);
                return EXIT_FAILURE;
        } else if (child_pid == -1) {
@@ -75,17 +108,8 @@ int main(int argc, char **argv) {
                perror("fdopen");
                exit(1);
        }
-       do {
-               if (fwrite(buf, r*sizeof(char), 1, outf) < 1) {
-                       fprintf(stderr, "Write error to %s\n", argv[1]);
-                       exit(EXIT_FAILURE);
-               }
-               r = read(0, buf, BUFSIZ*sizeof(char));
-       } while (r > 0);
-       if (r == -1) {
-               perror("read");
-               exit(EXIT_FAILURE);
-       }
+
+       stdin_to_stream(buf, r, outf);
        fclose(outf);
 
        if (waitpid(child_pid, &child_status, 0) != child_pid) {
index 92c7f4835d7c28a65c173273ec734b53fe3fdb41..38e38897c780935e426eb3d1bc1ddb0479aae3a3 100644 (file)
@@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                        <firstname>Javier</firstname>
                        <surname>Merino</surname>
                </author>
-               <date>2008-03-19</date>
+               <date>2008-05-01</date>
        </refentryinfo>
 
        <refmeta>
@@ -48,21 +48,42 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
        <refsynopsisdiv>
                <cmdsynopsis>
-                       <command>ifne command</command>
+                       <command>ifne [-n] command</command>
                </cmdsynopsis>
        </refsynopsisdiv>
        
        <refsect1>
                <title>DESCRIPTION</title>
                
-                <para><command>ifne</command> runs the following command if and only if
-                the standard input is not empty.</para>
+               <para><command>ifne</command> runs the following command if and only if
+                       the standard input is not empty.</para>
        </refsect1>
        
+       <refsect1>
+               <title>OPTIONS</title>
+
+               <variablelist>
+                       <varlistentry>
+                               <term><option>-n</option></term>
+                               <listitem>
+                                       <para>Reverse operation. Run the command if the standard input is empty.</para>
+                               </listitem>
+                       </varlistentry>
+               </variablelist>
+       </refsect1>
+
        <refsect1>
                <title>EXAMPLE</title>
                <cmdsynopsis>
                        <command>find . -name core | ifne mail -s "Core files found" root</command>
                </cmdsynopsis>
        </refsect1>
+
+       <refsect1>
+               <title>AUTHOR</title>
+
+               <para>Copyright 2008 by Javier Merino &lt;cibervicho@gmail.com&gt;</para>
+               <para>Licensed under the GNU GPL</para>
+       </refsect1>
+
 </refentry>