From e1fe79a9e705e3cab8f632cdbe8e1774cdef2761 Mon Sep 17 00:00:00 2001
From: Laurent Bercot
Date: Thu, 19 Feb 2015 04:13:20 +0000
Subject: - exit code overhaul: forx, forbacktickx, loopwhilex, if, ifelse,
ifte, ifthenelse - new -o option to forx, forbacktickx, loopwhilex -
documentation updated - version: rc for 2.1.0.0
---
doc/exitcodes.html | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++
doc/forbacktickx.html | 18 ++++++----
doc/foreground.html | 9 ++++-
doc/forx.html | 16 ++++++---
doc/if.html | 4 +--
doc/ifelse.html | 3 +-
doc/ifte.html | 3 +-
doc/ifthenelse.html | 3 +-
doc/index.html | 4 +--
doc/loopwhilex.html | 25 ++++++++-----
doc/upgrade.html | 12 +++++++
11 files changed, 166 insertions(+), 28 deletions(-)
create mode 100644 doc/exitcodes.html
(limited to 'doc')
diff --git a/doc/exitcodes.html b/doc/exitcodes.html
new file mode 100644
index 0000000..4b8afda
--- /dev/null
+++ b/doc/exitcodes.html
@@ -0,0 +1,97 @@
+
+
+
+
+ execline: exit codes
+
+
+
+
+
+
+
+execline
+Software
+skarnet.org
+
+
+ How to propagate exit codes up a process dynasty
+
+
+ Say we have a parent process P, child of a grandparent process
+G, spawning a child process C and waiting for it.
+Either C dies normally with an exit code from 0 to 255, or it is
+killed by a signal.
+ How can we make sure that P reports to G what happened
+to C, with as much precision as possible ?
+
+
+
+ The problem is, there's more information in a wstat (the
+structure filled in by
+waitpid())
+than a process can report by
+simply exiting. P could exit with the same exit code as C,
+but then what should it do if C has been killed by a signal ?
+
+
+
+ An idea is to have P kill itself with the same signal that killed
+C.
+But that's actually not right, because P itself could be killed by a
+signal from another source, and G needs that information. "P has been
+killed by a signal" and "C has been killed by a signal" are two
+different informations, so they should not be reported in the same way.
+
+
+
+ So, any way you look at it, there is always more information than we
+can report.
+
+
+
+Shells have their own
+convention
+for reporting crashes, but since any exit code greater than 127 is reported
+as is, the information given by the shell is unreliable: "child exited 129"
+and "child was killed by SIGHUP" are indistinguishable. When shells get
+nested, all bets are off - the information conveyed by exit codes becomes
+devoid of meaning pretty fast. We need something better.
+
+
+ execline's solution
+
+
+execline commands such as forx, that can report
+a child's exit code, proceed that way when they're in the position of
+P:
+
+
+
+ - If C was killed by a signal: P exits 128 plus the
+signal number.
+ - If C exited 128 or more: P exits 128.
+ - Else, P exits with the same code as C.
+
+
+
+ Rationale:
+
+
+
+ - 128+ exit codes are extremely rare and should report really
+problematic conditions; commands usually exit 127 or less. If C
+exits 128+, it's more important to convey the information
+"something really bad happened, but the C process itself was not
+killed by a signal" than the exact nature of the event.
+ - Commands following that convention can be nested. If P exits
+129+, G knows that C was
+killed by a signal. If G also needs to report that to its parent,
+it will exit 128: G's parent will not know the signal number, but
+it will know that P reported 128 or more, so either C or
+a scion of C had problems.
+ - Exact information is reported in the common case.
+
+
+
+
diff --git a/doc/forbacktickx.html b/doc/forbacktickx.html
index d40799a..0780f3d 100644
--- a/doc/forbacktickx.html
+++ b/doc/forbacktickx.html
@@ -29,7 +29,7 @@ run another program.
- forbacktickx [ -p | -x breakcode ] [ -n ] [ -C | -c ] [ -0 | -d delim ] variable { gen... } loop...
+ forbacktickx [ -p | -o okcodes | -x breakcodes ] [ -n ] [ -C | -c ] [ -0 | -d delim ] variable { gen... } loop...
@@ -56,11 +56,17 @@ exiting, though.
- -0 : accept null characters from gen's output,
using them as delimiters. If this option and a -d option are
used simultaneously, the rightmost one wins.
- - -x breakcodes : breakcodes must
-be a comma-separated list of exit codes. If at some point loop...
-exits with a code listed in breakcodes, forbacktickx will not keep
-looping, but will exit immediately with the same exit code. This doesn't apply
-if the -p option has been given.
+ - -o okcodes : okcodes must
+be a comma-separated list of exit codes. If the -p flag
+hasn't been given and loop exits with one of the codes in
+okcodes,
+forbacktickx will run the following instances of the loop, but if the exit code is
+not listed in okcodes, forbacktickx will exit immediately with an
+approximation of the same exit code.
+ - -x breakcodes : like the previous
+option, but with inverted meaning - the listed exit codes are codes
+that will make forbacktickx break the loop and exit, and the unlisted exit
+codes will make it keep looping.
- Other options are used to control
the substitution mechanism for every x. Of course, you can't
split x.
diff --git a/doc/foreground.html b/doc/foreground.html
index a2a465f..c0928e9 100644
--- a/doc/foreground.html
+++ b/doc/foreground.html
@@ -37,7 +37,8 @@
executes it, then waits for it to complete.
- foreground sets the ? environment
variable to the exit code of prog1. If prog1...
-did not exit normally, the ? value is 111.
+was killed by a signal, the ? value is 256 plus the signal
+number.
- foreground then execs into prog2....
@@ -51,6 +52,12 @@ wrap external commands that exit instead of natively supporting the
foreground prog1... "" prog2... is
equivalent to sh -c 'prog1... ; exec prog2...'.
+ 256 and above are not valid exit codes for commands, so when the
+? environment variable contains 256 or more, it means that the
+previous command was killed by a signal. There is no ambiguity here, and
+? reports exactly what happened to the previous command;
+foreground does not exit, so there is no need for
+exit code approximation.