summary refs log tree commit diff
path: root/doc
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-02-19 04:13:20 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-02-19 04:13:20 +0000
commite1fe79a9e705e3cab8f632cdbe8e1774cdef2761 (patch)
treefcf1e195e4025ca14b7caea13c0da41fca15ea97 /doc
parentc73a41da14650d93801a59b85757a73741be986f (diff)
downloadexecline-67bc135fbc3869bf42749fac612fd4f10a3fa361.tar.gz
execline-67bc135fbc3869bf42749fac612fd4f10a3fa361.tar.xz
execline-67bc135fbc3869bf42749fac612fd4f10a3fa361.zip
- exit code overhaul: forx, forbacktickx, loopwhilex, if, ifelse, ifte, v2.1.0.0
ifthenelse
 - new -o option to forx, forbacktickx, loopwhilex
 - documentation updated
 - version: rc for 2.1.0.0
Diffstat (limited to 'doc')
-rw-r--r--doc/exitcodes.html97
-rw-r--r--doc/forbacktickx.html18
-rw-r--r--doc/foreground.html9
-rw-r--r--doc/forx.html16
-rw-r--r--doc/if.html4
-rw-r--r--doc/ifelse.html3
-rw-r--r--doc/ifte.html3
-rw-r--r--doc/ifthenelse.html3
-rw-r--r--doc/index.html4
-rw-r--r--doc/loopwhilex.html25
-rw-r--r--doc/upgrade.html12
11 files changed, 166 insertions, 28 deletions
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 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: exit codes</title>
+    <meta name="Description" content="execline: exit codes" />
+    <meta name="Keywords" content="execline exit codes" />
+    <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">execline</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> How to propagate exit codes up a process dynasty </h1>
+
+<p>
+ Say we have a parent process <em>P</em>, child of a grandparent process
+<em>G</em>, spawning a child process <em>C</em> and waiting for it.
+Either <em>C</em> dies normally with an exit code from 0 to 255, or it is
+killed by a signal.
+ How can we make sure that <em>P</em> reports to <em>G</em> what happened
+to <em>C</em>, with as much precision as possible&nbsp;?
+</p>
+
+<p>
+ The problem is, there's more information in a wstat (the
+structure filled in by
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html">waitpid()</a>)
+than a process can report by
+simply exiting. <em>P</em> could exit with the same exit code as <em>C</em>,
+but then what should it do if C has been killed by a signal&nbsp;?
+</p>
+
+<p>
+ An idea is to have <em>P</em> kill itself with the same signal that killed
+<em>C</em>.
+But that's actually not right, because <em>P</em> itself could be killed by a
+signal from another source, and G needs that information. "<em>P</em> has been
+killed by a signal" and "<em>C</em> has been killed by a signal" are two
+different informations, so they should not be reported in the same way.
+</p>
+
+<p>
+ So, any way you look at it, there is always more information than we
+can report.
+</p>
+
+<p>
+Shells have their own
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02">convention</a>
+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.
+</p>
+
+<h2> execline's solution </h2>
+
+<p>
+execline commands such as <a href="forx.html">forx</a>, that can report
+a child's exit code, proceed that way when they're in the position of
+<em>P</em>:
+</p>
+
+<ul>
+ <li> If <em>C</em> was killed by a signal: <em>P</em> exits 128 plus the
+signal number. </li>
+ <li> If <em>C</em> exited 128 or more: <em>P</em> exits 128. </li>
+ <li> Else, <em>P</em> exits with the same code as <em>C</em>. </li>
+</ul>
+
+<p>
+ Rationale:
+</p>
+
+<ul>
+ <li> 128+ exit codes are extremely rare and should report really
+problematic conditions; commands usually exit 127 or less. If <em>C</em>
+exits 128+, it's more important to convey the information
+"something really bad happened, but the <em>C</em> process itself was not
+killed by a signal" than the exact nature of the event. </li>
+ <li> Commands following that convention can be nested. If <em>P</em> exits
+129+, <em>G</em> knows that <em>C</em> was
+killed by a signal. If <em>G</em> also needs to report that to its parent,
+it will exit 128: <em>G</em>'s parent will not know the signal number, but
+it will know that <em>P</em> reported 128 or more, so either <em>C</em> or
+a scion of <em>C</em> had problems. </li>
+ <li> Exact information is reported in the common case. </li>
+</ul>
+
+</body>
+</html>
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.
 </p>
 
 <pre>
