about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-02-06 20:03:13 +0100
committerChristian Neukirchen <chneukirchen@gmail.com>2016-02-06 20:03:13 +0100
commit86fa5ec3d5bd08d5ea5282aafb8a1d02917a088b (patch)
tree32022429559c150420b088582bc46ebec1560b63
parentd0cc05244f2cf598f98dbaf42c2461be9763b0a4 (diff)
downloadxe-86fa5ec3d5bd08d5ea5282aafb8a1d02917a088b.tar.gz
xe-86fa5ec3d5bd08d5ea5282aafb8a1d02917a088b.tar.xz
xe-86fa5ec3d5bd08d5ea5282aafb8a1d02917a088b.zip
drop -k and make it default, add -F to exit on errors immediately
-rw-r--r--README.md4
-rwxr-xr-xtests7
-rw-r--r--xe.18
-rw-r--r--xe.c19
4 files changed, 23 insertions, 15 deletions
diff --git a/README.md b/README.md
index 0c7d1ee..1f5c352 100644
--- a/README.md
+++ b/README.md
@@ -22,14 +22,14 @@ Over apply:
 
 ## Usage:
 
-	xe [-0Rknv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...
+	xe [-0FRnv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...
 	   | -s SHELLSCRIPT
 	   | -a COMMAND... -- ARGS...
 	   | -A ARGSEP COMMAND... ARGSEP ARGS...
 
 * `-0`: input filenames are seperated by NUL bytes (default: newlines).
+* `-F`: fatal: stop after first failing command.
 * `-R`: return with status 122 when no arguments have been passed.
-* `-k`: keep going: don't stop when a command failed to execute.
 * `-n`: don't run the commands, just print them.
 * `-v`: print commands to standard error before running them.
 * `-I`: replace occurences of *arg* with the argument(s) (default: `{}`).
diff --git a/tests b/tests
index 51a47a4..b02b638 100755
--- a/tests
+++ b/tests
@@ -204,14 +204,15 @@ check_output 'exit code on empty input when run with -R' 'true | $XE -R echo a |
 122
 EOF
 
-check_output 'stops on first error' 'necho a b c | $XE -s "if [ b = \$1 ]; then false; else echo \$1; fi" || echo $?' <<EOF
+check_output 'doesn'\''t stop on errors by default' 'necho a b c | $XE -s "if [ b = \$1 ]; then false; else echo \$1; fi" || echo $?' <<EOF
 a
+c
 123
 EOF
 
-check_output 'doesn'\''t stop on errors with -k' 'necho a b c | $XE -k -s "if [ b = \$1 ]; then false; else echo \$1; fi"' <<EOF
+check_output 'stops on first error with -F' 'necho a b c | $XE -F -s "if [ b = \$1 ]; then false; else echo \$1; fi" 2>/dev/null || echo $?' <<EOF
 a
-c
+123
 EOF
 
 printf '# limit checks, expecting maximal POSIX limits available\n'
diff --git a/xe.1 b/xe.1
index 8c232d6..81e3698 100644
--- a/xe.1
+++ b/xe.1
@@ -6,7 +6,7 @@
 .Nd run command for each line or argument
 .Sh SYNOPSIS
 .Nm
-.Op Fl 0Rknv
+.Op Fl 0FRnv
 .Op Fl I Ar arg
 .Op Fl N Ar maxargs
 .Op Fl j Ar maxjobs
@@ -69,11 +69,11 @@ The options are as follows:
 .It Fl 0
 Input filenames are seperated by NUL bytes (instead of newlines, which
 is the default)
+.It Fl F
+Fatal:
+stop and exit when a command execution failed.
 .It Fl R
 Return with status 122 when no arguments have been passed.
-.It Fl k
-Keep going:
-Don't stop when a command failed to execute.
 .It Fl n
 Dry run: don't run the commands, just print them.
 .It Fl v
diff --git a/xe.c b/xe.c
index cab012e..77acdd7 100644
--- a/xe.c
+++ b/xe.c
@@ -28,7 +28,8 @@ static char *sflag;
 static int maxatonce = 1;
 static int maxjobs = 1;
 static int runjobs = 0;
-static int Rflag, Aflag, aflag, kflag, nflag, vflag;
+static int failed = 0;
+static int Aflag, Fflag, Rflag, aflag, nflag, vflag;
 static long iterations = 0;
 static FILE *traceout;
 
@@ -84,9 +85,13 @@ mywait()
 		// no other error possible?
 	}	
 	
-	if (WIFEXITED(status) && !kflag) {
+	if (WIFEXITED(status)) {
 		if (WEXITSTATUS(status) >= 1 && WEXITSTATUS(status) <= 125) {
-			exit(123);
+			if (Fflag) {
+				fprintf(stderr, "xe: pid %d exited with status %d\n", pid, WEXITSTATUS(status));
+				exit(123);
+			}
+			failed = 1;
 		} else if (WEXITSTATUS(status) == 255) {
 			fprintf(stderr, "xe: pid %d exited with status 255\n", pid);
 			exit(124);
@@ -275,22 +280,22 @@ main(int argc, char *argv[], char *envp[])
 
 	traceout = stdout;
 
-	while ((c = getopt(argc, argv, "+0A:I:N:Raj:kns:v")) != -1)
+	while ((c = getopt(argc, argv, "+0A:FI:N:Raj:ns:v")) != -1)
 		switch(c) {
 		case '0': delim = '\0'; break;
 		case 'A': argsep = optarg; Aflag++; break;
 		case 'I': replace = optarg; break;
 		case 'N': maxatonce = atoi(optarg); break;
+		case 'F': Fflag++; break;
 		case 'R': Rflag++; break;
 		case 'a': aflag++; break;
 		case 'j': maxjobs = parse_jobs(optarg); break;
-		case 'k': kflag++; break;
 		case 'n': nflag++; break;
 		case 's': sflag = optarg; break;
 		case 'v': vflag++; traceout = stderr; break;
 		default:
 			fprintf(stderr, 
-			    "Usage: %s [-0Rknv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...\n"
+			    "Usage: %s [-0FRnv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...\n"
 			    "     | -s SHELLSCRIPT\n"
 			    "     | -a COMMAND... -- ARGS...\n"
 			    "     | -A ARGSEP COMMAND... ARGSEP ARGS...\n",
@@ -376,5 +381,7 @@ main(int argc, char *argv[], char *envp[])
 
 	if (Rflag && iterations == 0)
 		return 122;
+	if (failed)
+		return 123;
 	return 0;
 }