diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/exitcodes.html | 97 | ||||
-rw-r--r-- | doc/forbacktickx.html | 18 | ||||
-rw-r--r-- | doc/foreground.html | 9 | ||||
-rw-r--r-- | doc/forx.html | 16 | ||||
-rw-r--r-- | doc/if.html | 4 | ||||
-rw-r--r-- | doc/ifelse.html | 3 | ||||
-rw-r--r-- | doc/ifte.html | 3 | ||||
-rw-r--r-- | doc/ifthenelse.html | 3 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | doc/loopwhilex.html | 25 | ||||
-rw-r--r-- | doc/upgrade.html | 12 |
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 ? +</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 ? +</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> : 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> <em>breakcodes</em> : <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> <em>okcodes</em> : <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> <em>breakcodes</em> : 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> <em>breakcodes</em> : <em>breakcodes</em> must + <li> <tt>-o</tt> <em>okcodes</em> : <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> <em>breakcodes</em> : 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> <em>exitcodes</em> : <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> : 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> <em>okcodes</em> : <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> <em>breakcodes</em> : 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> : 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> |