-     forbacktickx [ -p | -x breakcode ] [ -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> { <em>gen...</em> } <em>loop...</em>
+     forbacktickx [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> { <em>gen...</em> } <em>loop...</em>
 </pre>
 
 <ul>
@@ -56,11 +56,17 @@ exiting, though. </li>
  <li> <tt>-0</tt>&nbsp;: accept null characters from <em>gen</em>'s output,
 using them as delimiters. If this option and a <tt>-d</tt> option are
 used simultaneously, the rightmost one wins. </li>
- <li> <tt>-x</tt>&nbsp;<em>breakcodes</em>&nbsp;: <em>breakcodes</em> must
-be a comma-separated list of exit codes. If at some point <em>loop...</em>
-exits with a code listed in <em>breakcodes</em>, forbacktickx will not keep
-looping, but will exit immediately with the same exit code. This doesn't apply
-if the <tt>-p</tt> option has been given. </li>
+ <li> <tt>-o</tt>&nbsp;<em>okcodes</em>&nbsp;: <em>okcodes</em> must
+be a comma-separated list of exit codes. If the <tt>-p</tt> flag
+hasn't been given and <em>loop</em> exits with one of the codes in
+<em>okcodes</em>,
+forbacktickx will run the following instances of the loop, but if the exit code is
+not listed in <em>okcodes</em>, forbacktickx will exit immediately with an
+<a href="exitcodes.html">approximation</a> of the same exit code. </li>
+ <li> <tt>-x</tt>&nbsp;<em>breakcodes</em>&nbsp;: 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. </li>
  <li> Other options are used to <a href="el_transform.html">control
 the substitution mechanism</a> for every <em>x</em>. Of course, you can't
 split <em>x</em>. </li>
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. </li>
  <li> <tt>foreground</tt> sets the <tt>?</tt> environment
 variable to the exit code of <em>prog1</em>. If <em>prog1...</em>
-did not exit normally, the <tt>?</tt> value is 111. </li>
+was killed by a signal, the <tt>?</tt> value is 256 plus the signal
+number. </li>
  <li> <tt>foreground</tt> then execs into <em>prog2...</em>. </li>
 </ul>
 
@@ -51,6 +52,12 @@ wrap external commands that exit instead of natively supporting the
  <li> <tt>foreground <em>prog1...</em> "" <em>prog2...</em></tt> is
 equivalent to <tt>sh -c '<em>prog1...</em> ; exec <em>prog2...</em>'</tt>.
  </li>
+ <li> 256 and above are not valid exit codes for commands, so when the
+<tt>?</tt> environment variable contains 256 or more, it means that the
+previous command was killed by a signal. There is no ambiguity here, and
+<tt>?</tt> reports exactly what happened to the previous command;
+<tt>foreground</tt> does not exit, so there is no need for
+<a href="exitcodes.html">exit code approximation</a>. </li>
 </ul>
 
 </body>
diff --git a/doc/forx.html b/doc/forx.html
index 0349a85..0ed4799 100644
--- a/doc/forx.html
+++ b/doc/forx.html
@@ -28,7 +28,7 @@
 </p>
 
 <pre>
-     forx [ -p | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em>
+     forx [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em>
 </pre>
 
 <ul>
@@ -48,11 +48,17 @@ That block contains a list of <em>args</em>. </li>
 <em>loop...</em> to exit before spawning the next one. <tt>forx</tt>
 will still wait for all instances of <em>loop</em> to terminate before
 exiting, though. </li>
- <li> <tt>-x</tt>&nbsp;<em>breakcodes</em>&nbsp;: <em>breakcodes</em> must
+ <li> <tt>-o</tt>&nbsp;<em>okcodes</em>&nbsp;: <em>okcodes</em> must
 be a comma-separated list of exit codes. If the <tt>-p</tt> flag
-hasn't been given and <em>loop</em> exits with one of the codes in <em>breakcodes</em>,
-forx will not run the following instances of the loop, but exit immediately with the
-same exit code. </li>
+hasn't been given and <em>loop</em> exits with one of the codes in
+<em>okcodes</em>,
+forx will run the following instances of the loop, but if the exit code is
+not listed in <em>okcodes</em>, forx will exit immediately with an
+<a href="exitcodes.html">approximation</a> of the same exit code. </li>
+ <li> <tt>-x</tt>&nbsp;<em>breakcodes</em>&nbsp;: like the previous
+option, but with inverted meaning - the listed exit codes are codes
+that will make forx break the loop and exit, and the unlisted exit
+codes will make it keep looping. </li>
 </ul>
 
 <h2> Notes </h2>
diff --git a/doc/if.html b/doc/if.html
index 2157a07..5723ef7 100644
--- a/doc/if.html
+++ b/doc/if.html
@@ -35,8 +35,8 @@
  <li> <tt>if</tt> reads <em>prog1...</em> in a
 <a href="el_semicolon.html">block</a>. It forks and executes it,
 then waits for it to complete. </li>
- <li> If <em>prog1</em> crashes, <tt>if</tt> exits 1 with a special
-error message. </li>
+ <li> If <em>prog1</em> crashes, <tt>if</tt> prints an error message
+then exits 128 plus the number of the signal that killed <em>prog1</em>. </li>
  <li> If <em>prog1</em> exits a non-zero status,
 <tt>if</tt> exits 1.</li>
  <li> Else <tt>if</tt> execs into <em>prog2</em>. </li>
diff --git a/doc/ifelse.html b/doc/ifelse.html
index 2298cf8..06d2e9c 100644
--- a/doc/ifelse.html
+++ b/doc/ifelse.html
@@ -34,7 +34,8 @@
  <li> <tt>ifelse</tt> reads <em>prog1...</em> in a
 <a href="el_semicolon.html">block</a>. It forks and executes it,
 then waits for it to complete. </li>
- <li> If <em>prog1</em> crashes, <tt>ifelse</tt> exits 1 with an error message. </li>
+ <li> If <em>prog1</em> crashes, <tt>ifelse</tt> prints an error message
+and exits 128 plus the number of the signal that killed <em>prog1</em>. </li>
  <li> If <em>prog1</em> exits with a return code equal to 0,
 <tt>ifelse</tt> execs into <em>prog2</em>. </li>
  <li> Else <tt>ifelse</tt> execs into <em>prog3</em>. </li>
diff --git a/doc/ifte.html b/doc/ifte.html
index 40b0ec9..9cbfdcc 100644
--- a/doc/ifte.html
+++ b/doc/ifte.html
@@ -37,7 +37,8 @@ consecutive <a href="el_semicolon.html">blocks</a>. </li>
  <li> <tt>ifte</tt> runs <em>progif...</em> as a child process
 and waits for it to complete. </li>
  <li> If <em>progif...</em> crashes (i.e. is killed by a signal), <tt>ifte</tt>
-exits 1 with an error message. </li>
+prints an error message, then exits 128 plus the number of the signal that
+killed <em>progif</em>. </li>
  <li> If <em>progif...</em> exits zero, <tt>ifte</tt> execs into
 <em>progthen...</em>, else it execs into <em>progelse...</em>. </li>
 </ul>
diff --git a/doc/ifthenelse.html b/doc/ifthenelse.html
index 3180412..97aec39 100644
--- a/doc/ifthenelse.html
+++ b/doc/ifthenelse.html
@@ -38,7 +38,8 @@ consecutive <a href="el_semicolon.html">blocks</a>. </li>
  <li> <tt>ifthenelse</tt> runs <em>progif...</em> as a child process
 and waits for it to complete. </li>
  <li> If <em>progif...</em> crashes (i.e. is killed by a signal), <tt>ifthenelse</tt>
-exits 1 with an error message. </li>
+prints an error message, then exits 128 plus the number of the signal
+that killed <em>progif</em>. </li>
  <li> If <em>progif...</em> exits zero, <tt>ifthenelse</tt> runs
 <em>progthen...</em> as a child process, else it runs <em>progelse...</em>. </li>
  <li> <tt>ifthenelse</tt> waits for its child to complete and puts the exit
diff --git a/doc/index.html b/doc/index.html
index 5fdfb46..5b19477 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -51,7 +51,7 @@ shell's syntax, and has no security issues.
  <li> GNU make, version 4.0 or later. Please be aware that execline will
 not build with an earlier version. </li>
  <li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version
-2.3.0.0 or later. It's a build-time requirement. It's also a run-time
+2.3.1.0 or later. It's a build-time requirement. It's also a run-time
 requirement if you link against the shared version of the skalibs
 library. </li>
 </ul>
@@ -66,7 +66,7 @@ library. </li>
 <h3> Download </h3>
 
 <ul>
- <li> The current released version of execline is <a href="execline-2.0.2.1.tar.gz">2.0.2.1</a>. </li>
+ <li> The current released version of execline is <a href="execline-2.1.0.0.tar.gz">2.1.0.0</a>. </li>
  <li> Alternatively, you can checkout a copy of the execline git repository:
 <pre> git clone git://git.skarnet.org/execline </pre> </li>
 </ul>
diff --git a/doc/loopwhilex.html b/doc/loopwhilex.html
index 91e9fb1..8c8d760 100644
--- a/doc/loopwhilex.html
+++ b/doc/loopwhilex.html
@@ -24,31 +24,38 @@
 <h2> Interface </h2>
 
 <pre>
-     loopwhilex [ -n ] [ -x <em>exitcodes</em> ] <em>prog...</em>
+     loopwhilex [ -n ] [ -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>prog...</em>
 </pre>
 
 <ul>
  <li> <tt>loopwhilex</tt> runs <em>prog...</em> as a child process and
 waits for it to complete. </li>
  <li> As long as <em>prog</em> exits zero, <tt>loopwhile</tt> runs it again. </li>
- <li> <tt>loopwhilex</tt> then exits 0. If <em>prog</em> was killed by a signal,
-<tt>loopwhilex</tt> exits that signal's number instead. </li>
+ <li> <tt>loopwhilex</tt> then exits with an
+<a href="exitcodes.html">approximation</a> of the last <em>prog</em>
+invocation's exit code. </li>
 </ul>
 
 <h2> Options </h2>
 
 <ul>
- <li> <tt>-x</tt>&nbsp;<em>exitcodes</em>&nbsp;: <em>exitcodes</em> must be a comma-separated
-list of valid exit codes. If this option is given, <tt>loopwhilex</tt> will run
-<em>prog...</em> as long as its exit code is <em>not</em> listed in <em>breakcodes</em>. </li>
- <li> <tt>-n</tt>&nbsp;: negate the test: run <em>prog...</em> as long as it exits non-zero
-(or exits a code that <em>is</em> listed in <em>breakcodes</em>). </li>
+ <li> <tt>-o</tt>&nbsp;<em>okcodes</em>&nbsp;: <em>okcodes</em> must
+be a comma-separated list of exit codes. <tt>loopwhilex</tt> will keep
+looping as long as <em>prog</em> exits with one of the codes in
+<em>okcodes</em>. </li>
+ <li> <tt>-x</tt>&nbsp;<em>breakcodes</em>&nbsp;: like the previous
+option, but with inverted meaning - the listed exit codes are codes
+that will break the loop and exit, and the unlisted exit codes will keep
+the loop running. </li>
+ <li> <tt>-n</tt>&nbsp;: negate the test. This option is now redundant,
+and may disappear soon. </li>
 </ul>
 
 <h2> Notes </h2>
 
 <ul>
- <li> <tt>loopwhilex <em>prog</em>...</tt> is equivalent to <tt>loopwhilex -n -x 0 <em>prog...</em></tt>. </li>
+ <li> <tt>loopwhilex <em>prog</em>...</tt> is equivalent to <tt>loopwhilex -n -x 0 <em>prog...</em></tt>
+and <tt>loopwhilex -o 0 <em>prog</em>...</tt> </li>
  <li> Be careful: execline <strong>maintains no state</strong>, in particular it
 uses <strong>no real variables</strong>, and environment will
 be of no use here since every instance of <em>prog...</em> runs as a separate
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 115ed5e..b66a215 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -17,6 +17,18 @@
 
 <h1> What has changed in execline </h1>
 
+<h2> in 2.1.0.0 </h2>
+
+<ul>
+ <li> skalibs dependency bumped to 2.3.1.0 </li>
+ <li> <a href="foreground.html">foreground</a> now sets the ? environment
+variable to 256 plus the signal number when its block was killed by a signal
+(in previous releases it used 126). </li>
+ <li> New rules for exit codes of forx, loopwhilex, forbacktickx </li>
+ <li> New <tt>-e</tt> option to <a href="loopwhilex.html">loopwhilex</a>,
+deprecating the <tt>-x</tt> option. </li>
+</ul>
+
 <h2> in 2.0.2.1 </h2>
 
 <ul>