From 752a84ae61dd1c37dec9a1cb0d30e8c27db1994a Mon Sep 17 00:00:00 2001 From: Javier Merino Date: Thu, 20 Mar 2008 13:03:26 +0100 Subject: [PATCH] Moreutils: Added ifne Hi, I read the suggestion about ifne in the Discussion page of moreutils and found it interesting. It's a command that runs another process if the standard input is not empty. I think it can be very useful in admin scripts so I've implemented it. I attach a patch against the current head of moreutils' git. You may include it in moreutils if you think it's worth it. I've considered making an "ifempty" or "ifne -v" that would run a command if the standard input is empty, but I'm not sure if that could be useful. Any comments will be appreciated. Regards, Javi --- Makefile | 7 +++- README | 2 + debian/control | 1 + ifne.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ ifne.docbook | 68 ++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 ifne.c create mode 100644 ifne.docbook diff --git a/Makefile b/Makefile index a15226e..f5142db 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -BINS=isutf8 ifdata pee sponge mispipe lckdo +BINS=isutf8 ifdata ifne pee sponge mispipe lckdo PERLSCRIPTS=vidir vipe ts combine zrun -MANS=sponge.1 vidir.1 vipe.1 isutf8.1 ts.1 combine.1 ifdata.1 pee.1 zrun.1 mispipe.1 lckdo.1 +MANS=sponge.1 vidir.1 vipe.1 isutf8.1 ts.1 combine.1 ifdata.1 ifne.1 pee.1 zrun.1 mispipe.1 lckdo.1 CFLAGS=-O2 -g -Wall INSTALL_BIN=install -s @@ -26,6 +26,9 @@ isutf8.1: isutf8.docbook ifdata.1: ifdata.docbook docbook2x-man $< +ifne.1: ifne.docbook + docbook2x-man $< + pee.1: pee.docbook docbook2x-man $< diff --git a/README b/README index 702bb0d..ccc257c 100644 --- a/README +++ b/README @@ -7,6 +7,8 @@ ifdata get network interface info without parsing ifconfig output isutf8 check if a file or standard input is utf-8 +ifne + run a command if the standard input is not empty lckdo execute a program with a lock held mispipe diff --git a/debian/control b/debian/control index f69a5ee..5db3b33 100644 --- a/debian/control +++ b/debian/control @@ -20,6 +20,7 @@ Description: additional unix utilities So far, it includes the following utilities: - sponge: soak up standard input and write to a file - ifdata: get network interface info without parsing ifconfig output + - ifne: run a program if the standard input is not empty - vidir: edit a directory in your text editor - vipe: insert a text editor into a pipe - ts: timestamp standard input diff --git a/ifne.c b/ifne.c new file mode 100644 index 0000000..9af19fa --- /dev/null +++ b/ifne.c @@ -0,0 +1,99 @@ + +/* + * + * Copyright 2008 Javier Merino + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + ssize_t r; + int fds[2]; + int child_status; + pid_t child_pid; + char buf[BUFSIZ]; + + if (argc < 2) { + /* Noop */ + return EXIT_SUCCESS; + } + + r = read(0, buf, BUFSIZ*sizeof(char)); + + if (r == 0) + return EXIT_SUCCESS; + else if (r == -1) { + perror("read"); + return EXIT_FAILURE; + } + + if (pipe(fds)) { + perror("pipe"); + return EXIT_FAILURE; + } + + child_pid = fork(); + if (!child_pid) { + /* child process: rebind stdin and exec the subcommand */ + close(fds[1]); + if (dup2(fds[0], 0)) { + perror("dup2"); + return EXIT_FAILURE; + } + + execvp(argv[1], &argv[1]); + perror(argv[1]); + close(fds[0]); + return EXIT_FAILURE; + } else if (child_pid == -1) { + perror("fork"); + return EXIT_FAILURE; + } + + /* Parent: write in fds[1] our stdin */ + close(fds[0]); + + do { + if (write(fds[1], buf, r*sizeof(char)) == -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); + } + + close(fds[1]); + if (waitpid(child_pid, &child_status, 0) != child_pid) { + perror("waitpid"); + return EXIT_FAILURE; + } + if (WIFEXITED(child_status)) { + return (WEXITSTATUS(child_status)); + } else if (WIFSIGNALED(child_status)) { + raise(WTERMSIG(child_status)); + return EXIT_FAILURE; + } + + return EXIT_FAILURE; +} diff --git a/ifne.docbook b/ifne.docbook new file mode 100644 index 0000000..92c7f48 --- /dev/null +++ b/ifne.docbook @@ -0,0 +1,68 @@ + + + + + + + + +
+ cibervicho@gmail.com +
+ + Javier + Merino + + 2008-03-19 +
+ + + ifne + 1 + + + + ifne + Run command if the standard input is not empty + + + + + ifne command + + + + + DESCRIPTION + + ifne runs the following command if and only if + the standard input is not empty. + + + + EXAMPLE + + find . -name core | ifne mail -s "Core files found" root + + +
-- 2.39.5