From 928fef078672051b014f53dbdd07d70dd1149435 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 13 Jan 2024 10:22:53 -0700 Subject: [PATCH] psrelay(1) --- psrelay/Makefile | 3 +++ psrelay/psrelay.1 | 42 ++++++++++++++++++++++++++++++++++++ psrelay/psrelay.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 psrelay/Makefile create mode 100644 psrelay/psrelay.1 create mode 100644 psrelay/psrelay.c diff --git a/psrelay/Makefile b/psrelay/Makefile new file mode 100644 index 0000000..26ab94a --- /dev/null +++ b/psrelay/Makefile @@ -0,0 +1,3 @@ +CFLAGS += -I../libpsargs + +psrelay: psrelay.o ../libpsargs/libpsargs.o diff --git a/psrelay/psrelay.1 b/psrelay/psrelay.1 new file mode 100644 index 0000000..9fb8ef5 --- /dev/null +++ b/psrelay/psrelay.1 @@ -0,0 +1,42 @@ +.TH PSRELAY 1 + +.SH NAME + +psrelay \(en conditionally execute a process + +.SH SYNOPSIS + +psrelay +"[" +.RB [ command +.RB ( argument... )] +"]" +"[" +.RB [ command +.RB ( argument... )] +"]" + +.SH DESCRIPTION + +Psrelay runs the first given command and, if it exits successfully, runs the +second given command, exiting with the status of the second command. +.PP +Standard input given to psrelay is not directed to the first given command, +only to the second given command. + +.SH DIAGNOSTICS + +Psrelay will print an error message and exit with the appropriate status from +sysexits(3) in the event of improper invocation or operating system error. +Psrelay will exit with the status of the second given command if run without +error. + +.SH BUGS + +Unintuitively, "psrelay [ wc -c /* errno */ +#include /* fprintf(3) */ +#include /* strerror(3) */ +#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE +# include +#endif +#include /* fork(2) */ +#include /* */ +#include /* wait(2), WIFEXITED, WEXITSTATUS */ +#include "libpsargs.h" + +int oserr(char *argv0, char *s){ + + fprintf(stderr, "%s: %s\n", argv0, s); + + return EX_OSERR; +} + +int usage(char *s){ + + fprintf(stderr, + "Usage: %s \"[\" [command (arguments...)] \"]\"" + " \"[\" [command (arguments...)] \"]\"\n", + s); + + return EX_USAGE; +} + +int main(int argc, char *argv[]){ + int child; + char **corr; + char **curr; + int i; + int r; + + if(argc < 2 || check_arg(curr = &argv[1]) != 2) + return usage(argc == 0 ? "" : argv[0]); + + do{ + *(corr = corresponding_arg(curr++)) = NULL; + + if(i == 1 || (r = fork()) == 0) + execvp(*curr, curr); + if(i == 1 || r == -1 || r == 0) + return oserr(argv[0], strerror(errno)); + + wait(&child); + if(!WIFEXITED(child) || WEXITSTATUS(child) != 0) + return 1; + + curr = corr + 1; + }while(++i < 2); + /* UNREACHABLE */ + +}