1
0

psrelay(1)

This commit is contained in:
dtb 2024-01-13 10:22:53 -07:00
parent eb1f7c3473
commit 928fef0786
3 changed files with 100 additions and 0 deletions

3
psrelay/Makefile Normal file
View File

@ -0,0 +1,3 @@
CFLAGS += -I../libpsargs
psrelay: psrelay.o ../libpsargs/libpsargs.o

42
psrelay/psrelay.1 Normal file
View File

@ -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 <file | xargs test 4 = ] [ cat ]" will
redirect the contents of "file" into "psrelay [ wc -c" and pipe that output to
"xargs test 4 = ] [ cat ]".
.SH COPYRIGHT
Public domain.

55
psrelay/psrelay.c Normal file
View File

@ -0,0 +1,55 @@
#include <errno.h> /* errno */
#include <stdio.h> /* fprintf(3) */
#include <string.h> /* strerror(3) */
#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE
# include <sysexits.h>
#endif
#include <unistd.h> /* fork(2) */
#include <sys/types.h> /* <sys/wait.h> */
#include <sys/wait.h> /* 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 ? "<no argv[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 */
}