From 4425bfd45edfc4d2be18ce6d2a2eeb7ab80f7a6c Mon Sep 17 00:00:00 2001 From: Vicho Date: Thu, 1 May 2008 12:17:45 +0200 Subject: [PATCH] Added -n option to ifne. With -n, ifne runs the command if the standard input is empty and does nothing otherwise. --- ifne.c | 56 +++++++++++++++++++++++++++++++++++++--------------- ifne.docbook | 29 +++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/ifne.c b/ifne.c index 817b1c5..a7abd21 100644 --- a/ifne.c +++ b/ifne.c @@ -22,23 +22,49 @@ #include #include #include +#include +#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) { diff --git a/ifne.docbook b/ifne.docbook index 92c7f48..38e3889 100644 --- a/ifne.docbook +++ b/ifne.docbook @@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Javier Merino - 2008-03-19 + 2008-05-01 @@ -48,21 +48,42 @@ with this program; if not, write to the Free Software Foundation, Inc., - ifne command + ifne [-n] command DESCRIPTION - ifne runs the following command if and only if - the standard input is not empty. + ifne runs the following command if and only if + the standard input is not empty. + + OPTIONS + + + + + + Reverse operation. Run the command if the standard input is empty. + + + + + EXAMPLE find . -name core | ifne mail -s "Core files found" root + + + AUTHOR + + Copyright 2008 by Javier Merino <cibervicho@gmail.com> + Licensed under the GNU GPL + + -- 2.39.5