summary refs log tree commit diff
path: root/doc
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2014-09-18 20:03:23 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2014-09-18 20:03:23 +0000
commitf316a2ed52195135a35e32d7096e876357c48c69 (patch)
tree5f4486b9a5a213a69e66ef574d6bc643a207981c /doc
downloadexecline-f316a2ed52195135a35e32d7096e876357c48c69.tar.gz
execline-f316a2ed52195135a35e32d7096e876357c48c69.tar.xz
execline-f316a2ed52195135a35e32d7096e876357c48c69.zip
initial commit: rc for execline-2.0.0.0
Diffstat (limited to 'doc')
-rw-r--r--doc/background.html57
-rw-r--r--doc/backtick.html66
-rw-r--r--doc/cd.html45
-rw-r--r--doc/componentsb.txt41
-rw-r--r--doc/define.html42
-rw-r--r--doc/dieshdiedie.html278
-rw-r--r--doc/dollarat.html86
-rw-r--r--doc/el_pushenv.html173
-rw-r--r--doc/el_semicolon.html124
-rw-r--r--doc/el_substitute.html309
-rw-r--r--doc/el_transform.html204
-rw-r--r--doc/elgetopt.html60
-rw-r--r--doc/elgetpositionals.html94
-rw-r--r--doc/elglob.html68
-rw-r--r--doc/emptyenv.html57
-rw-r--r--doc/exec.html50
-rw-r--r--doc/execline-shell.html53
-rw-r--r--doc/execline-startup.html59
-rw-r--r--doc/execlineb.html246
-rw-r--r--doc/exit.html44
-rw-r--r--doc/export.html43
-rw-r--r--doc/fdblock.html55
-rw-r--r--doc/fdclose.html44
-rw-r--r--doc/fdmove.html55
-rw-r--r--doc/fdreserve.html92
-rw-r--r--doc/forbacktickx.html77
-rw-r--r--doc/foreground.html57
-rw-r--r--doc/forx.html66
-rw-r--r--doc/getpid.html44
-rw-r--r--doc/grammar.html160
-rw-r--r--doc/heredoc.html56
-rw-r--r--doc/homeof.html37
-rw-r--r--doc/if.html68
-rw-r--r--doc/ifelse.html59
-rw-r--r--doc/ifte.html67
-rw-r--r--doc/ifthenelse.html59
-rw-r--r--doc/import.html37
-rw-r--r--doc/importas.html57
-rw-r--r--doc/index.html213
-rw-r--r--doc/loopwhilex.html60
-rw-r--r--doc/multidefine.html69
-rw-r--r--doc/multisubstitute.html121
-rw-r--r--doc/pipeline.html67
-rw-r--r--doc/piperw.html38
-rw-r--r--doc/quine-dam.txt110
-rw-r--r--doc/quine-jriou.txt28
-rw-r--r--doc/quine-prj-2.txt15
-rw-r--r--doc/quine-prj-3.txt13
-rw-r--r--doc/quine-prj.txt13
-rw-r--r--doc/redirfd.html100
-rw-r--r--doc/runblock.html75
-rw-r--r--doc/shift.html68
-rw-r--r--doc/tryexec.html67
-rw-r--r--doc/umask.html44
-rw-r--r--doc/unexport.html46
-rw-r--r--doc/upgrade.html35
-rw-r--r--doc/wait.html53
57 files changed, 4524 insertions, 0 deletions
diff --git a/doc/background.html b/doc/background.html
new file mode 100644
index 0000000..85d2589
--- /dev/null
+++ b/doc/background.html
@@ -0,0 +1,57 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the background command</title>
+ <meta name="Description" content="execline: the background command" />
+ <meta name="Keywords" content="execline command background" />
+ <!-- <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> The <tt>background</tt> program </h1>
+
+<tt>background</tt> launches a command in the background, then goes on
+with the execution flow.
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     background [ -d ] { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <li> <tt>background</tt> reads a <em>prog1...</em> command in a
+<a href="el_semicolon.html">block</a> and unquotes it. </li>
+ <li> It spawns a child executing <em>prog1...</em>. </li>
+ <li> It sets the <tt>!</tt> environment
+variable to the pid of the <em>prog1...</em> process. </li>
+ <li> It then execs into <em>prog2...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-d</tt>&nbsp;: doublefork. If the <tt>-d</tt> option is set,
+<em>prog1...</em> will run as a grandchild of <tt>background</tt>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>background <em>prog1...</em> "" <em>prog2...</em></tt> is
+equivalent to <tt>sh -c '<em>prog1...</em> & ; exec <em>prog2...</em>'</tt>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/backtick.html b/doc/backtick.html
new file mode 100644
index 0000000..7bdc037
--- /dev/null
+++ b/doc/backtick.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the backtick command</title>
+ <meta name="Description" content="execline: the backtick command" />
+ <meta name="Keywords" content="execline command backtick" />
+ <!-- <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> The <tt>backtick</tt> program </h1>
+
+<p>
+<tt>backtick</tt> runs a program and uses its output as the argument of
+another program.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     backtick [ -i ] [ -n ] <em>variable</em> { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <li> <tt>backtick</tt> reads <em>prog1...</em> in a
+<a href="el_semicolon.html">block</a> and unquotes it. </li>
+ <li> It runs <em>prog1...</em> as a child process and saves its
+output in memory. This output must not contain a null character. </li>
+ <li><tt>backtick</tt> execs into the modified <em>prog2...</em>, with
+<em>variable</em> added to the environment with <em>prog1...</em>'s
+output as a value. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-i</tt>&nbsp;: insist. If <em>prog1</em> exits non-zero,
+<tt>backtick</tt> exits with the same exit code (or 111 if <em>prog1</em>
+crashed for some reason). Without this option, <tt>backtick</tt> execs into
+<em>prog2...</em> no matter what <em>prog1</em> does, with the null word as
+<em>variable</em>'s value if <em>prog1</em> didn't write anything before
+dying. </li>
+ <li> <tt>-n</tt>&nbsp;: chomp an ending newline off <em>prog1...</em>'s
+output. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> You can start <em>prog2...</em> with "import <em>variable</em> unexport <em>variable</em>"
+to perform variable substitution. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/cd.html b/doc/cd.html
new file mode 100644
index 0000000..416dc42
--- /dev/null
+++ b/doc/cd.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the cd command</title>
+ <meta name="Description" content="execline: the cd command" />
+ <meta name="Keywords" content="execline command cd chdir" />
+ <!-- <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> The <tt>cd</tt> program </h1>
+
+<p>
+<tt>cd</tt> changes the current working directory to a
+given directory, then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     cd <em>dir</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>cd</tt> performs a
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html">chdir()</a>
+system call on <em>dir</em>, then execs into <em>prog...</em>.
+</p>
+
+<h2> Notes </h2>
+
+<p>
+<tt>cd</tt> is a standard shell builtin. Be careful if you want to
+use the <tt>cd</tt> command outside of an <tt>execline</tt> script.
+</p>
+
+</body>
+</html>
diff --git a/doc/componentsb.txt b/doc/componentsb.txt
new file mode 100644
index 0000000..a191f04
--- /dev/null
+++ b/doc/componentsb.txt
@@ -0,0 +1,41 @@
+#!/command/execlineb
+
+# This execlineb script will sleep for 1 second, then print some
+# silly things on the standard output.
+
+
+foreground     # an unquoted string, evaluated to: foreground
+{              # A single opening brace, not included in the argv
+  sleep 1      # Two unquoted strings, evaluated to " sleep" and " 1"
+               # (without the quotation marks).
+}              # A single closing brace, evaluated to the empty word
+
+"echo"     # this is a quoted string. It will evaluate to the word: echo
+
+foo\ bar\ zoinx  # This is one word, since the spaces are escaped
+"foo bar zoinx"  # This is exactly the same word, written another way
+
+ " # this is not a comment, since it is inside a quoted string
+# This is not a comment either \" # nor is this " # but this is one
+
+"\0x41\66\0103D\n"   # This is the string ABCD followed by a newline.
+                     # Be careful: the newline will be part of the word.
+
+ \n   # this is not a newline, but the single word: n
+
+$23   # This will NOT be replaced by anything with execline-1.y, unless
+      # substitution is explicitly asked for in the script.
+      # The dollar is no special character for the execline binary.
+
+baz"$1"qux  # This will evaluate to the word baz$1qux
+baz\$1qux   # Same here
+baz$1qux    # Same here in execline-1.y
+
+${PATH}   # This will NOT be replaced by execline ; use the import command
+          # if you need the $PATH value.
+
+'this is not a string'  # it will be parsed as five separate words
+
+"\
+"        # This will be parsed as the empty word. A (backslash, newline)
+         # sequence inside a quoted string is entirely removed.
diff --git a/doc/define.html b/doc/define.html
new file mode 100644
index 0000000..4d5e0f2
--- /dev/null
+++ b/doc/define.html
@@ -0,0 +1,42 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the define command</title>
+ <meta name="Description" content="execline: the define command" />
+ <meta name="Keywords" content="execline command define" />
+ <!-- <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> The <tt>define</tt> program </h1>
+
+<p>
+<tt>define</tt> replaces a literal with a value, then executes
+another program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     define [ -s ] [ -C | -c ] [ -n ] [ -d <em>delim</em> ] <em>variable</em> <em>value</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>define</tt> performs
+<a href="el_substitute.html">variable substitution</a> on
+<em>prog...</em>, using <em>variable</em> as key and
+<em>value</em> as value.
+<tt>define</tt>'s options are used to <a href="el_transform.html">control
+the substitution mechanism</a>. </li>
+ <li> <tt>define</tt> then execs into the modified <em>prog...</em>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/dieshdiedie.html b/doc/dieshdiedie.html
new file mode 100644
index 0000000..dc3c661
--- /dev/null
+++ b/doc/dieshdiedie.html
@@ -0,0 +1,278 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: why execline and not sh</title>
+    <meta name="Description" content="execline: why execline and not sh" />
+    <meta name="Keywords" content="execline sh shell script language" />
+    <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<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> Why not just use <tt>/bin/sh</tt>&nbsp;? </h1>
+
+
+<a name="security">
+<h2> Security </h2></a>
+
+<p>
+ One of the most frequent sources of security problems in programs
+is <em>parsing</em>. Parsing is a complex operation, and it is easy to
+make mistakes while designing and implementing a parser. (See
+<a href="http://cr.yp.to/qmail/guarantee.html">what Dan Bernstein says
+on the subject</a>, section 5.)
+</p>
+
+<p>
+ But shells parse all the time. Worse, the <em>essence</em>
+of the shell is parsing: the parser and the runner are intimately
+interleaved and cannot be clearly separated, thanks to the
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html">specification</a>.
+Even worse, the
+shell sometimes has to perform <em>double parsing</em>, for instance
+after parameter expansion. This can lead to atrocities like
+<pre>
+zork="foo ; echo bar"
+touch $zork
+</pre> not doing what you would like them to do, even in that simple
+case. (<a href="http://www.zsh.org/">zsh</a> has a sane behaviour by
+default, at the expense of explicitly breaking the spec.)
+</p>
+
+<p>
+<tt>execlineb</tt> parses the script only once: when
+reading it. The parser has been designed to be simple and systematic,
+to reduce the potential for bugs - which you just cannot do
+with a shell. After <tt>execlineb</tt> has split up the script into
+words, no other parsing phase will happen, unless the user explicitly
+requires it. Positional parameters, when
+used, are never split, even if they contain spaces or newlines, unless
+the user explicitly requires it. Users control exactly what
+is split, what is done, and how.
+</p>
+
+<a name="portability">
+<h2> Portability </h2></a>
+
+<p>
+ The shell language was designed to make scripts portable across various
+versions of Unix. But it is actually really hard to write a portable shell
+script. There are dozens of distinct
+<tt>sh</tt> flavours, not even counting the openly incompatible
+<tt>csh</tt> approach and its various <tt>tcsh</tt>-like followers.
+The <tt>ash</tt>, <tt>bash</tt>, <tt>ksh</tt> and <tt>zsh</tt> shells
+all exhibit a different behaviour, <em>even when they are
+run with the so-called compatibility mode</em>. From what I have
+seen on various experiments, only <tt>zsh</tt> is able to follow the
+specification to the letter, at the expense of being big and complex to
+configure. This is a source of endless problems for shell script writers,
+who <em>should</em> be able to assume that a script will run everywhere,
+but <em>cannot</em> in practice. Even a simple utility like <tt>test</tt>
+cannot be used safely with the normalized options, because most shells
+come with a builtin <tt>test</tt> that does <em>not</em> respect the
+specification to the letter. And let's not get started about <tt>echo</tt>,
+which has its own set of problems. Rich Felker has
+<a href="http://www.etalabs.net/sh_tricks.html">a page</a> listing tricks
+to use to write portable shell scripts. Writing a portable script should
+not be that hard.
+</p>
+
+<p>
+execline scripts are portable. There is no
+complex syntax with opportunity to have an undefined or nonportable
+behaviour. The execline package is portable across platforms:
+there is no reason for vendors or distributors to fork their own
+incompatible version.
+ Scripts will
+not break from one machine to another; if they do,
+it's not a "portability problem", it's a bug. You are then encouraged
+to find the program that is responsible for the different behaviour,
+and send a bug-report to the program author - including me, if the
+relevant program is part of the execline distribution.
+</p>
+
+<p>
+ A long-standing problem with Unix scripts is the shebang line, which
+requires an absolute path to the interpreter. Scripts are only portable
+as is if the interpreter can be found at the same absolute path on every
+system. With <tt>/bin/sh</tt>, it is <em>almost</em> the case (Solaris
+manages to get it wrong by having a non-POSIX shell as <tt>/bin/sh</tt>
+and requiring something like <tt>#!/usr/xpg4/bin/sh</tt> to get a POSIX
+shell to interpret your script). Other scripting languages are not so
+lucky: perl can be <tt>/bin/perl</tt>, <tt>/usr/bin/perl</tt>,
+<tt>/usr/local/bin/perl</tt> or something else entirely. For those cases,
+some people advocate the use of <tt>env</tt>: <tt>#!/usr/bin/env perl</tt>.
+But first, <tt>env</tt> can only find interpreters that can be found via the
+user's PATH environment variable, which defeats the purpose of having an
+absolute path in the shebang line in the first place; and second, this only
+displaces the problem: the <tt>env</tt> utility does not
+have a guaranteed absolute path. <tt>/usr/bin/env</tt> is the usual
+convention, but not a strong guarantee: it is valid for systems to have
+<tt>/bin/env</tt> instead, for instance.
+</p>
+
+<p>
+<tt>execline</tt> suffers from the same issues. <tt>#!/bin/execlineb</tt>&nbsp;?
+<tt>#!/usr/bin/execlineb</tt>&nbsp;? This is the only portability problem that
+you will find with execline, and it is common to every script language. 
+</p>
+
+<p>
+ The real solution to this portability problem is a convention that
+guarantees fixed absolute paths for executables, which the FHS does not do.
+The <a href="http://cr.yp.to/slashpackage.html">slashpackage</a> convention is
+such an initiative, and is well-designed; but as with every
+convention, it only works if everyone follows it, and unfortunately,
+slashpackage has not
+found many followers. Nevertheless, like every skarnet.org package, execline
+can be configured to follow the slashpackage convention.
+</p>
+
+<a name="simplicity">
+<h2> Simplicity </h2></a>
+
+<p>
+ I originally wanted a shell that could be used on an embedded system.
+Even the <tt>ash</tt> shell seemed big, so I thought of writing my
+own. Hence I had a look at the
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html">sh
+specification</a>... and ran away screaming.
+This specification
+is <em>insane</em>. It goes against every good programming
+practice; it seems to have been designed only to give headaches
+to wannabe <tt>sh</tt> implementors.
+</p>
+
+<p>
+ POSIX cannot really be blamed for that: it only normalizes existing, historical
+behaviour. One can argue whether it is a good idea to normalize atrocious
+behaviour for historical reasons, as is the case with the infamous
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html">gets</a>
+function, but this is the way it is.
+</p>
+
+<p>
+ The fact remains that modern shells have to be compatible with that historical
+nonsense and that makes them big and complex at best, or incompatible and ridden
+with bugs at worst.
+An OpenBSD developer said to me, when asked about the OpenBSD <tt>/bin/sh</tt>:
+"It works, but it's far from not being a nightmare".
+</p>
+
+<p>
+ Nobody should have
+nightmare-like software on their system. Unix is simple. Unix
+was designed to be simple. And if, as Dennis Ritchie said, "it takes a
+genius to understand the simplicity", that's because incompetent people
+took advantage of the huge Unix flexibility to write insanely crappy or
+complex software. System administrators can only do a decent job when
+they understand how the programs they run are supposed to work. People
+are slowly starting to grasp this (or are they&nbsp;? We finally managed
+to get rid of sendmail and BIND, but GNU/Linux users seem happy to
+welcome the era of D-Bus and systemd. Will we ever learn&nbsp;?) - but even
+<tt>sh</tt>, a seemingly simple and basic Unix program, is hard to
+understand when you lift the cover.
+</p>
+
+<p>
+ So I decided to forego sh entirely and take a new approach. So far it
+has been working.
+ The <a href="grammar.html">execline specification</a> is simple, and,
+as I hope to have shown, easy to implement without too many bugs or
+glitches.
+</p>
+
+<a name="performance">
+<h2> Performance </h2></a>
+
+<p>
+ Since it was made to run on an embedded system, <tt>execline</tt> was
+designed to be light in memory usage. And it is.
+</p>
+
+<ul>
+ <li> No overhead due to interactive support. </li>
+ <li> No overhead due to unneeded features. Since every command performs
+its task then executes another command, all occupied resources are instantly
+freed. By contrast, a shell stays in memory during the whole execution
+time. </li>
+ <li> Very limited use of the C library. Only the C interface to the
+kernel's system calls, and some very basic functions like <tt>malloc()</tt>,
+are used in the C library. In addition to avoiding the horrible interfaces
+like <tt>stdio</tt> and the legacy libc bugs, this approach makes it easy
+to statically compile execline - you will want to do that on an embedded
+system, or just to gain performance. </li>
+</ul>
+
+<p>
+ You can have hundreds of execline scripts running simultaneously on an
+embedded box. Not exactly possible with a shell.
+</p>
+
+<p>
+ For scripts than do not require many computations that a shell can do
+without calling external programs,
+ <tt>execline</tt> is <em>faster</em> than the shell.
+Unlike <tt>sh</tt>'s
+one, the <tt>execline</tt> parser is simple and
+straightforward; actually, it's more of a lexer than a parser, because
+the execline language has been designed to be LL(1) - keep it simple,
+stupid.
+execline scripts get analysed and launched practically without a delay.
+</p>
+
+<a name="comparison" />
+<ul>
+ <li>
+ The best use case of execline is a linear, straightforward script, a
+simple command line that does not require the shell's processing power.
+In that case, execline will skip the shell's overhead and win big time
+on resource usage and execution speed. </li>
+ <li> For longer scripts that fork a few commands, with a bit of
+control flow, on average, an execline script will run at roughly the
+same speed as the equivalent shell script, while using less resources. </li>
+ <li> The worst use case of execline is when the shell is used as a
+programming language, and the script loops over complex internal constructs
+that execline is unable to replicate without forking. In that case,
+execline will waste a lot of time in fork/exec system calls that the
+shell does not have to perform, and be noticeably slower. execline has
+been designed as a <em>scripting</em> language, not as a <em>programming</em>
+language: it is efficient at being the glue that ties together programs
+doing a job, not at implementing a program's logic. </li>
+</ul>
+
+<a name="limitations">
+<h2> execline limitations </h2></a>
+
+<ul>
+ <li> <tt>execline</tt> can only handle scripts that fit in one <em>argv</em>.
+Unix systems have a limit on the <em>argv</em>+<em>envp</em> size;
+<tt>execline</tt> cannot execute scripts that are bigger than this limit.</li>
+ <li> <tt>execline</tt> commands do not perform signal handling. It is not
+possible to trap signals inside an execline script. If you want to trap
+signals, write a specific C program, or use a shell. </li>
+ <li> Due to the <tt>execline</tt> design, maintaining a state is
+difficult. Information has to transit via environment variables or
+temporary files, which makes commands like
+<a href="loopwhilex.html">loopwhilex</a> a bit painful to handle. </li>
+ <li> Despite all its problems, the main shell advantage (apart from
+being available on every Unix platform, that is) is that it
+is often <em>convenient</em>. Shell constructs can be terse and short,
+where <tt>execline</tt> constructs will be verbose and lengthy. </li>
+ <li> An execline script is generally heavier on <tt>execve()</tt> than
+the average shell script - notably in programs where the shell can
+use builtins. This can lead to a performance loss, especially when
+executed programs make numerous calls to the dynamic linker: the system
+ends up spending a lot of time resolving dynamic symbols. If it is a
+concern to you, you should try and <em>statically compile</em> the
+execline package, to eliminate the dynamic resolution costs. Unless
+you're heavily looping around <tt>execve()</tt>,
+the remaining costs will be negligible. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/dollarat.html b/doc/dollarat.html
new file mode 100644
index 0000000..2c09592
--- /dev/null
+++ b/doc/dollarat.html
@@ -0,0 +1,86 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the dollarat command</title>
+ <meta name="Description" content="execline: the dollarat command" />
+ <meta name="Keywords" content="execline command dollarat" />
+ <!-- <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> The <tt>dollarat</tt> program </h1>
+
+<p>
+<tt>dollarat</tt> prints the positional parameters of an execline script.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     dollarat [ -n ] [ -0 | -d <em>delimchar</em> ]
+</pre>
+
+<ul>
+ <li> <tt>dollarat</tt> reads the number <em>n</em> of "positional
+parameters" in the <tt>#</tt> environment variable. If that variable
+is not set or does not contain a valid <em>n</em>, <tt>dollarat</tt>
+exits 100. </li>
+ <li> <tt>dollarat</tt> prints the value of the <tt>1</tt> environment
+variable, then <em>delimchar</em>, then the value of the <tt>2</tt>
+environment variable... and so on until <tt><em>n</em></tt>. If one of
+these variables is not set, <tt>dollarat</tt> exits 100. </li>
+ <li> If everything runs OK, <tt>dollarat</tt> exits 0. This makes it
+one of the rare "exiting" execline commands. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-n</tt>&nbsp;: <em>chomp</em>. Do not print the last
+<em>delimchar</em>. </li>
+ <li> <tt>-d</tt>&nbsp;<em>delimchar</em>&nbsp;: use the character
+<em>delimchar</em> as separator between the arguments. Default: <tt>\n</tt>.
+If <em>delimchar</em> has more than one character, only the first one is
+used. If <em>delimchar</em> is the empty string, then <tt>dollarat</tt>
+will output the positional parameters as a
+<a href="el_transform.html#netstrings">sequence of netstrings</a> (and the
+<tt>-n</tt> option will be ignored). </li>
+ <li> <tt>-0</tt>&nbsp;: use the null character as separator. Any <tt>-d</tt>
+argument will be ignored. Warning: this option should only be used to feed
+data to programs that know how to handle null-separated lists. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> You can use <tt>dollarat&nbsp;-d&nbsp;""</tt> along with the
+<a href="forbacktickx.html">forbacktickx</a> command to reliably loop
+over the positional parameters:
+<pre>
+ #!/command/execlineb
+ forbacktickx -d "" ARG { dollarat -d "" }
+ dosomething $ARG
+</pre>
+
+ will call <tt>dosomething</tt> in turn on each argument to the script.
+That will work even if those arguments contain spaces, newlines,
+or other fancy characters. </li>
+
+ <li> Alternatively, instead of encoding data into a netstring, you can
+use a null-separated list, which will work the same way:
+<pre>
+ #!/command/execlineb
+ forbacktickx -0 ARG { dollarat -0 }
+ dosomething $ARG
+</pre> </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/el_pushenv.html b/doc/el_pushenv.html
new file mode 100644
index 0000000..2ae16dd
--- /dev/null
+++ b/doc/el_pushenv.html
@@ -0,0 +1,173 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: pushing and popping the environment</title>
+    <meta name="Description" content="execline: pushing and popping the environment" />
+    <meta name="Keywords" content="execline environment push pop el_pushenv el_popenv" />
+    <!-- <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> Pushing and popping the environment </h1>
+
+<p>
+ The <a href="execlineb.html">execlineb</a> launcher
+can store <em>positional
+parameters</em>, i.e. arguments given to your script, into the
+environment. The <tt>#</tt> variable contains the number of arguments;
+the <tt>0</tt> variable contains the name of your execline script;
+the <tt>1</tt> variable contains the first argument; and so on.
+</p>
+
+<p>
+ Up to execline-1.04, this could create problems with nested scripts:
+the inner script would overwrite the outer script's parameters, and
+there was no way to get them back. In particular, writing execline
+commands in the execline language via the
+<a href="runblock.html">runblock</a> command was impossible.
+</p>
+
+<a name="push" />
+
+<p>
+ To solve that issue, execline now implements a kind of <em>environment
+stack</em>. When execlineb reads the arguments, it does
+not overwrite the positional parameters, but <em>pushes</em> them on a
+stack:
+</p>
+
+<ul>
+ <li> <tt>#</tt> will be set to the current number of arguments </li>
+ <li> but if a variable named <tt>#</tt> existed before, it is renamed <tt>#:1</tt> </li>
+ <li> and if a variable named <tt>#:1</tt> also existed, it is renamed <tt>#:2</tt> </li>
+ <li> ... and so on until <tt>#:<em>n+1</em></tt> doesn't exist. </li>
+</ul>
+
+<p>
+ Same goes for the other <em>positional parameters</em>.
+</p>
+
+<p>
+ The script then runs; and commands such as
+<a href="elgetpositionals.html">elgetpositionals</a> use the current
+frame of positional parameters, without paying attention to the deeper
+levels.
+</p>
+
+<a name="pop" />
+
+<p>
+ When you are done with the arguments, it is advisable to <em>drop</em>
+the current frame, and <em>pop</em> the environment stack to get it back
+to its previous state:
+</p>
+
+<ul>
+ <li> <tt>#</tt> will be unset </li>
+ <li> but if <tt>#:1</tt> exists, it will be renamed <tt>#</tt> </li>
+ <li> and if <tt>#:2</tt> exists, it will be renamed <tt>#:1</tt> </li>
+ <li> ... and so on until <tt>#:<em>n+1</em></tt> doesn't exist. </li>
+</ul>
+
+<p>
+ Again, same goes for the other <em>positional parameters</em>. <br />
+The <a href="runblock.html">runblock</a> command will perform that
+<em>pop</em> operation automatically; the standard "manual" way to
+perform it is to use the <a href="emptyenv.html">emptyenv -P</a> command.
+</p>
+
+<h2> A pop example </h2>
+
+<p>
+ Suppose you want to run the long-lived program <em>prog</em> after
+printing the list of its arguments.
+</p>
+
+<pre>
+ #!/command/execlineb
+ elgetpositionals
+ foreground { echo $0 $@ }
+ prog $@
+</pre>
+
+<p>
+will work, but will pollute <em>prog</em>'s environment with a set of
+positional parameters that have no meaning to it. A better script is:
+</p>
+
+<pre>
+ #!/command/execlineb
+ elgetpositionals
+ foreground { echo $0 $@ }
+ emptyenv -P
+ prog $@
+</pre>
+
+<p>
+which will run <em>prog</em> with the same environment as the script's
+caller.
+</p>
+
+<a name="integrated" />
+
+<h2> Substituting positional parameters without touching the environment </h2>
+
+<p>
+ Most of the time, you just need to substitute the positional parameters
+in your execline script, and don't need to go through the whole
+<a href="elgetpositionals.html">elgetpositionals</a> and
+<a href="emptyenv.html">emptyenv</a> chain. execline comes with an
+integrated substitution mechanism, that does not touch the environment
+at all: the <tt>-S&nbsp;<em>n</em></tt> option.
+</p>
+
+<p>
+ Scripts beginning with:
+</p>
+
+<pre>
+#!/command/execlineb -S<em>n</em>
+<em>foobar...</em>
+</pre>
+
+<p>
+ are equivalent to:
+</p>
+
+<pre>
+#!/command/execlineb
+elgetpositionals -P<em>n</em>
+emptyenv -P
+<em>foobar...</em>
+</pre>
+
+<p>
+ So, to summarize, from most efficient (but less flexible) to least efficient
+(but more flexible):
+</p>
+
+<ul>
+ <li> Use <tt>execlineb -P</tt> if you don't need positional parameters
+at all; for instance, in
+<a href="http://skarnet.org/software/s6/">s6</a> or
+<a href="http://smarden.org/runit/">runit</a> <em>run scripts</em>. </li>
+ <li> Use <tt>execlineb -S<em>n</em></tt> if you need only simple
+positional parameter substitution in your script - no
+<a href="shift.html">shift</a> or <a href="elgetopt.html">elgetopt</a>,
+no <tt>import 1</tt>. </li>
+ <li> Use <tt>execlineb -p</tt>, then <tt>elgetpositionals</tt> if
+you don't mind overwriting the current stack of positional parameters. </li>
+ <li> Use <tt>execlineb</tt>, then <tt>elgetpositionals</tt>, then
+<tt>emptyenv -P</tt> if you need the full power of positional parameter
+handling. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/el_semicolon.html b/doc/el_semicolon.html
new file mode 100644
index 0000000..615b411
--- /dev/null
+++ b/doc/el_semicolon.html
@@ -0,0 +1,124 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta http-equiv="Content-Language" content="en" />
+<title>execline: block management</title>
+<meta name="Description" content="execline: block management" />
+<meta name="Keywords" content="execline block blocks null argument tilda semicolon el_semicolon" />
+<!-- <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> Blocks </h1>
+
+<p>
+A command line (and thus an execline script) is one-dimensional. But a
+Unix execution flow can be <em>two</em>-dimensional: when two
+instructions are sequenced, for instance. In that case, we need a
+way to extract <em>two</em> command lines from <em>one</em> argv.
+That is precisely what <em>blocks</em> are made for.
+</p>
+
+<p>
+ execline commands that need more than one linear set of arguments
+use blocks. For instance, the
+<a href="foreground.html">foreground</a> command needs to spawn a
+first process, then execute into a second one. It reads the command
+line for the first process from a block, and the command line for the
+second process from the rest of the argv. In the following script:
+</p>
+<pre>
+ #!/command/execlineb
+ foreground { echo 1 } echo 2
+</pre>
+<p>
+ <tt>echo&nbsp;1</tt> is read from a block and spawned; then
+<tt>echo&nbsp;2</tt> is executed.
+</p>
+
+<h2> execlineb syntax </h2>
+
+<p>
+ In <a href="execlineb.html">execlineb</a> scripts, blocks are
+delimited by braces. They can be nested.
+</p>
+
+<h2> argv syntax </h2>
+
+<p>
+ execlineb reads and parses the script, and converts it into an <em>argv</em>
+(a simple Unix command line) with a different syntax for blocks. 
+In an argv, blocks are not delimited by braces;
+they are made of <em>quoted arguments</em> and terminated by an
+empty word (""). A quoted argument begins with a space.
+ Nested blocks are represented by arguments being
+quoted several times, i.e. having several spaces in front of them;
+an empty word inside a block
+gets quoted too, i.e. it will be represented as a series of
+spaces.
+</p>
+
+<p>
+ Actually, the block-reading commands know nothing about braces;
+they only understand the "quoted arguments + empty word" syntax.
+So if you want to use <a href="foreground.html">foreground</a>
+from your shell to sequence <tt>echo&nbsp;1</tt> and
+<tt>echo&nbsp;2</tt>, you will have to write
+</p>
+
+<pre>
+ $ foreground ' echo' ' 1' '' echo 2
+</pre>
+
+<p>
+ You do not really need to quote every argument inside a block in
+that simple case. The following command works as well:
+</p>
+
+<pre>
+ $ foreground echo 1 '' echo 2
+</pre>
+
+<p>
+ However, this is bad practice, because it leads to a security hole:
+commands that perform
+<a href="el_substitute.html">substitution</a> inside a block may
+produce empty words, which may modify your script's execution flow.
+</p>
+
+<pre>
+ $ define FOO '' foreground ' echo' ' ${FOO}' ' rm' ' -rf' ' /' '' echo blah
+</pre>
+
+<p>
+ is safe, whereas
+</p>
+
+<pre>
+ $ define FOO '' foreground echo '${FOO}' rm -rf / '' echo blah
+</pre>
+
+<p>
+ has very much unwanted results. (Don't try this at home.)
+</p>
+
+<p>
+ You can use the <tt>EXECLINE_STRICT</tt> environment variable to
+check proper block quoting. If that variable contains <tt>1</tt>,
+commands that read blocks will print a warning message everytime
+they find an unquoted argument inside a block. If that variable
+contains <tt>2</tt> or a bigger integer, commands will print an
+error message and die on unquoted arguments.
+<br /> You can use <a href="execlineb.html">execlineb</a>'s
+<tt>-w</tt> or <tt>-W</tt>
+switch to set <tt>EXECLINE_STRICT</tt> to <tt>1</tt> or <tt>2</tt>.
+</p>
+
+</body>
+</html>
diff --git a/doc/el_substitute.html b/doc/el_substitute.html
new file mode 100644
index 0000000..4da03f5
--- /dev/null
+++ b/doc/el_substitute.html
@@ -0,0 +1,309 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: variable substitution</title>
+    <meta name="Description" content="execline: variable substitution" />
+    <meta name="Keywords" content="execline variable substitution el_substitute" />
+    <!-- <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> Variable substitution </h1>
+
+<p>
+ In a shell, when you write
+</p>
+<pre>
+ $ A='foobar' ; echo $A
+</pre>
+<p>
+ the <tt>echo</tt> command is given the argument <tt>foobar</tt>.
+The <tt>foobar</tt> <em>value</em> has been substituted for the
+<tt>A</tt> <em>variable</em>.
+</p>
+<p>
+ Although <tt>execline</tt> maintains no state, and thus has no
+real variables, it provides such a <em>substitution</em> facility
+via <em>substitution commands</em>, namely:
+</p>
+<ul>
+ <li> <a href="define.html">define</a> </li>
+ <li> <a href="import.html">import</a> </li>
+ <li> <a href="importas.html">importas</a> </li>
+ <li> <a href="elglob.html">elglob</a> </li>
+ <li> <a href="elgetpositionals.html">elgetpositionals</a> </li>
+ <li> <a href="multidefine.html">multidefine</a> </li>
+ <li> <a href="multisubstitute.html">multisubstitute</a> </li>
+</ul>
+
+<p>
+ A substitution command takes a <em>key</em>, i.e. a string
+(which can contain any character but <tt>$</tt>, <tt>{</tt> and
+<tt>}</tt>, although it is recommended to use only alphanumerical
+characters), and a way to compute a <em>value</em>.
+</p>
+
+<h2> Basics </h2>
+
+<ul>
+ <li> If the substitution key is <em>foo</em>, then the substitution
+command will look for every occurrence of <tt>${<em>foo</em>}</tt> or
+<tt>$<em>foo</em></tt> in the rest of its argv. Note that
+<tt>${<em>foo</em>}bar</tt> matches, but <tt>$<em>foo</em>bar</tt>
+<strong>does not</strong>. To be safe, always use the syntax with
+braces, unless <tt>$<em>foo</em></tt> is a word on its own. </li>
+ <li> Every match is then replaced with the <em>value</em>. </li>
+</ul>
+
+<p>
+The simplest example is the following:
+</p>
+
+<pre>
+#!/command/execlineb
+define FOO blah
+echo $FOO
+</pre>
+
+<p>
+ which will replace the <tt>FOO</tt> key with the <tt>blah</tt> value,
+then execute the <tt>echo</tt> command. So that script will print
+<tt>blah</tt> on stdout.
+</p>
+
+<a name="quoting" />
+<h2> Quoting </h2>
+
+<p>
+ execline allows you to write literal <tt>${<em>foo</em>}</tt> constructs
+even when the <em>foo</em> variable is being substituted, thanks to a
+quoting mechanism.
+ Brace (pun intended) yourself: the following is the most complex part
+of the whole language.
+</p>
+
+<h3> Rationale </h3>
+
+<p>
+ If we want to be able to have a literal <tt>${<em>foo</em>}</tt>, then:
+</p>
+<ul>
+ <li> The <tt>${<em>foo</em>}</tt> sequence will mean one of two things:
+be substituted, or <em>don't</em> be substituted. </li>
+ <li> The default (unquoted) action should be: substitute. </li>
+ <li> A sequence that means "do not substitute" should be able
+to appear literally. The quote character should also be able to
+appear literally before a sequence that means "substitute". (Tricky, eh&nbsp;?) </li>
+ <li> There should be as few quote characters as possible, to avoid
+shell-like quoting nightmares. </li>
+</ul>
+
+<h3> Syntax </h3>
+
+<p>
+ Rule:
+</p>
+
+<ul>
+ <li> The backslash (<tt>\</tt>) is a quote character for substitution commands. </li>
+ <li> The following rule applies only if the <em>foo</em> key is
+explicitly used in a substitution command. If no command tries to
+substitute anything for <em>foo</em>, sequences like
+<tt>${<em>foo</em>}</tt> and preceding backslashes are left untouched. </li>
+ <li> (Substitute.) If <tt>${<em>foo</em>}</tt> is preceded by <tt>2*n</tt> backslashes
+(an <strong>even</strong> number), the whole sequence will be
+replaced with <tt>n</tt> backslashes, followed by the substituted value. </li>
+ <li> (Do not substitute.) If <tt>${<em>foo</em>}</tt> is preceded by <tt>2*n+1</tt> backslashes
+(an <strong>odd</strong> number), the whole sequence will be replaced
+with  <tt>n</tt> backslashes, followed by the literal <tt>${<em>foo</em>}</tt>. </li>
+</ul>
+
+<p>
+ And now, the catch: the <a href="execlineb.html">execlineb</a> launcher,
+as well as the shell,
+interprets backslashes as escape characters. To make a word that contains
+a backlash, you need to write <em>two</em> backslashes in your execline
+script or shell command line. That means that the whole number of backslashes
+you must write before your <tt>${<em>foo</em>}</tt> sequence must be doubled
+for the substitution command to read the proper number of backslashes and
+perform its work correctly. <br />
+ Once you keep that in mind, the quoting rule is logical.
+</p>
+
+<h3> Example </h3>
+
+<p>
+ The quoting rule is best illustrated with the following example, where
+the <tt>A</tt> key is substituted, and the <tt>$B</tt> sequences mean
+nothing special.
+</p>
+
+<pre>
+#!/command/execlineb
+define A val
+foreground { echo $A \\$A \\\\$A \\\\\\$A \\\\\\\\$A \\\\\\\\\\$A }
+             echo $B \\$B \\\\$B \\\\\\$B \\\\\\\\$B \\\\\\\\\\$B
+</pre>
+<p>
+ prints
+</p>
+<pre>
+val $A \val \$A \\val \\$A
+$B \$B \\$B \\\$B \\\\$B \\\\\$B
+</pre>
+
+<p>
+ Phew.
+</p>
+
+<a name="el_transform">
+<h2> Value transformations </h2>
+</a>
+
+<p>
+ A value can go through
+<a href="el_transform.html">several transformations</a> before it is
+substituted. It can be <a href="el_transform.html#crunch">crunched</a>,
+<a href="el_transform.html#chomp">chomped</a>, and/or
+<a href="el_transform.html#split">split</a>.
+</p>
+
+<a name="split">
+<h2> Substitution of split values </h2>
+</a>
+
+<p>
+ A <a href="el_transform.html">split</a> value for <tt>FOO</tt> means that
+a word containing <tt>${FOO}</tt> will be replaced by zero, one, or
+(usually) more than one word. The value actually means a
+<em>list</em> of values.
+</p>
+
+<p>
+ The rule is: substituting a list of values
+(<em>v1</em>, <em>v2</em>, <em>...</em>) for a key <em>A</em> is the
+same as listing the substitutions of every value <em>v<tt>i</tt></em>
+for <em>A</em>. <br />
+ For instance,
+</p>
+
+<pre>
+#!/command/execlineb
+define -s FOO "v1 v2 v3" echo prefix-${FOO}-postfix
+</pre>
+
+<p>
+ will substitute three values for <tt>$FOO</tt>: <tt>v1</tt>, <tt>v2</tt>
+and <tt>v3</tt>. So the <tt>echo</tt> command will be called with three
+arguments: <tt>prefix-v1-postfix</tt>, <tt>prefix-v2-postfix</tt>, and
+<tt>prefix-v3-postfix</tt>.
+</p>
+
+<p>
+(Implementation note: the fact that word prefixes are kept is
+what makes execline's subtitutions secure.
+<a href="el_semicolon.html">Blocks</a> are implemented via prefix
+space characters; a substitution occurring inside a block will always produce
+words beginning with the right amount of spaces, thus substituted
+values cannot prematurely terminate a block.)
+</p>
+
+<a name="recursive" />
+<h3> Recursive substitutions </h3>
+
+<p>
+ A direct consequence of that rule is that substitutions will be performed
+recursively if more than one key appears in one word and the values for
+those keys are split. Parallel substitutions are performed from left to
+right. For instance, in
+</p>
+
+<pre>
+#!/command/execlineb
+define -s B "1 2 3" echo ${B}x${B}
+</pre>
+<p>
+ the <tt>${B}x${B}</tt> word will be replaced with <em>nine</em> words:
+<tt>1x1</tt>, <tt>1x2</tt>, <tt>1x3</tt>, <tt>2x1</tt>, <tt>2x2</tt>,
+<tt>2x3</tt>, <tt>3x1</tt>, <tt>3x2</tt>, and <tt>3x3</tt>, in that order.
+<br /> Here is an example with two distinct substitutions in parallel:
+</p>
+
+<pre>
+#!/command/execlineb
+multisubstitute
+{
+  define -s A "a b c d"
+  define -s B "1 2 3"
+}
+echo ${A}x${B}
+</pre>
+
+<p>
+ The <tt>${A}x${B}</tt> word will be replaced with <em>twelve</em> words:
+<tt>ax1</tt>, <tt>ax2</tt>, <tt>ax3</tt>, <tt>bx1</tt>, <tt>bx2</tt>,
+<tt>bx3</tt>, <tt>cx1</tt>, <tt>cx2</tt>, <tt>cx3</tt>, <tt>dx1</tt>,
+<tt>dx2</tt>, and <tt>dx3</tt>, in that order. You can check that the
+order of the <tt>define</tt> directives in
+<a href="multisubstitute.html">multisubstitute</a> does not matter.
+</p>
+
+<p>
+If the left-to-right order does not suit you, then you should perform
+<em>serial</em> substitutions. For instance, the previous script can
+be replaced with
+</p>
+
+<pre>
+#!/command/execlineb
+define -s B "1 2 3"
+define -s A "a b c d"
+echo ${A}x${B}
+</pre>
+<p>
+ and will substitute <tt>${B}</tt> first, then <tt>${A}</tt>. So it
+will print
+</p>
+
+<pre>
+ax1 bx1 cx1 dx1 ax2 bx2 cx2 dx2 ax3 bx3 cx3 dx3
+</pre>
+
+<p>
+ in that order.
+</p>
+
+<a name="brainfsck"></a>
+<h2> Not for the faint of heart </h2>
+
+<p>
+ If you think you have mastered the art of execline substitution, then
+you can try to do better than these people:
+</p>
+
+<ul>
+ <li><a href="http://jriou.org/">Jo&euml;l Riou</a>
+wrote the <a href="quine-jriou.txt">first execlineb quine</a>, using
+only <tt>echo</tt> as non-execline external command. </li>
+ <li> Shortly after, <a href="http://code.dogmap.org/">Paul Jarc</a>
+wrote a <a href="quine-prj.txt">much shorter quine</a>, using
+<tt>echo</tt> and <tt>env</tt> as non-execline external commands. He
+also wrote a <a href="quine-prj-2.txt">revised version</a>, using only
+<tt>echo</tt>, and a shorter <a href="quine-prj-3.txt">definitive
+version</a>. The last one is probably very close to the shortest
+possible execline quine. </li>
+ <li> <a href="http://www.madore.org/~david/">David Madore</a>
+wrote <a href="quine-dam.txt">another quine</a>, using <tt>printf</tt>.
+His quine is longer than the other ones, but is well-commented and can
+be used as a tutorial on how to write quines. :) </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/el_transform.html b/doc/el_transform.html
new file mode 100644
index 0000000..094533a
--- /dev/null
+++ b/doc/el_transform.html
@@ -0,0 +1,204 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: value transformation</title>
+    <meta name="Description" content="execline: value transformation" />
+    <meta name="Keywords" content="execline value transformation el_transform crunch chomp split" />
+    <!-- <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> Value transformation </h1>
+
+<p>
+ You can apply 3 kinds of transformations to a value which is to be
+<a href="el_substitute.html">substituted</a> for a variable:
+crunching, chomping and splitting. They
+always occur in that order.
+</p>
+
+
+<a name="delim">
+<h2> Delimiters </h2>
+</a>
+
+<p>
+ The transformations work around <em>delimiters</em>. Delimiters are
+the semantic bounds of the "words" in your value.
+ You can use any character (except the null character, which you cannot
+use in execline scripts) as a delimiter, by giving a string consisting
+of all the delimiters you want as the argument to the <tt>-d</tt> option
+used by substitution commands. By default, the string "<tt>&nbsp;\n\r\t</tt>"
+is used, which means that the default delimiters are spaces, newlines,
+carriage returns and tabs.
+</p>
+
+
+<a name="crunch">
+<h2> Crunching </h2>
+</a>
+
+<p>
+ You can tell the substitution command to merge sets of consecutive
+delimiters into a single delimiter. For instance, to replace
+three consecutive spaces, or a space and 4 tab characters, with a
+single space. This is called <em>crunching</em>, and it is done
+by giving the <tt>-C</tt> switch to the substitution command. The
+remaining delimiter will always be the first in the sequence.
+</p>
+
+<p>
+ Crunching is mainly useful when also <a href="#split">splitting</a>.
+</p>
+
+<a name="chomp">
+<h2> Chomping </h2>
+</a>
+
+<p>
+ Sometimes you don't want the last delimiter in a value.
+ <em>Chomping</em> deletes the last character of a value if it is a
+delimiter. It can be requested by giving the <tt>-n</tt> switch to the
+substitution command. Note that chomping always happens <em>after</em>
+crunching, which means you can use crunching+chomping to ignore, for
+instance, a set of trailing spaces.
+</p>
+
+
+<a name="split">
+<h2> Splitting </h2>
+</a>
+
+<p>
+ In a shell, when you write
+</p>
+
+<pre>
+ $ A='foo bar' ; echo $A
+</pre>
+
+<p>
+ the <tt>echo</tt> command is given two arguments, <tt>foo</tt>
+and <tt>bar</tt>. The <tt>$A</tt> value has been <em>split</em>,
+and the space between <tt>foo</tt> and <tt>bar</tt> acted as a
+<em>delimiter</em>.
+</p>
+
+<p>
+If you want to avoid splitting, you must write something like
+</p>
+
+<pre>
+ $ A='foo bar' ; echo "$A"
+</pre>
+
+<p>
+ The doublequotes "protect" the spaces. Unfortunately, it's easy
+to forget them and perform unwanted splits during script execution
+- countless bugs happen because of the shell's splitting behaviour.
+</p>
+
+<p>
+ <tt>execline</tt> provides a <em>splitting</em> facility, with
+several advantages over the shell's:
+</p>
+
+<ul>
+ <li> Splitting has to be explicitly requested, by specifying the
+<tt>-s</tt> option to commands that perform
+<a href="el_substitute.html">substitution</a>. By default,
+substitutions are performed as is, without interpreting the
+characters in the value. </li>
+ <li> Positional parameters are never split, so that execline
+scripts can handle arguments the way the user intended to. To
+split <tt>$1</tt>, for instance, you have to ask for it
+specifically:
+<pre>
+#!/command/<a href="execlineb.html">execlineb</a> -S1
+<a href="define.html">define</a> -sd" " ARG1S $1
+blah $ARG1S
+</pre>
+ and $ARG1S will be split using the space character as only delimiter.
+ </li>
+ <li> Any character can be a delimiter. </li>
+</ul>
+
+<h3> How it works </h3>
+
+<ul>
+ <li> A substitution command can request that the substitution value
+be split, via the <tt>-s</tt> switch. </li>
+ <li> The splitting function parses the value, looking for delimiters.
+It fills up a structure, marking the split points, and the number
+<em>n</em> of words the value is to be split into.
+ <ul>
+  <li> A word is a sequence of characters in the value <em>terminated
+by a delimiter</em>. The delimiter is not included in the word. </li>
+  <li> If the value begins with <em>x</em> delimiters, the word list
+will begin with <em>x</em> empty words. </li>
+  <li> The last sequence of characters in the value will be recognized
+as a word even if it is not terminated by a delimiter, unless you have
+requested <a href="#chomp">chomping</a> and there was no delimiter at
+the end of the value <em>before</em> the chomp operation - in which case
+that last sequence will not appear at all. </li>
+ </ul> </li>
+ <li> The substitution rewrites the argv. A non-split value will
+be written as one word in the argv; a split value will be written
+as <em>n</em> separate words. </li>
+ <li> Substitution of split values is
+<a href="el_substitute.html#recursive">performed recursively</a>. </li>
+</ul>
+
+
+<a name="netstrings">
+<h3> Decoding netstrings </h3>
+</a>
+
+<p>
+ <a href="http://cr.yp.to/proto/netstrings.txt">Netstrings</a> are
+a way to reliably encode strings containing arbitrary characters.
+<tt>execline</tt> takes advantage of this to offer a completely safe
+splitting mechanism. If a substitution command is given an empty
+delimiter string (by use of the <tt>-d&nbsp;""</tt> option), the
+splitting function will try to interpret the value as a sequence
+of netstrings, every netstring representing a word. For instance,
+in the following command line:
+</p>
+
+<pre>
+ $ define -s -d "" A '1:a,2:bb,0:,7:xyz 123,1: ,' echo '$A'
+</pre>
+
+<p>
+ the <tt>echo</tt> command will be given five arguments:
+</p>
+
+<ul>
+ <li> the "<tt>a</tt>" string </li>
+ <li> the "<tt>bb</tt>" string </li>
+ <li> the empty string </li>
+ <li> the "<tt>xyz 123</tt>" string </li>
+ <li> the "<tt> </tt>" string (a single space) </li>
+</ul>
+
+<p>
+ However, if the value is not a valid sequence of netstrings, the
+substitution command will die with an error message.
+</p>
+
+<p>
+ The <a href="dollarat.html">dollarat</a> command, for instance,
+can produce a sequence of netstrings (encoding all the arguments
+given to an execline script), meant to be decoded by a substitution
+command with the <tt>-d&nbsp;""</tt> option.
+</p>
+
+</body>
+</html>
diff --git a/doc/elgetopt.html b/doc/elgetopt.html
new file mode 100644
index 0000000..a5650f2
--- /dev/null
+++ b/doc/elgetopt.html
@@ -0,0 +1,60 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the elgetopt command</title>
+ <meta name="Description" content="execline: the elgetopt command" />
+ <meta name="Keywords" content="execline command elgetopt options arguments" />
+ <!-- <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> The <tt>elgetopt</tt> program </h1>
+
+<p>
+<tt>elgetopt</tt> performs <tt>getopt</tt>-style parsing on the
+arguments to an execline script.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     elgetopt <em>optstring</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>elgetopt</tt> expects to find a valid number <em>n</em> of
+arguments in the <tt>#</tt> environment variable, and <em>n</em>+1
+environment variables <tt>0</tt>, <tt>1</tt>, ..., <tt><em>n</em></tt>.
+It exits 100 if it is not the case. </li>
+ <li> <tt>elgetopt</tt> <a href="el_pushenv.html">pushes</a>
+environment variables starting with <tt>ELGETOPT_</tt>. To get the
+previous values back, use
+<a href="emptyenv.html"><tt>emptyenv&nbsp;-o</tt></a>. </li>
+ <li> <tt>elgetopt</tt> looks into <tt>1</tt>, <tt>2</tt>... for options,
+as specified by <em>optstring</em>, which is a standard <tt>getopt</tt>
+string. </li>
+ <li> If the <tt>-<em>c</em></tt> switch is recognized, <tt>elgetopt</tt>
+sets the <tt>ELGETOPT_<em>c</em></tt> environment variable. The value
+of that variable is the argument to the <tt>-<em>c</em></tt> switch if
+it has one, and 1 otherwise. </li>
+ <li> After setting all recognized options, <tt>elgetopt</tt> makes
+new <tt>#</tt>, <tt>1</tt>, <tt>2</tt>... "positional parameters" with
+what remains. </li>
+ <li> <tt>elgetopt</tt> then execs into <em>prog...</em>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> GNU-style options are not supported. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/elgetpositionals.html b/doc/elgetpositionals.html
new file mode 100644
index 0000000..d193413
--- /dev/null
+++ b/doc/elgetpositionals.html
@@ -0,0 +1,94 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the elgetpositionals command</title>
+ <meta name="Description" content="execline: the elgetpositionals command" />
+ <meta name="Keywords" content="execline command elgetpositionals arguments positional parameters" />
+ <!-- <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> The <tt>elgetpositionals</tt> program </h1>
+
+<p>
+<tt>elgetpositionals</tt> substitutes the positional parameters of an execline script.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     elgetpositionals [ -P <em>sharp</em> ] <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>elgetpositionals</tt> reads the number <em>n</em> of "positional
+parameters" in the <tt>#</tt> environment variable. If that variable
+is not set or does not contain a valid <em>n</em>, <tt>elgetpositionals</tt>
+exits 100. </li>
+ <li> <tt>elgetpositionals</tt> performs some
+<a href="el_substitute.html">substitutions</a> in parallel on
+<em>prog...</em>:
+<ul>
+ <li> key: <tt>#</tt>, value: <em>n</em> </li>
+ <li> key: <tt>0</tt>, value: the value of the <tt>0</tt> environment
+variable </li>
+ <li> key: <tt>1</tt>, value: the value of the <tt>1</tt> environment
+variable </li>
+ <li> ... and so on until <em>n</em> (or <em>sharp</em> if it is
+greater than <em>n</em>). Those values are never transformed. </li>
+ <li> key: <tt>@</tt>, value: all values of the variables from <tt>1</tt> to
+<tt><em>n</em></tt>. This value is <a href="el_transform.html#split">split</a>
+into <em>n</em> words. </li>
+</ul>
+ If a variable between <tt>0</tt> and <tt><em>n</em></tt> does not
+exist, <tt>elgetpositionals</tt> exits 100.
+ </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-P</tt>&nbsp;<em>sharp</em>&nbsp;: substitute at least
+<em>sharp</em>+1 positional parameters, from 0 to
+max(<em>n</em>, <em>sharp</em>). If <em>n</em>&lt;<em>sharp</em>,
+positional parameters between <em>n</em>+1 and <em>sharp</em> are
+replaced with the empty string. Not having the <tt>-P</tt> switch is
+equivalent to having <tt>-P&nbsp;0</tt>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> A typical argument-taking execline script will
+often begin that way:
+<pre>
+ #!/command/execlineb
+ elgetopt <em>optstring</em>
+ elgetpositionals
+ <em>prog...</em>
+</pre>
+</li>
+ <li> If you are performing other substitutions that do not depend
+on the positional parameters, think about replacing the
+<tt>elgetpositionals</tt> call with a
+<a href="multisubstitute.html">multisubstitute</a> call containing
+the <tt>elgetpositionals</tt> directive. </li>
+ <li> If you are going to use the <a href="shift.html">shift</a>
+command, it is best to use <a href="importas.html">importas</a> to
+substitute the first positional parameters, then use <tt>shift</tt>,
+then <tt>elgetpositionals</tt>. That way, <tt>$@</tt> will correctly
+be replaced by the remaining arguments. More generally, you should
+try to use <tt>elgetpositionals</tt> as late as possible. </li>
+ <li> Use <tt>execlineb</tt>'s <tt>-S</tt> switch instead of
+<tt>elgetpositionals</tt> whenever you can. It is more efficient. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/elglob.html b/doc/elglob.html
new file mode 100644
index 0000000..5b5d6aa
--- /dev/null
+++ b/doc/elglob.html
@@ -0,0 +1,68 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the elglob command</title>
+ <meta name="Description" content="execline: the elglob command" />
+ <meta name="Keywords" content="execline command elglob pattern shell globbing" />
+ <!-- <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> The <tt>elglob</tt> program </h1>
+
+<p>
+<tt>elglob</tt> performs globbing on a pattern, then executes
+another program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     elglob [ -v ] [ -w ] [ -s ] [ -m ] [ -e ] [ -0 ] <em>variable</em> <em>pattern</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>elglob</tt> performs
+<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html">globbing</a>
+on <em>pattern</em>. </li>
+ <li> It then performs
+<a href="el_substitute.html">variable substitution</a> on
+<em>prog...</em>, using <em>variable</em> as key and the result of the
+globbing as value. The value is always split: it contains as many words
+as they are matches for the globbing pattern. </li>
+ <li> <tt>elglob</tt> then execs into the modified <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-v</tt>&nbsp;: verbose. If there is a problem while globbing, print
+a warning message on stderr. </li>
+ <li> <tt>-w</tt>&nbsp;: strict. If there is a problem while globbing, die
+immediately. This is harsh - you probably don't need that option. </li>
+ <li> <tt>-s</tt>&nbsp;: sort the matches. By default, the results are
+left unsorted. </li>
+ <li> <tt>-m</tt>&nbsp;: mark. Append a slash to each word that corresponds
+to a directory. </li>
+ <li> <tt>-e</tt>&nbsp;: no escape. Treat backslashes in <em>pattern</em>
+literally; do not allow quoting of metacharacters in <em>pattern</em> via
+backslashes. <strong>Warning</strong>: the
+<a href="execlineb.html">execlineb</a> launcher
+uses the backslash as their own escape character - if you want a
+backslash to be passed to <tt>elglob</tt>, do not forget to <em>double</em>
+it. </li>
+ <li> <tt>-0</tt>&nbsp;: null globbing. By default, if <em>pattern</em>
+matches nothing, it will be substituted as is (verbatim in one word). With
+this option, if <em>pattern</em> matches nothing, it will be properly
+substituted as zero word. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/emptyenv.html b/doc/emptyenv.html
new file mode 100644
index 0000000..81cf45a
--- /dev/null
+++ b/doc/emptyenv.html
@@ -0,0 +1,57 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the emptyenv program</title>
+    <meta name="Description" content="execline: the emptyenv program" />
+    <meta name="Keywords" content="execline command emptyenv" />
+    <!-- <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> The <tt>emptyenv</tt> program </h1>
+
+<p>
+<tt>emptyenv</tt> empties the current environment, or cleans it up; then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     emptyenv [ -p ] <em>prog...</em>
+     emptyenv -c <em>prog...</em>
+     emptyenv [ -o ] [ -P ] <em>prog...</em>
+</pre>
+
+<p>
+By default, <tt>emptyenv</tt> unsets all environment variables, then
+execs into <em>prog</em> with its arguments. Options control which
+environment variables are unset.
+</p>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-p</tt>&nbsp;: keep the <tt>PATH</tt> environment variable. </li>
+ <li> <tt>-c</tt>&nbsp;: clean up. Do not empty the environment. Instead,
+remove every variable used internally by the execline programs, to avoid
+any interference with or information leakage to external programs. </li>
+ <li> <tt>-o</tt>&nbsp;: <a href="el_pushenv.html#pop">pop</a> environment
+variables starting with <tt>ELGETOPT_</tt>. You might want to do this
+before executing a final program from a script that uses
+<a href="elgetpositionals.html">elgetpositionals</a>. </li>
+ <li> <tt>-P</tt>&nbsp;: <a href="el_pushenv.html#pop">pop</a> environment
+variables starting with <tt>#</tt>, <tt>0</tt> to <tt>9</tt>, and
+<tt>EXECLINE_</tt>. You might want to do this before executing a final program
+from a script launched by <a href="execlineb.html">execlineb</a>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/exec.html b/doc/exec.html
new file mode 100644
index 0000000..8655541
--- /dev/null
+++ b/doc/exec.html
@@ -0,0 +1,50 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the exec program</title>
+    <meta name="Description" content="execline: the exec program" />
+    <meta name="Keywords" content="execline command exec" />
+    <!-- <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> The <tt>exec</tt> program </h1>
+
+<p>
+<tt>exec</tt> executes the command line it is given.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     exec [ -c ] [ -l ] [ -a <em>argv0</em> ]<em>prog...</em>
+</pre>
+
+<p>
+<tt>exec</tt> execs into <em>prog...</em>. It does nothing else.
+<br /> Without options, <tt>exec</tt> can be seen as the execline NOP.
+</p>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-c</tt>&nbsp;: empty the environment. <em>prog</em> is executed with no environment variables. <strong>Warning:&nbsp;</strong><em>prog</em> will run with an empty PATH, so make sure it does not rely on it. </li>
+ <li> <tt>-l</tt>&nbsp;: login. Prepends <em>prog</em>'s argv[0] with a dash. </li>
+ <li> <tt>-a <em>argv0</em></tt>&nbsp;: argv0. Replace <em>prog</em>'s argv[0] with <em>argv0</em>. This is done <em>before</em> adding a dash, if the <tt>-l</tt> option is also present. </li>
+</ul>
+
+<p>
+The <tt>exec</tt> command, along with its options, is designed to emulate
+the standard <tt>exec</tt> shell builtin, which replaces the shell with the
+command it is given.
+</p>
+
+</body>
+</html>
diff --git a/doc/execline-shell.html b/doc/execline-shell.html
new file mode 100644
index 0000000..b3526f0
--- /dev/null
+++ b/doc/execline-shell.html
@@ -0,0 +1,53 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the execline-shell script</title>
+ <meta name="Description" content="execline: the execline-shell script" />
+ <meta name="Keywords" content="execline script execline-shell" />
+ <!-- <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> The <tt>execline-shell</tt> script </h1>
+
+<p>
+<tt>execline-shell</tt> executes <tt>$HOME/.execline-shell</tt>
+with the arguments it is given.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     /etc/execline-shell
+</pre>
+
+<ul>
+ <li> <tt>execline-shell</tt> transforms itself into
+<tt>${HOME}/.execline-shell $@</tt>. </li>
+ <li><tt>${HOME}/.execline-shell</tt> must be readable and
+executable by the user. It must exec into an interactive
+shell with <tt>$@</tt> as its argument.</li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>execline-shell</tt> is meant to be used as the <tt>SHELL</tt>
+environment variable value. It allows one to specify his favourite shell and
+shell configuration in any language, since the <tt>${HOME}/.execline-shell</tt>
+file can be any executable program. <tt>${HOME}/.execline-shell</tt> can be seen
+as a portable <tt>.<em>whatever</em>rc</tt> file. </li>
+ <li> As an administrator-modifiable configuration file, <tt>execline-shell</tt>
+provided in execline's <tt>etc/</tt> subdirectory, and should be copied by
+the administrator to <tt>/etc</tt>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/execline-startup.html b/doc/execline-startup.html
new file mode 100644
index 0000000..5df401d
--- /dev/null
+++ b/doc/execline-startup.html
@@ -0,0 +1,59 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en" />
+ <title>execline: the execline-startup script</title>
+ <meta name="Description" content="execline: the execline-startup script" />
+ <meta name="Keywords" content="execline execline-startup startup login script .profile" />
+ <!-- <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> The <tt>execline-startup</tt> script </h1>
+
+<p>
+<tt>execline-startup</tt> performs some system-specific
+login initialization, then executes <tt>${HOME}/.execline-loginshell</tt>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     /etc/execline-startup
+</pre>
+
+<ul>
+ <li> <tt>execline-startup</tt> sets the <tt>SHELL</tt>
+environment variable to <tt>/etc/execline-shell</tt>.
+It then performs some system-specific initialization, and
+transforms itself into <tt>${HOME}/.execline-loginshell $@</tt>. </li>
+ <li><tt>${HOME}/.execline-loginshell</tt> must be readable and
+executable by the user. It must exec into <tt>$SHELL $@</tt>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>execline-startup</tt> is an
+<a href="execlineb.html">execlineb</a> script; hence, it is readable
+and modifiable. It is meant to be modified by the system administrator
+to perform system-specific login-time initialization. </li>
+ <li> As a modifiable configuration file, execline-startup is provided in execline's
+<tt>etc/</tt> subdirectory, and should be copied by the administrator
+to <tt>/etc</tt>. </li>
+ <li> <tt>execline-startup</tt> is meant to be used as a login shell.
+System administrators should manually add <tt>/etc/execline-startup</tt>
+to the <tt>/etc/shells</tt> file. The <tt>/etc/execline-startup</tt>
+file itself plays the role of the <tt>/etc/profile</tt> file, and
+<tt>${HOME}/.execline-loginshell</tt> plays the role of the
+<tt>${HOME}/.profile</tt> file.</li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/execlineb.html b/doc/execlineb.html
new file mode 100644
index 0000000..64f29bd
--- /dev/null
+++ b/doc/execlineb.html
@@ -0,0 +1,246 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-6" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the execlineb command</title>
+    <meta name="Description" content="execline: the execlineb command" />
+    <meta name="Keywords" content="execline command execlineb launcher" />
+    <!-- <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> The <tt>execlineb</tt> program </h1>
+
+<p>
+<tt>execlineb</tt> reads and executes a script.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     execlineb [ -q | -w | -W ] [ -p | -P | -S <em>nmin</em> ] -c <em>script</em> [ <em>args...</em> ]
+</pre>
+
+<p>
+or
+</p>
+
+<pre>
+     execlineb [ -q | -w | -W ] [ -p | -P | -S <em>nmin</em> ] <em>scriptfile</em> [ <em>args...</em> ]
+</pre>
+
+<p>
+or in an executable file:
+</p>
+
+<pre>
+#!/command/execlineb [ -qwWpPS<em>nmin</em> ]
+<em>script</em>
+</pre>
+
+<p>
+ <em>Parsing phase</em>.
+</p>
+
+<ul>
+ <li> <tt>execlineb</tt> reads and parses the script it is given.
+It exits 100 on a syntax error and 111 on a temporary error.
+It makes an <em>argv</em>, i.e. a system command line, with the
+parsed script. If the <em>argv</em> is empty, <tt>execlineb</tt>
+exits 0. </li>
+</ul>
+
+<p>
+ <em>Environment management phase</em>.
+</p>
+
+<ul>
+ <li> <em>Pushing the current stack frame.</em> If neither the
+<tt>-p</tt> nor the <tt>-P</tt> nor the <tt>-S</tt> option is set:
+<tt>execlineb</tt> <a href="el_pushenv.html">pushes</a>
+the current positional parameters, i.e. environment variables that
+start with <tt>#</tt>, <tt>0</tt>, <tt>1</tt>, ..., <tt>9</tt>.
+To get the previous values back, use
+<a href="emptyenv.html"><tt>emptyenv&nbsp;-P</tt></a>. </li>
+ <li> <em>Setting the new stack frame.</em> If neither the <tt>-P</tt>
+nor the <tt>-S</tt> option is set:
+ <ul>
+  <li> <tt>execlineb</tt> sets the <tt>#</tt> environment variable to
+the number <em>n</em> of <em>args</em> it is given. </li>
+  <li> It sets the <tt>0</tt> environment variable to the name
+of the script - or to the <tt>execlineb</tt> invocation name
+if the <tt>-c</tt> option is used. </li>
+  <li> It sets the <tt>1</tt>, <tt>2</tt>, ... <tt><em>n</em></tt>
+environment variables to the different <em>args</em>. </li>
+ </ul> </li>
+</ul>
+
+<p>
+ <em>Execution phase</em>.
+</p>
+
+<ul>
+ <li> <tt>execlineb</tt> executes into the <em>argv</em> it
+has built from the script.
+There is only one command line for the
+whole script: the <tt>execlineb</tt> binary is a <em>launcher</em>,
+whose sole purpose is to execute into that command line. It does
+not stay in memory like a traditional <em>interpreter</em> would. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-c&nbsp;<em>script</em></tt>&nbsp;: execute <em>script</em>, do not
+look for a file. </li>
+</ul>
+
+<p>
+ See below for the other options.
+</p>
+
+<h2> Syntax of scripts </h2>
+
+<p>
+ An execlineb script is a string that must not contain the null character.
+<tt>execlineb</tt> parses it and divides it into <em>words</em>.
+
+ The parser recognizes the following components:
+</p>
+
+<ul>
+ <li> <em>whitespace</em> is defined as spaces, tabs, newlines and
+carriage returns. Words are always separated by whitespace.</li>
+ <li> A <em>quoted string</em> begins with a doublequote (<tt>"</tt>)
+and ends with another doublequote. Quoted doublequotes must be prefixed
+by a backslash (<tt>\</tt>). Quoted strings always evaluate to exactly
+one word. For instance, <tt>""</tt> evaluates to the empty word. </li>
+ <li> The <tt>\a</tt>, <tt>\b</tt>, <tt>\t</tt>, <tt>\n</tt>, <tt>\v</tt>,
+<tt>\f</tt>, and <tt>\r</tt> sequences are recognized in quoted
+strings, and are converted to the ASCII numbers 7, 8, 9, 10, 11, 12 and
+13 respectively. </li>
+ <li> Inside a quoted string, backslashed
+newlines disappear completely. </li>
+ <li> <tt>\0x<em>ab</em></tt> sequences are recognized in quoted strings
+and evaluate to ASCII hexadecimal number <em>ab</em>. </li>
+ <li> <tt>\0<em>abc</em></tt> sequences are recognized in quoted strings
+and evaluate to ASCII octal number <em>abc</em>. </li>
+ <li> <tt>\<em>abc</em></tt> sequences are recognized in quoted strings
+and evaluate to ASCII decimal number <em>abc</em>. <em>a</em> must not
+be zero. </li>
+ <li> A comment starts with a <tt>#</tt> and ends with the line. Comments
+are not recognized inside quoted strings. </li>
+ <li> Anything else is an unquoted string, that can evaluate to
+zero or more words. </li>
+ <li> Any character can be escaped in unquoted strings by prepending
+it with a backslash. It works the same way in quoted strings, except
+for the special sequences described above. </li>
+</ul>
+
+<p>
+ You can see an example of distinct <tt>execlineb</tt> components
+<a href="componentsb.txt">here</a>.
+</p>
+
+<p>
+ In addition to that simple lexing,
+<tt>execlineb</tt> performs the following higher-level parsing:
+</p>
+
+<ul>
+   <li> A word consisting of a single <em>opening brace</em> (<tt>{</tt>)
+increments an internal level counter, <em>blevel</em>, and disappears from the
+<em>argv</em>. Quoted open braces do not have that behaviour. </li>
+ <li> A word consisting of a single <em>closing brace</em> (<tt>}</tt>)
+decrements <em>blevel</em>, and is replaced with the empty word.
+Quoted closing braces do not have that behaviour. </li>
+ <li> If <tt>execlineb</tt> finds that braces are unmatched (i.e.
+<em>blevel</em> goes below 0 during the parsing, or is not 0 at the end
+of the script), it exits 100 with an error message. </li>
+ <li> <tt>execlineb</tt> automatically quotes
+<a href="el_semicolon.html">blocks</a>. Which means that everytime it
+finds a word, it prepends it with <em>blevel</em> spaces. </li>
+</ul>
+
+<p>
+For proper execution, the sequence of words must follow
+the <a href="grammar.html">execline grammar</a>.
+</p>
+
+<h2> Options for block syntax checking </h2>
+
+<p>
+ External execline commands that read blocks, like
+<a href="foreground.html">foreground</a>, use the <tt>EXECLINE_STRICT</tt>
+environment variable: if it is set to 1, they will print a warning message
+on stderr if they find their blocks not to be properly quoted. If it is set
+to 2, they will also die. If it is set to 0, or unset, they won't complain
+at all.
+</p>
+
+<p>
+ Normally the <tt>EXECLINE_STRICT</tt> environment variable is
+inherited from the caller. You can
+force it unset, set to 1, or set to 2 by giving respectively the
+<tt>-q</tt>, <tt>-w</tt> or <tt>-W</tt> option to <tt>execlineb</tt>.
+</p>
+
+<h2> Options for environment management </h2>
+
+<p>
+ Normally, execline scripts are <em>reentrant</em>: environment variables
+potentially overwritten by <tt>execlineb</tt>, such as <tt>#</tt> or
+<tt>0</tt>, are
+<a href="el_pushenv.html">pushed</a>. This is the standard, safe
+behaviour. Nevertheless, it is rather costly, and may be unneeded for
+small scripts: for those cases, execline comes with two options
+that bypass the environment management. Be warned that the purpose
+of these options is <strong>optimization</strong>, and you should not
+use them if you're not familiar with the way execlineb uses the
+environment to store positional parameters. Alternatively, there's also
+an integrated substitution mechanism that doesn't make use
+of the environment at all.
+</p>
+
+<ul>
+ <li> The <tt>-p</tt> option will bypass the
+<a href="el_pushenv.html">push</a> phase: the current frame of positional
+parameters will be <em>overwritten</em>. The script will <em>not</em> be
+reentrant. </li>
+ <li> The <tt>-P</tt> option will bypass positional parameter handling
+<em>completely</em>: the environment will not be pushed, and positional
+parameters will be ignored. <tt>execlineb -P -c "<em>script</em>"</tt> is
+equivalent to, but more efficient than, <tt>execlineb -c
+"emptyenv -P <em>script</em>"</tt>. You should use the <tt>-P</tt> option
+only in standalone scripts that take no arguments, such as
+<a href="http://skarnet.org/software/s6/">s6</a>'s or 
+<a href="http://smarden.org/runit/">runit</a>'s <em>run scripts</em>. </li>
+ <li> The <tt>-S&nbsp;<em>nmin</em></tt> option <em>will</em> substitute the
+positional parameters - up to at least <em>nmin</em> - but <em>will not</em>
+push nor set environment
+variables. <tt>execlineb -S3 -c "<em>script</em>"</tt> is equivalent to,
+but more efficient than, <tt>execlineb -c "elgetpositionals -P3 emptyenv
+-P <em>script</em>"</tt>. See
+<a href="el_pushenv.html#integrated">the details</a>. </li>
+</ul>
+
+<h2> Current limitations </h2>
+
+<p>
+ <tt>execlineb</tt> builds and executes a unique
+<em>argv</em> with the script: hence scripts are subject to OS-dependent
+limitations such as the kernel buffer size for <em>argv</em> and <em>envp</em>
+ - at least 64 kB on most systems. This means that <tt>execlineb</tt> cannot
+execute arbitrarily large scripts. Be careful with deeply nested scripts too:
+without the <tt>-p</tt>/<tt>-P</tt>/<tt>-S</tt> option, each execlineb
+invocation uses up some space in the environment.
+</p>
+
+</body>
+</html>
diff --git a/doc/exit.html b/doc/exit.html
new file mode 100644
index 0000000..1e94ebd
--- /dev/null
+++ b/doc/exit.html
@@ -0,0 +1,44 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the exit program</title>
+    <meta name="Description" content="execline: the exit program" />
+    <meta name="Keywords" content="execline command exit" />
+    <!-- <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> The <tt>exit</tt> program </h1>
+
+<p>
+<tt>exit</tt> exits with a given exit code.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     exit [ <em>n</em> ]
+</pre>
+
+<p>
+<tt>exit</tt> exits with the exit code <em>n</em>, or 0 if <em>n</em> is not
+given (in which case it's the same as <tt>true</tt>). If <em>n</em> is not
+a number, <tt>exit</tt> exits 100.
+</p>
+
+
+<h2> Notes </h2>
+
+<p>
+<tt>exit</tt> is a standard shell builtin, with the same function.
+</p>
+
+</body>
+</html>
diff --git a/doc/export.html b/doc/export.html
new file mode 100644
index 0000000..35a7f68
--- /dev/null
+++ b/doc/export.html
@@ -0,0 +1,43 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the export program</title>
+    <meta name="Description" content="execline: the export program" />
+    <meta name="Keywords" content="execline command export environment variable" />
+    <!-- <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> The <tt>export</tt> program </h1>
+
+<p>
+<tt>export</tt> sets an environment variable to a given value, then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     export <em>var</em> <em>value</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>export</tt> sets the <em>var</em> environment variable to
+the string <em>value</em>, then execs into <em>prog</em> with
+its arguments.
+</p>
+
+<ul>
+ <li> <em>var</em> must be given without a dollar&nbsp;! </li>
+ <li> <em>var</em> must not contain the character <tt>=</tt> . </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/fdblock.html b/doc/fdblock.html
new file mode 100644
index 0000000..5b2bfa8
--- /dev/null
+++ b/doc/fdblock.html
@@ -0,0 +1,55 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the fdblock program</title>
+    <meta name="Description" content="execline: the fdblock program" />
+    <meta name="Keywords" content="execline command fdblock file descriptor blocking" />
+    <!-- <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> The <tt>fdblock</tt> program </h1>
+
+<p>
+<tt>fdblock</tt> sets or unsets the O_NONBLOCK flag on a given file descriptor
+(which makes reading or writing non-blocking or blocking), then executes
+a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     fdblock [ -n ] <em>fd</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>fdblock</tt> makes the file descriptor number <em>fd</em> blocking,
+no matter what its previous state was. It then execs into <em>prog</em>
+with its arguments.
+</p>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-n</tt>&nbsp;: non-blocking. Sets <em>fd</em> to non-blocking
+mode instead of blocking mode. If used on stdin (0) or stdout (1), this
+option will make a lot of command-line programs behave improperly, because
+most simple command-line programs only support blocking stdin and stdout.
+Make sure you know what you are doing. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>fdblock</tt> has no portable shell equivalent. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/fdclose.html b/doc/fdclose.html
new file mode 100644
index 0000000..15265ac
--- /dev/null
+++ b/doc/fdclose.html
@@ -0,0 +1,44 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the fdclose program</title>
+    <meta name="Description" content="execline: the fdclose program" />
+    <meta name="Keywords" content="execline command fdclose file descriptor close" />
+    <!-- <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> The <tt>fdclose</tt> program </h1>
+
+<p>
+<tt>fdclose</tt> closes a given file descriptor, then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     fdclose <em>fd</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>fdclose</tt> closes the file descriptor number <em>fd</em>, then
+execs into <em>prog</em> with its arguments.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>fdclose <em>n</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>n</em>&lt;&amp;-'</tt></li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/fdmove.html b/doc/fdmove.html
new file mode 100644
index 0000000..8498408
--- /dev/null
+++ b/doc/fdmove.html
@@ -0,0 +1,55 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the fdmove program</title>
+    <meta name="Description" content="execline: the fdmove program" />
+    <meta name="Keywords" content="execline command fdmove file descriptor dup dup2" />
+    <!-- <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> The <tt>fdmove</tt> program </h1>
+
+<p>
+<tt>fdmove</tt> moves or copies a given file descriptor, then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     fdmove [ -c ] <em>fdto</em> <em>fdfrom</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>fdmove</tt> moves the file descriptor number <em>fdfrom</em>,
+to number <em>fdto</em>, then execs into <em>prog</em> with its arguments.
+If <em>fdto</em> is open, <tt>fdmove</tt> closes it before moving
+<em>fdfrom</em> to it.
+</p>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-c</tt>&nbsp;: duplicate <em>fdfrom</em> to <em>fdto</em>
+instead of moving it; do not close <em>fdfrom</em>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>fdmove -c <em>a</em> <em>b</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>a</em>&gt;&amp;<em>b</em>'</tt></li>
+ <li> <tt>fdmove <em>a</em> <em>b</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>a</em>&gt;&amp;<em>b</em> <em>b</em>&lt;&amp;-'</tt></li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/fdreserve.html b/doc/fdreserve.html
new file mode 100644
index 0000000..ef047dc
--- /dev/null
+++ b/doc/fdreserve.html
@@ -0,0 +1,92 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the fdreserve program</title>
+    <meta name="Description" content="execline: the fdreserve program" />
+    <meta name="Keywords" content="execline command fdreserve file descriptor" />
+    <!-- <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> The <tt>fdreserve</tt> program </h1>
+
+<p>
+<tt>fdreserve</tt> updates the environment with file descriptors that
+are guaranteed safe to use, then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     fdreserve <em>n</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>fdreserve</tt> tries to reserve <em>n</em> file descriptors. </li>
+ <li> <tt>fdreserve</tt> sets the <tt>FD0</tt>, <tt>FD1</tt>, ...,
+<tt>FD<em>n-1</em></tt> environment variables: each FD<em>i</em> contains a
+valid file descriptor, that can be safely opened. </li>
+ <li> <tt>fdreserve</tt> then execs into <em>prog</em> with its arguments.
+</ul>
+
+<h2> Common use </h2>
+
+<p>
+<tt>fdreserve</tt> can be used when you do not want to hardcode file
+descriptors in your scripts. For instance, to create a pipe, you could
+use:
+</p>
+
+<pre>
+ #!/command/execlineb
+ fdreserve 2
+ multisubstitute
+ {
+   importas fdr FD0
+   importas fdw FD1
+  }
+ piperw $fdr $fdw
+ <em>prog...</em>
+</pre>
+
+<p>
+ Warning: <tt>fdreserve</tt> does not allocate descriptors, it merely returns
+descriptors that are free at the time it is run. A program like
+</p>
+
+<pre>
+ #!/command/execlineb
+ fdreserve 3
+ multisubstitute
+ {
+   importas fdr FD0
+   importas fdw FD1
+ }
+ piperw $fdr $fdw
+ fdreserve 1
+ multisubstitute
+ {
+   importas oldfd FD2
+   importas newfd FD0
+ }
+ <em>prog...</em>
+</pre>
+
+<p>
+may fail, because <em>oldfd</em> and <em>newfd</em> may be the same.
+To avoid that, you should make sure that all descriptors returned by
+<tt>fdreserve</tt> are actually allocated before calling <tt>fdreserve</tt>
+again.
+(Thanks to <a href="http://code.dogmap.org/">Paul Jarc</a> for having
+spotted that case.)
+</p>
+
+</body>
+</html>
diff --git a/doc/forbacktickx.html b/doc/forbacktickx.html
new file mode 100644
index 0000000..9e09c81
--- /dev/null
+++ b/doc/forbacktickx.html
@@ -0,0 +1,77 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the forbacktickx command</title>
+  <meta name="Description" content="execline: the forbacktickx command" />
+  <meta name="Keywords" content="execline command forbacktickx" />
+  <!-- <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> The <tt>forbacktickx</tt> program </h1>
+
+<p>
+<tt>forbacktickx</tt> runs a program and uses its output as loop elements to
+run another program.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     forbacktickx [ -p | -x breakcode ] [ -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> { <em>gen...</em> } <em>loop...</em>
+</pre>
+
+<ul>
+ <li> <tt>forbacktickx</tt> reads a
+<a href="el_semicolon.html">block</a>,
+<em>gen...</em>, and unquotes it. </li>
+ <li> It runs <em>gen...</em> as a child process. <em>gen</em>'s
+output must not contain a null character. </li>
+ <li> It reads <em>gen</em>'s output as it needs,
+<a href="el_transform.html#split">splitting</a> it automatically. </li>
+ <li> For every argument <em>x</em> in the split output,
+<tt>forbacktickx</tt> runs <em>loop...</em> as a child process, with
+<em>variable</em>=<em>x</em> added to its environment. </li>
+ <li><tt>forbacktickx</tt> then exits 0.
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-p</tt>&nbsp;: parallel mode. Do not wait for a <em>loop...</em>
+instance to finish before spawning the next one. <em>forbacktickx</em> will
+still wait for all instances of <em>loop</em> to terminate before
+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> 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>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> You can start <em>loop...</em> with "import <em>variable</em> unexport <em>variable</em>"
+to perform variable substitution.
+</ul>
+ 
+</body>
+</html>
diff --git a/doc/foreground.html b/doc/foreground.html
new file mode 100644
index 0000000..a2a465f
--- /dev/null
+++ b/doc/foreground.html
@@ -0,0 +1,57 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the foreground command</title>
+  <meta name="Description" content="execline: the foreground command" />
+  <meta name="Keywords" content="execline command foreground" />
+  <!-- <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> The <tt>foreground</tt> program </h1>
+
+<p>
+<tt>foreground</tt> executes a sequence of commands.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     foreground { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <li> <tt>foreground</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> <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>
+ <li> <tt>foreground</tt> then execs into <em>prog2...</em>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>foreground</tt> is the basic sequence operator: it takes two
+commands and executes them one by one. execline scripts require it to
+wrap external commands that exit instead of natively supporting the
+"perform some action, then execute some other program" model. </li>
+ <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>
+</ul>
+
+</body>
+</html>
diff --git a/doc/forx.html b/doc/forx.html
new file mode 100644
index 0000000..86729b8
--- /dev/null
+++ b/doc/forx.html
@@ -0,0 +1,66 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the forx command</title>
+  <meta name="Description" content="execline: the forx command" />
+  <meta name="Keywords" content="execline command forx" />
+  <!-- <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> The <tt>forx</tt> program </h1>
+
+<p>
+<tt>forx</tt> runs a loop.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     forx [ -p | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em>
+</pre>
+
+<ul>
+ <li> <tt>forx</tt> reads a
+<a href="el_semicolon.html">block</a> and unquotes it.
+That block contains a list of <em>args</em>. </li>
+ <li> For each argument <em>x</em> in <em>args...</em>,
+<tt>forx</tt> runs <em>loop</em> as a child process, with
+<em>variable</em>=<em>x</em> added to its environment. </li>
+ <li> <tt>forx</tt> then exits 0. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-p</tt>&nbsp;: run in parallel. Do not wait for an instance of
+<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
+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>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> You can start <em>loop</em> with "import <em>variable</em> unexport <em>variable</em>"
+if you want variable substitution. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/getpid.html b/doc/getpid.html
new file mode 100644
index 0000000..fb60c7c
--- /dev/null
+++ b/doc/getpid.html
@@ -0,0 +1,44 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the getpid program</title>
+    <meta name="Description" content="execline: the getpid program" />
+    <meta name="Keywords" content="execline command getpid process id variable" />
+    <!-- <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> The <tt>getpid</tt> program </h1>
+
+<p>
+<tt>getpid</tt> stores its process ID in a given environment variable,
+then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     getpid <em>var</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>getpid</tt> stores its PID in the <em>var</em> variable, then
+execs into <em>prog</em> with its arguments.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <em>var</em> must be given without a dollar&nbsp;! </li>
+ <li> <em>var</em> must not contain <tt>=</tt>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/grammar.html b/doc/grammar.html
new file mode 100644
index 0000000..6c26dbd
--- /dev/null
+++ b/doc/grammar.html
@@ -0,0 +1,160 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: language design and grammar</title>
+    <meta name="Description" content="execline: language design and grammar" />
+    <meta name="Keywords" content="execline language design grammar script shell" />
+    <!-- <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> The <tt>execline</tt> language design and grammar </h1>
+
+<a name="principles" />
+<h2> <tt>execline</tt> principles </h2>
+
+<p>
+ Here are some basic Unix facts:
+</p>
+
+<ul>
+ <li> Unix programs are started with the <tt>execve()</tt>
+system call, which takes 3 arguments: the command name (which
+we won't discuss here because it's redundant in most cases),
+the command line <em>argv</em>, which specifies the program name and its
+arguments, and the environment <em>envp</em>. </li>
+ <li> The <em>argv</em> structure makes it easy to read some
+arguments at the beginning of <em>argv</em>, perform some action,
+then <tt>execve()</tt> into the rest of <em>argv</em>. For
+instance, the <tt>nice</tt> command works that way:
+<pre> nice -10 echo blah </pre> will read <tt>nice</tt> and <tt>-10</tt>
+from the argv, change the process' <em>nice</em> value, then exec into
+the command <tt>echo blah</tt>. This is called
+<a href"http://en.wikipedia.org/wiki/Chain_loading">chain loading</a>
+by some people, and <a href="http://www.faqs.org/docs/artu/ch07s02.html">
+Bernstein chaining</a> by others. </li>
+ <li> The purpose of the environment is to preserve some state across
+<tt>execve()</tt> calls. This state is usually small: most programs
+keep their information in the filesystem. </li>
+ <li> A <em>script</em> is basically a text file whose meaning is a
+sequence of actions, i.e. calls to Unix programs, with some control
+over the execution flow. You need a program to interpret your script.
+Traditionally, this program is <tt>/bin/sh</tt>: scripts are written
+in the <em>shell</em> language. </li>
+ <li> The shell reads and interprets the script command after command.
+That means it must preserve a state, and stay in memory while the
+script is running. </li>
+ <li> Standard shells have lots of built-in features and commands, so
+they are big. Spawning (i.e. <tt>fork()</tt>ing then <tt>exec()</tt>ing)
+a shell script takes time, because the shell program itself must be
+initialized. For simple programs like <tt>nice -10 echo blah</tt>,
+a shell is overpowered - we only need a way to make an <em>argv</em>
+from the "<tt>nice -10 echo blah</tt>" string, and <tt>execve()</tt>
+into that <em>argv</em>. </li>
+ <li> Unix systems have a size limit for <em>argv</em>+<em>envp</em>,
+but it is high. POSIX states that this limit must not be inferior to
+4&nbsp;KB - and most simple scripts are smaller than that. Modern systems
+have a much higher limit: for instance, it is 64&nbsp;KB on FreeBSD-4.6,
+and 128&nbsp;KB on Linux. </li>
+</ul>
+
+<p>
+ Knowing that, and wanting lightweight and efficient scripts, I
+wondered: "Why should the interpreter stay in memory while the script
+is executing&nbsp;? Why not parse the script once and for all, put
+it all into one <em>argv</em>, and just execute into that <em>argv</em>,
+relying on external commands (which will be called from within the
+script) to control the execution flow&nbsp;?"
+</p>
+
+<p> <tt>execline</tt> was born. </p>
+
+<ul>
+ <li> <tt>execline</tt> is the first script language to rely
+<em>entirely</em> on chain loading. An execline script is a
+single <em>argv</em>, made of a chain of programs designed to
+perform their action then <tt>exec()</tt> into the next one. </li>
+ <li> The <a href="execlineb.html">execlineb</a> command is a
+<em>launcher</em>: it reads and parses a text file, converting it
+to an <em>argv</em>, then executes into that <em>argv</em>. It
+does nothing more. </li>
+ <li> Straightforward scripts like <tt>nice -10 echo blah</tt>
+will be run just as they are, without the shell overhead.
+Here is what the script could look like:
+<pre>
+#!/command/execlineb -P
+nice -10
+echo blah
+</pre>
+ </li>
+ <li> More complex scripts will include calls to other <tt>execline</tt>
+commands, which are meant to provide some control over the process state
+and execution flow from inside an <em>argv</em>. </li>
+</ul>
+
+<a name="grammar" />
+<h2> Grammar of an execline script </h2>
+
+<p>
+An execline script can be parsed as follows:
+</p>
+
+<pre>
+ &lt;instruction&gt; = &lt;&gt; | external options &lt;arglist&gt; &lt;instruction&gt; | builtin options &lt;arglist&gt; &lt;blocklist&gt; &lt;instruction&gt;
+ &lt;arglist&gt; = &lt;&gt; | arg &lt;arglist&gt;
+ &lt;blocklist&gt; = &lt;&gt; | &lt;block&gt; &lt;blocklist&gt;
+ &lt;block&gt; = { &lt;arglist&gt; } | { &lt;instrlist&gt; }
+ &lt;instrlist&gt; = &lt;&gt; | &lt;instruction&gt; &lt;instrlist&gt;
+</pre>
+
+<p>
+(This grammar is ambivalent, but much simpler to understand than the
+non-ambivalent ones.)
+</p>
+
+<ul>
+ <li> An execline script is valid if it reduces to an
+<em>instruction</em>. </li>
+ <li> The empty <em>instruction</em> is the same as the <tt>true</tt>
+command: when an execline component must exec into the empty
+instruction, it exits 0. </li>
+ <li> Basically, every non-empty <em>instruction</em>, be it
+"<em>builtin</em>" - an execline command - or "<em>external</em>"
+- a program such as <tt>echo</tt> or <tt>cp</tt> - takes a number of
+arguments, the <em>arglist</em>, then executes into a (possibly empty)
+<em>instruction</em>. </li>
+ <li> Some <em>builtin</em>s are special because they also take a
+non-empty <em>blocklist</em> after their <em>arglist</em>. For instance,
+the <a href="foreground.html">foreground</a> command takes an empty
+<em>arglist</em> and one <em>block</em>: <pre>
+ #!/command/execlineb -P
+ foreground { sleep 1 } echo blah
+</pre> is a valid <a href="execlineb.html">execlineb</a> script.
+The <a href="foreground.html">foreground</a> command uses the
+<tt>sleep&nbsp;1</tt> <em>block</em> then execs into the
+remaining <tt>echo&nbsp;blah</tt> <em>instruction</em>. </li>
+</ul>
+
+<a name="features"></a>
+<h2> execline features </h2>
+
+<p>
+ <tt>execline</tt> commands can perform some transformations on
+their <em>argv</em>, to emulate some aspects of a shell. Here are
+descriptions of these features:
+</p>
+
+<ul>
+ <li> <a href="el_semicolon.html">Block management</a> </li>
+ <li> <a href="el_substitute.html">Variable substitution</a> </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/heredoc.html b/doc/heredoc.html
new file mode 100644
index 0000000..f49f880
--- /dev/null
+++ b/doc/heredoc.html
@@ -0,0 +1,56 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the heredoc program</title>
+    <meta name="Description" content="execline: the heredoc program" />
+    <meta name="Keywords" content="execline command heredoc here document" />
+    <!-- <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> The <tt>heredoc</tt> program </h1>
+
+<p>
+<tt>heredoc</tt> runs a command with a certain string fed to a
+file descriptor.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     heredoc [ -d ] <em>fd</em> <em>string</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>heredoc</tt> execs into <em>prog...</em> with
+<em>string</em> available on the <em>fd</em> file
+descriptor. </li>
+ <li> <em>string</em> must not contain a null character. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-d</tt>&nbsp;: run the process feeding <em>string</em> to <em>fd</em>
+as a grandchild of <tt>heredoc</tt>. This is meant to prevent a zombie
+from hanging around if <em>prog...</em> has read <em>string</em> and fails
+to wait for its children.</li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>heredoc</tt> is meant to be used in place of the shell
+<tt>&lt;&lt;</tt> construct, which includes <em>here-documents</em>
+into scripts. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/homeof.html b/doc/homeof.html
new file mode 100644
index 0000000..31f2a40
--- /dev/null
+++ b/doc/homeof.html
@@ -0,0 +1,37 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the homeof program</title>
+    <meta name="Description" content="execline: the homeof program" />
+    <meta name="Keywords" content="execline command homeof" />
+    <!-- <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> The <tt>homeof</tt> program </h1>
+
+<p>
+<tt>homeof</tt> prints the home directory of a user.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     homeof <em>user</em>
+</pre>
+
+<p>
+<tt>homeof</tt> finds the name of <em>user</em>'s home directory, writes
+it on stdout, then exits 0. If an error occurs, it prints nothing on
+stdout but exits 111 with an explanatory message on stderr.
+</p>
+
+</body>
+</html>
diff --git a/doc/if.html b/doc/if.html
new file mode 100644
index 0000000..2157a07
--- /dev/null
+++ b/doc/if.html
@@ -0,0 +1,68 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the if command</title>
+  <meta name="Description" content="execline: the if command" />
+  <meta name="Keywords" content="execline command if" />
+  <!-- <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> The <tt>if</tt> program </h1>
+
+<p>
+<tt>if</tt> performs conditional execution.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     if [ -X ] [ -n ] [ -t | -x <em>exitcode</em> ] { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <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> exits a non-zero status,
+<tt>if</tt> exits 1.</li>
+ <li> Else <tt>if</tt> execs into <em>prog2</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-X</tt>&nbsp;: treat a crash of <em>prog1</em> as a non-zero ("false") exit.
+ <li> <tt>-n</tt>&nbsp;: negate the test (exit on true, exec into <em>prog2</em> on false) </li>
+ <li> <tt>-x</tt>&nbsp;<em>exitcode</em>&nbsp;: exit <em>exitcode</em> instead of 1 if the test fails. </li>
+ <li> <tt>-t</tt>&nbsp;: exit 0 instead of 1 if the test fails.
+This is equivalent to <tt>-x 0</tt>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>if</tt> will exit if <em>prog1...</em> exits false. To use it in
+an execline script that must run <em>prog3...</em> no matter the result of
+the test, use a <tt>foreground</tt> wrapper:
+<pre> foreground { if { <em>prog1...</em> } <em>prog2...</em> } <em>prog3...</em> </pre>
+(in <a href="execlineb.html">execlineb</a> syntax) </li>
+ <li> <tt>if <em>prog1...</em> "" <em>prog2...</em></tt> is
+equivalent to <tt>sh -c '<em>prog1...</em> && exec <em>prog2...</em>'</tt>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/ifelse.html b/doc/ifelse.html
new file mode 100644
index 0000000..2298cf8
--- /dev/null
+++ b/doc/ifelse.html
@@ -0,0 +1,59 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the ifelse command</title>
+  <meta name="Description" content="execline: the ifelse command" />
+  <meta name="Keywords" content="execline command ifelse" />
+  <!-- <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://www.skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>ifelse</tt> program </h1>
+
+<p>
+ <tt>ifelse</tt> performs conditional execution, with two branches.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+<pre>
+     ifelse [ -X ] [ -n ] { <em>prog1...</em> } { <em>prog2...</em> } <em>prog3...</em>
+</pre>
+
+<ul>
+ <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> 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>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-n</tt>&nbsp;: negate the test. </li>
+ <li> <tt>-X</tt>&nbsp;: do not die if <em>prog1</em> crashes; treat a crash
+as a non-zero ("false") exit. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>ifelse <em>prog1...</em> "" <em>prog2...</em> "" <em>prog3...</em></tt> is
+roughly equivalent to <tt>sh -c '<em>prog1...</em> && exec <em>prog2...</em> || exec <em>prog3...</em>'</tt>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/ifte.html b/doc/ifte.html
new file mode 100644
index 0000000..40b0ec9
--- /dev/null
+++ b/doc/ifte.html
@@ -0,0 +1,67 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the ifte command</title>
+  <meta name="Description" content="execline: the ifte command" />
+  <meta name="Keywords" content="execline command ifte" />
+  <!-- <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> The <tt>ifte</tt> program </h1>
+
+<p>
+<tt>ifte</tt> performs a conditional alternative.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     ifte [ -X ] [ -n ] { <em>progthen...</em> } { <em>progelse...</em> } <em>progif...</em>
+</pre>
+
+<ul>
+ <li> <tt>ifte</tt> reads <em>progthen...</em> and <em>progelse...</em> in two
+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>
+ <li> If <em>progif...</em> exits zero, <tt>ifte</tt> execs into
+<em>progthen...</em>, else it execs into <em>progelse...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-X</tt>&nbsp;: do not exit if <em>progif</em> crashes; instead,
+proceed as if the test had returned false. </li>
+ <li> <tt>-n</tt>&nbsp;: negate the test. <em>progthen...</em> will be run
+iff <em>progif...</em> exits nonzero. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<p>
+ <tt>ifte</tt> is a simpler version of <a href="ifthenelse.html">ifthenelse</a>.
+It performs <em>only</em> conditional execution, not instruction sequence.
+</p>
+
+<p>
+"<tt>ifthenelse { progif } { progthen } { progelse } remainder</tt>" is the
+equivalent of "<tt>foreground { ifte { progthen } { progelse } progif } remainder</tt>".
+</p>
+
+</body>
+</html>
diff --git a/doc/ifthenelse.html b/doc/ifthenelse.html
new file mode 100644
index 0000000..3180412
--- /dev/null
+++ b/doc/ifthenelse.html
@@ -0,0 +1,59 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the ifthenelse command</title>
+  <meta name="Description" content="execline: the ifthenelse command" />
+  <meta name="Keywords" content="execline command ifthenelse" />
+  <!-- <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> The <tt>ifthenelse</tt> program </h1>
+
+<p>
+<tt>ifthenelse</tt> performs a conditional alternative.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     ifthenelse [ -X ] [ -s ] { <em>progif...</em> } { <em>progthen...</em> } { <em>progelse...</em> } <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>ifthenelse</tt> reads
+<em>progif...</em>, <em>progthen...</em> and <em>progelse...</em> in 3
+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>
+ <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
+status in the <tt>?</tt> environment variable. It then
+execs into <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-X</tt>&nbsp;: if <em>progif</em> crashes, do not exit; proceed
+as if it had returned false. </li>
+ <li> <tt>-s</tt>&nbsp;: magic scoping hack. This option does powerful but
+ugly things, and is left undocumented on purpose. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/import.html b/doc/import.html
new file mode 100644
index 0000000..1c6896c
--- /dev/null
+++ b/doc/import.html
@@ -0,0 +1,37 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the import program</title>
+    <meta name="Description" content="execline: the import program" />
+    <meta name="Keywords" content="execline command import environment variable" />
+    <!-- <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> The <tt>import</tt> program </h1>
+
+<p>
+<tt>import</tt> replaces an environment variable name with its value,
+then executes another program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     import [ -i | -D <em>default</em> ] [ -s ] [ -C | -c ] [ -n ] [ -d <em>delim</em> ] <em>envvar</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>import</tt> behaves exactly as
+<tt><a href="importas.html">importas</a> <em>envvar</em> <em>envvar</em></t>.
+</ul>
+
+</body>
+</html>
diff --git a/doc/importas.html b/doc/importas.html
new file mode 100644
index 0000000..a9c6f15
--- /dev/null
+++ b/doc/importas.html
@@ -0,0 +1,57 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the importas program</title>
+    <meta name="Description" content="execline: the importas program" />
+    <meta name="Keywords" content="execline command importas import environment variable" />
+    <!-- <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> The <tt>importas</tt> program </h1>
+
+<p>
+<tt>importas</tt> replaces a literal with the value of an
+environment variable, then executes another program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     importas [ -i | -D default ] [ -s ] [ -C | -c ] [ -n ] [ -d <em>delim</em> ] <em>variable</em> <em>envvar</em> <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>importas</tt> fetches the value of <em>envvar</em> in the
+environment. If neither the <em>-D</em> nor the <em>-i</em> option is given,
+and <em>envvar</em> is undefined, the <strong>null word</strong> is returned. </li>
+ <li> <tt>importas</tt> then performs
+<a href="el_substitute.html">variable substitution</a> on <em>prog...</em>,
+with <em>variable</em> as key and that string as value.
+ <li><tt>importas</tt> then execs into the modified <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-D</tt>&nbsp;<em>default</em>&nbsp;: If <em>envvar</em> is
+undefined, and this option is not given, substitute zero word for
+<em>variable</em> instead of the empty word; and if it is given,
+substitute <em>default</em> instead. To substitute the empty word,
+use <tt>-D&nbsp;""</tt>. </li>
+ <li> <tt>-i</tt>&nbsp;: Insist. If <em>envvar</em> is undefined,
+<tt>importas</tt> will not do anything; instead, it will exit 100 with an
+error message. This has precedence over any <tt>-D</tt> option. </li>
+ <li> Other options are used to <a href="el_transform.html">control
+the substitution mechanism</a>. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..682e935
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,213 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: a small scripting language</title>
+    <meta name="Description" content="execline: a small scripting language" />
+    <meta name="Keywords" content="execline script scripting language shell embedded chain loading bernstein chaining unix" />
+    <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> execline </h1>
+
+<h2> What is it&nbsp;? </h2>
+
+<p>
+ execline is a (non-interactive) scripting language, like <tt>sh</tt>&nbsp;;
+but its syntax is quite different from a traditional shell syntax.
+The <tt>execlineb</tt> program is meant to be used as an interpreter for a
+text file; the other commands are essentially useful inside an
+<tt>execlineb</tt> script.
+</p>
+
+<p>
+ execline is as powerful as a shell: it features
+<a href="loopwhilex.html">conditional loops</a>,
+<a href="elgetopt.html">getopt-style option handling</a>,
+<a href="elglob.html">filename globbing</a>, and more.
+ Meanwhile, its syntax is far more logic and predictable than the
+shell's syntax, and has no security issues.
+</p>
+
+<ul>
+<li> <a href="grammar.html">The execline design and grammar</a></li>
+<li> <a href="dieshdiedie.html">Why not just use <tt>/bin/sh</tt>&nbsp;?</a></li>
+</ul>
+
+<hr />
+
+<h2> Installation </h2>
+
+<h3> Requirements </h3>
+
+<ul>
+ <li> A POSIX-compliant system with a standard C development environment </li>
+ <li> GNU make, version 3.81 or later </li>
+ <li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version
+2.0.0.0 or later </li>
+</ul>
+
+<h3> Licensing </h3>
+
+<p>
+ execline is free software. It is available under the
+<a href="http://opensource.org/licenses/ISC">ISC license</a>.
+</p>
+
+<h3> Download </h3>
+
+<ul>
+ <li> The current execline version is <a href="execline-2.0.0.0.tar.gz">2.0.0.0</a>. </li>
+</ul>
+
+<h3> Compilation </h3>
+
+<ul>
+ <li> See the enclosed INSTALL file for installation details. </li>
+</ul>
+
+<h3> Upgrade notes </h3>
+
+<ul>
+ <li> <a href="upgrade.html">This page</a> lists the differences to be aware of between
+the previous versions of execline and the current one. </li>
+</ul>
+
+<hr />
+
+<h2> Special note </h2>
+
+<p>
+ Before version 2.0.0.0, execline used the slashpackage convention by default.
+ This is not the case anymore; nevertheless, the examples in this documentation
+still use <tt>#!/command/execlineb</tt> as their shebang line, and assume that
+the execline binaries are available in <tt>/command</tt>. Adapt them according
+to your installation: the shebang lines for your system might be something like
+<tt>#!/bin/execlineb</tt>, or <tt>#!/usr/bin/execlineb</tt>, or
+<tt>#!/usr/local/bin/execlineb</tt>, or something else entirely.
+</p>
+
+<hr />
+
+<h2> Reference </h2>
+<h3> Commands </h3>
+
+<p>
+ All these commands exit 111 if they encounter a temporary error, and
+100 if they encounter a permanent error - such as a misuse.
+</p>
+<p>
+ (Script parser / launcher)
+</p>
+<ul>
+<li><a href="execlineb.html">The <tt>execlineb</tt> program</a></li>
+</ul>
+<p>
+ (Process state control)
+</p>
+<ul>
+<li><a href="cd.html">The <tt>cd</tt> program</a></li>
+<li><a href="umask.html">The <tt>umask</tt> program</a></li>
+<li><a href="emptyenv.html">The <tt>emptyenv</tt> program</a></li>
+<li><a href="export.html">The <tt>export</tt> program</a></li>
+<li><a href="unexport.html">The <tt>unexport</tt> program</a></li>
+<li><a href="fdclose.html">The <tt>fdclose</tt> program</a></li>
+<li><a href="fdblock.html">The <tt>fdblock</tt> program</a></li>
+<li><a href="fdmove.html">The <tt>fdmove</tt> program</a></li>
+<li><a href="fdreserve.html">The <tt>fdreserve</tt> program</a></li>
+<li><a href="redirfd.html">The <tt>redirfd</tt> program</a></li>
+<li><a href="piperw.html">The <tt>piperw</tt> program</a></li>
+<li><a href="heredoc.html">The <tt>heredoc</tt> program</a></li>
+<li><a href="pipeline.html">The <tt>pipeline</tt> program</a></li>
+<li><a href="wait.html">The <tt>wait</tt> program</a></li>
+<li><a href="getpid.html">The <tt>getpid</tt> program</a></li>
+<li><a href="exec.html">The <tt>exec</tt> program</a></li>
+<li><a href="tryexec.html">The <tt>tryexec</tt> program</a></li>
+<li><a href="exit.html">The <tt>exit</tt> program</a></li>
+</ul>
+<p>
+ (<a href="el_semicolon.html">Basic block management</a>)
+</p>
+<ul>
+<li><a href="foreground.html">The <tt>foreground</tt> program</a></li>
+<li><a href="background.html">The <tt>background</tt> program</a></li>
+<li><a href="if.html">The <tt>if</tt> program</a></li>
+<li><a href="ifelse.html">The <tt>ifelse</tt> program</a></li>
+<li><a href="ifte.html">The <tt>ifte</tt> program</a></li>
+<li><a href="ifthenelse.html">The <tt>ifthenelse</tt> program</a></li>
+<li><a href="backtick.html">The <tt>backtick</tt> program</a></li>
+<li><a href="runblock.html">The <tt>runblock</tt> program</a></li>
+</ul>
+<p>
+ (<a href="el_substitute.html">Variable management</a>)
+</p>
+<ul>
+<li><a href="define.html">The <tt>define</tt> program</a></li>
+<li><a href="importas.html">The <tt>importas</tt> program</a></li>
+<li><a href="import.html">The <tt>import</tt> program</a></li>
+<li><a href="elglob.html">The <tt>elglob</tt> program</a></li>
+<li><a href="elgetpositionals.html">The <tt>elgetpositionals</tt> program</a></li>
+<li><a href="multidefine.html">The <tt>multidefine</tt> program</a></li>
+<li><a href="multisubstitute.html">The <tt>multisubstitute</tt> program</a></li>
+</ul>
+<p>
+ (Loops)
+</p>
+<ul>
+<li><a href="forx.html">The <tt>forx</tt> program</a></li>
+<li><a href="forbacktickx.html">The <tt>forbacktickx</tt> program</a></li>
+<li><a href="loopwhilex.html">The <tt>loopwhilex</tt> program</a></li>
+</ul>
+<p>
+ (Positional parameters and options management)
+</p>
+<ul>
+<li><a href="elgetopt.html">The <tt>elgetopt</tt> program</a></li>
+<li><a href="shift.html">The <tt>shift</tt> program</a></li>
+<li><a href="dollarat.html">The <tt>dollarat</tt> program</a></li>
+</ul>
+<p>
+ (Miscellaneous)
+</p>
+<ul>
+<li><a href="homeof.html">The <tt>homeof</tt> program</a></li>
+</ul>
+
+<h3> Provided scripts: example <tt>.profile</tt> replacement </h3>
+
+<ul>
+<li><a href="execline-shell.html">The <tt>execline-shell</tt> script</a></li>
+<li><a href="execline-startup.html">The <tt>execline-startup</tt> script</a></li>
+</ul>
+
+<h3> Fun stuff </h3>
+
+<ul>
+<li>An execline <a href="quine-jriou.txt">quine</a>. This was quinely provided by
+<a href="http://jriou.org/">Jo&euml;l Riou</a>. The only
+external command used is <tt>echo</tt>. </li>
+<li> Another <a href="quine-prj.txt">quine</a>, provided by
+<a href="http://code.dogmap.org/">Paul Jarc</a>. It is much shorter, but
+uses the external commands <tt>echo</tt> and <tt>env</tt>. Later, Paul rewrote
+it <a href="quine-prj-2.txt">using only <tt>echo</tt></a>, then
+<a href="quine-prj-3.txt">using only <tt>echo</tt> and the environment</a>. </li>
+<li> Another <a href="quine-dam.txt">quine</a>, provided by
+<a href="http://www.madore.org/~david/">David Madore</a>. It uses the
+external command <tt>printf</tt>. It is longer, but quite stylish. </li>
+</ul>
+
+<h2> Related resources </h2>
+
+<ul>
+ <li> <tt>execline</tt> is discussed on the
+<a href="http://skarnet.org/lists.html#skaware">skaware</a> mailing-list. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/loopwhilex.html b/doc/loopwhilex.html
new file mode 100644
index 0000000..9def60f
--- /dev/null
+++ b/doc/loopwhilex.html
@@ -0,0 +1,60 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the loopwhilex command</title>
+  <meta name="Description" content="execline: the loopwhilex command" />
+  <meta name="Keywords" content="execline command loopwhilex" />
+  <!-- <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> The <tt>loopwhilex</tt> program </h1>
+
+<p>
+<tt>loopwhilex</tt> performs a conditional loop.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     loopwhilex [ -n ] [ -x <em>exitcodes</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>
+</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 exit if <em>prog...</em>'s
+exit code is 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 is <em>not</em> listed in <em>breakcodes</em>). </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> 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
+child process. To avoid being stuck in an infinite loop, <em>prog...</em>
+should modify some external state - for instance, the filesystem. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/multidefine.html b/doc/multidefine.html
new file mode 100644
index 0000000..03f6b22
--- /dev/null
+++ b/doc/multidefine.html
@@ -0,0 +1,69 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the multidefine command</title>
+  <meta name="Description" content="execline: the multidefine command" />
+  <meta name="Keywords" content="execline command multidefine" />
+  <!-- <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> The <tt>multidefine</tt> program </h1>
+
+<p>
+<tt>multidefine</tt> splits a value and defines several variables at once,
+then executes another program.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     multidefine [ -0 ] [ -r ] [ -C | -c ] [ -n ] [ -d <em>delim</em> ] <em>value</em> { <em>variables...</em> } <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>multidefine</tt> reads a <a href="el_semicolon.html">block</a>
+containing a list of variables. </li>
+ <li> <tt>multidefine</tt> <a href="el_transform.html">splits</a>
+<em>value</em>, and performs other operations depending on the given
+options. </li>
+ <li> <tt>multidefine</tt> performs
+<a href="el_substitute.html">parallel substitution</a> on
+<em>prog...</em>, using all of the <em>variables</em> in the block as keys.
+The first word in the split <em>value</em> is assigned to the first
+<em>variable</em>, the second word is assigned to the second <em>variable</em>,
+and so on. Every <em>variable</em> is substituted with exactly one word. </li>
+ <li> If a <em>variable</em> is the empty word, then the word in the split
+<em>value</em> corresponding to its position is not substituted. So you can
+use empty words to pad the list of variables and only perform substition
+on the relevant fields. </li>
+ <li> <tt>multidefine</tt> then execs into the modified <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-0</tt>&nbsp;: if there are more <em>variables</em> in the block than
+there are words in the split <em>value</em>, the excess variables
+will be replaced with zero word. Without this option, the excess variables are
+replaced with the empty word. </li>
+ <li> <tt>-r</tt>&nbsp;: behave similarly to the "read" shell command.
+If there are more words in the split <em>value</em> than there are
+<em>variables</em> in the block, the last variable will be replaced with all
+the remaining words (and will be split). Without this option, the last variable
+is replaced with a single word, and the excess words are lost. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/multisubstitute.html b/doc/multisubstitute.html
new file mode 100644
index 0000000..6400187
--- /dev/null
+++ b/doc/multisubstitute.html
@@ -0,0 +1,121 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the multisubstitute command</title>
+  <meta name="Description" content="execline: the multisubstitute command" />
+  <meta name="Keywords" content="execline command multisubstitute" />
+  <!-- <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> The <tt>multisubstitute</tt> program </h1>
+
+<p>
+<tt>multisubstitute</tt> performs several substitutions at once in
+its <em>argv</em>, then executes another program.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     multisubstitute
+     {
+       [ <a href="define.html">define</a> [ -n ] [ -s ] [ -C | -c ] [ -d <em>delim</em> ] <em>variable</em> <em>value</em> ]
+       [ <a href="importas.html">importas</a> [ -i | -D <em>default</em> ] [ -n ] [ -s ] [ -C | -c ] [ -d <em>delim</em> ] <em>variable</em> <em>envvar</em> ]
+       [ <a href="import.html">import</a> [ -i | -D <em>default</em> ] [ -n ] [ -s ] [ -C | -c ] [ -d <em>delim</em> ] <em>envvar</em> ]
+       [ <a href="elglob.html">elglob</a> [ -v ] [ -w ] [ -s ] [ -m ] [ -e ] [ -0 ] <em>variable</em> <em>pattern</em> ]
+       [ <a href="elgetpositionals.html">elgetpositionals</a> [ -P <em>sharp</em> ] ]
+       [ <a href="multidefine.html">multidefine</a> <em>value</em> { <em>variable...</em> } ]
+       <em>...</em>
+     }
+     <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>multisubstitute</tt> reads a <a href="el_semicolon.html">block</a>
+containing a series of substitution commands. It performs all
+those <a href="el_substitute.html">substitutions</a> on
+<em>prog...</em> in parallel. Check the relevant documentation page
+to learn about the syntax of each substitution command. </li>
+ <li> <tt>multisubstitute</tt> then execs into the modified <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> If a <tt>backtick</tt> directive was given with the <tt>-i</tt> option,
+and <em>command</em> crashes or exits nonzero, <tt>multisubstitute</tt> will
+also exit with the same exit code. </li>
+ <li> If an <tt>import</tt> or <tt>importas</tt> directive was given with the
+<tt>-i</tt> option, and the looked up variable is undefined,
+<tt>multisubstitute</tt> will exit 100. </li>
+</ul>
+
+<h2> Rationale </h2>
+
+<h3> Security </h3>
+
+<p>
+ <tt>multisubstitute</tt> can be used to avoid unwanted
+<em>serial substitutions</em>. Consider the following script:
+</p>
+
+<pre>
+ #!/command/execlineb
+ export A wrong
+ define B ${A}
+ import A
+ echo ${B}
+</pre>
+
+<p>
+ Running it will print <tt>wrong</tt>, because <tt>A</tt> is substituted
+<em>after</em> B. On the contrary, the following script:
+</p>
+
+<pre>
+ #!/command/execlineb
+ export A wrong
+ multisubstitute
+ {
+   define B ${A}
+   import A
+ }
+ echo ${B}
+</pre>
+
+<p>
+ will print <tt>${A}</tt>, because A and B are substituted at the same
+time. Serial substitution may be what you want - but when in doubt,
+always perform parallel substitution.
+</p>
+
+<h3> Efficiency </h3>
+
+<p>
+<a href="el_substitute.html">Substitution</a> is a costly mechanism:
+the whole <em>argv</em> is read three times and rewritten twice.
+Serial substitution multiplies the cost by the number of
+substitutions, whereas parallel substitution pays the price only once.
+</p>
+
+<h2> Credits </h2>
+
+<p>
+<a href="http://code.dogmap.org/">Paul Jarc</a> first originated the
+idea of the <tt>multisubstitute</tt> command and a possible syntax.
+</p>
+
+</body>
+</html>
diff --git a/doc/pipeline.html b/doc/pipeline.html
new file mode 100644
index 0000000..4f6677f
--- /dev/null
+++ b/doc/pipeline.html
@@ -0,0 +1,67 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the pipeline command</title>
+  <meta name="Description" content="execline: the pipeline command" />
+  <meta name="Keywords" content="execline command pipeline" />
+  <!-- <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> The <tt>pipeline</tt> program </h1>
+
+<p>
+<tt>pipeline</tt> runs two commands with a pipe between them.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     pipeline [ -d ] [ -r | -w ] { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <li> <tt>pipeline</tt> reads <em>prog1...</em> in a
+<a href="el_semicolon.html">block</a> and unquotes it. </li>
+ <li> It runs <em>prog1...</em> as a child process and execs into
+<em>prog2...</em>, with a pipe between <em>prog1</em>'s stdout and
+<em>prog2</em>'s stdin. </li>
+ <li> <em>prog1</em>'s pid is available in <em>prog2</em> as the !
+environment variable. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-d</tt>&nbsp;: run <em>prog1...</em>
+as a grandchild of <tt>pipeline</tt>. This is meant to prevent a zombie
+from hanging around if <em>prog2...</em> fails to wait for its children.</li>
+ <li> <tt>-r</tt>&nbsp;: make <em>prog1...</em> the writer and
+<em>prog2...</em> the reader. This is the default. </li>
+ <li> <tt>-w</tt>&nbsp;: make <em>prog1...</em> the reader and
+<em>prog2...</em> the writer. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> You can easily create a chain of pipes: <tt>pipeline a "" pipeline b "" c</tt>
+is roughly equivalent to
+<tt>sh -c 'exec a | b | c'</tt>, except that shells usually run <tt>c</tt>
+as a child process like <tt>a</tt> and <tt>b</tt>, and <tt>exec</tt> has no
+effect. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/piperw.html b/doc/piperw.html
new file mode 100644
index 0000000..64b9477
--- /dev/null
+++ b/doc/piperw.html
@@ -0,0 +1,38 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the piperw command</title>
+  <meta name="Description" content="execline: the piperw command" />
+  <meta name="Keywords" content="execline command piperw" />
+  <!-- <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> The <tt>piperw</tt> program </h1>
+
+<p>
+<tt>piperw</tt> creates a pipe (an anonymous one), then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     piperw <em>fdr</em> <em>fdw</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>piperw</tt> creates a pipe with descriptor <em>fdw</em> as the
+writing end and descriptor <em>fdr</em> as the reading end.
+It then execs into <em>prog</em> with its arguments.
+</p>
+
+</body>
+</html>
diff --git a/doc/quine-dam.txt b/doc/quine-dam.txt
new file mode 100644
index 0000000..c69a52c
--- /dev/null
+++ b/doc/quine-dam.txt
@@ -0,0 +1,110 @@
+#! /command/execlineb -P
+# Public Domain.
+# See comments below.
+# (Search for "HERE".)
+#
+define -sCd "\n" lns "
+${p} ${bubble} is the end of the quine's data.
+${p} They represent the following code, with various quotations:
+${p} ${b} (backslash) is represented as ${d}${ob}b${cb}
+${p} ${q} (double quote) is represented as ${d}${ob}q${cb}
+${p} ${p} (sharp/pound/shibboleth/whatever) is represented as ${d}${ob}p${cb}
+${p} ${ob} (open brace) is represented as ${d}${ob}ob${cb}
+${p} ${cb} (closed brace) is represented as ${d}${ob}cb${cb}
+${p} ${d} (dollar) is represented as ${d}${ob}d${cb}
+${p} ${bubble} (the magic word) is represented as ${d}${ob}bubble${cb}
+${p} (The point of the magic word is to allow the reader
+${p} to conveniently skip over the large data section.)
+${p}
+${p} Now we have the quine's code!
+${p}
+${p} First, print the lines that come before the data.
+foreground ${ob} printf %s ${b}${p}${b}!${q} ${q} ${cb}
+foreground ${ob} printf %s${b}${b}n ${q}/command/execlineb -P${q} ${cb}
+foreground ${ob} printf %s${b}${b}n ${b}${p}${q} Public Domain.${q} ${cb}
+foreground ${ob} printf %s${b}${b}n ${b}${p}${q} See comments below.${q} ${cb}
+foreground ${ob} printf %s ${b}${p}${q} (Search for ${q} ${cb}
+foreground ${ob} printf %s${b}${b}n ${b}${q}${bubble}${b}${q}.) ${cb}
+foreground ${ob} printf %s${b}${b}n ${b}${p} ${cb}
+foreground ${ob} printf %s ${q}define -sCd ${b}${q}${b}${b}n${b}${q} lns ${b}${q}${q} ${cb}
+${p} Next, print the data themselves, as data.
+for lin ${ob} ${d}${ob}lns${cb} ${cb} ${ob}
+multisubstitute ${ob}
+define b ${d}${ob}b${cb}
+define q ${d}${ob}q${cb}
+define p ${d}${ob}p${cb}
+define ob ${d}${ob}ob${cb}
+define cb ${d}${ob}cb${cb}
+define d ${d}${ob}d${cb}
+define bubble ${d}${ob}bubble${cb}
+define intron ${d}${ob}intron${cb}
+${cb} printf ${b}${b}n%s ${d}${ob}lin${cb} ${cb}
+foreground ${ob} printf %s${b}${b}n ${b}${q} ${cb}
+${p} Finally, use the data to print the code!
+for lin ${ob} ${d}${ob}lns${cb} ${cb} ${ob}
+multisubstitute ${ob}
+define b ${b}${b}
+define q ${b}${q}
+define p ${b}${p}
+define ob ${b}${ob}
+define cb ${b}${cb}
+define d ${d}
+define bubble ${bubble}
+define intron ${q}${intron}${q}
+${cb} printf %s${b}${b}n ${d}${ob}lin${cb} ${cb}
+${p} That's all, folks! - Well, that wasn't so hard, was it?
+${p} (This quine was written by <david.madore@ens.fr> - see
+${p} <URL: http://www.eleves.ens.fr:8080/home/madore/computers/quine.html >
+${p} for more information on quines and how to write them.)"
+# HERE is the end of the quine's data.
+# They represent the following code, with various quotations:
+# \ (backslash) is represented as ${b}
+# " (double quote) is represented as ${q}
+# # (sharp/pound/shibboleth/whatever) is represented as ${p}
+# { (open brace) is represented as ${ob}
+# } (closed brace) is represented as ${cb}
+# $ (dollar) is represented as ${d}
+# HERE (the magic word) is represented as ${bubble}
+# (The point of the magic word is to allow the reader
+# to conveniently skip over the large data section.)
+#
+# Now we have the quine's code!
+#
+# First, print the lines that come before the data.
+foreground { printf %s \#\!" " }
+foreground { printf %s\\n "/command/execlineb -P" }
+foreground { printf %s\\n \#" Public Domain." }
+foreground { printf %s\\n \#" See comments below." }
+foreground { printf %s \#" (Search for " }
+foreground { printf %s\\n \"HERE\".) }
+foreground { printf %s\\n \# }
+foreground { printf %s "define -sCd \"\\n\" lns \"" }
+# Next, print the data themselves, as data.
+for lin { ${lns} } {
+multisubstitute {
+define b ${b}
+define q ${q}
+define p ${p}
+define ob ${ob}
+define cb ${cb}
+define d ${d}
+define bubble ${bubble}
+define intron ${intron}
+} printf \\n%s ${lin} }
+foreground { printf %s\\n \" }
+# Finally, use the data to print the code!
+for lin { ${lns} } {
+multisubstitute {
+define b \\
+define q \"
+define p \#
+define ob \{
+define cb \}
+define d $
+define bubble HERE
+define intron "NOTICE HOW THIS SENTENCE APPEARS ONLY ONCE IN THIS QUINE?"
+} printf %s\\n ${lin} }
+# That's all, folks! - Well, that wasn't so hard, was it?
+# (This quine was written by <david.madore@ens.fr> - see
+# <URL: http://www.eleves.ens.fr:8080/home/madore/computers/quine.html >
+# for more information on quines and how to write them.)
diff --git a/doc/quine-jriou.txt b/doc/quine-jriou.txt
new file mode 100644
index 0000000..f8e5455
--- /dev/null
+++ b/doc/quine-jriou.txt
@@ -0,0 +1,28 @@
+#!/command/execlineb
+define A "#!/command/execlineb"
+define B "fine G $ foreground { echo ${C} }
+echo -n foreground ${D} define C ${E}${C}${R}foreground
+${D} echo ${G}${D}A${H} ${H}${R}foreground
+${D} echo define A ${G}${D}C${H}${G}${D}A${H}${G}${D}C${H} ${H}${R}echo
+-n define B ${G}${D}C${H} ${H}${R}foreground
+${D} echo -n ${G}${D}B${H} ${H}${R}foreground
+${D} multisubstitute ${D} define C ${E}${C} define D ${E}${D}${R}define
+E ${E}${E}${R}define
+H ${E}${H} define R ${C}${R}${C} ${H} de } echo ${B}"
+foreground { define C \"
+foreground { echo ${A} }
+foreground { echo define A ${C}${A}${C} }
+echo -n define B ${C} }
+foreground { echo -n ${B} }
+foreground { multisubstitute { define C \" define D \{
+define E \\
+define H \} define R "
+" } define G $ foreground { echo ${C} }
+echo -n foreground ${D} define C ${E}${C}${R}foreground
+${D} echo ${G}${D}A${H} ${H}${R}foreground
+${D} echo define A ${G}${D}C${H}${G}${D}A${H}${G}${D}C${H} ${H}${R}echo
+-n define B ${G}${D}C${H} ${H}${R}foreground
+${D} echo -n ${G}${D}B${H} ${H}${R}foreground
+${D} multisubstitute ${D} define C ${E}${C} define D ${E}${D}${R}define
+E ${E}${E}${R}define
+H ${E}${H} define R ${C}${R}${C} ${H} de } echo ${B}
diff --git a/doc/quine-prj-2.txt b/doc/quine-prj-2.txt
new file mode 100644
index 0000000..9c60b92
--- /dev/null
+++ b/doc/quine-prj-2.txt
@@ -0,0 +1,15 @@
+#!/command/execlineb
+define e "#!/command/execlineb
+define e ${q}${E}${q}
+multisubstitute {
+define q ${b}${q}
+define b ${b}${b}
+define E $e
+}
+echo $e"
+multisubstitute {
+define q \"
+define b \\
+define E $e
+}
+echo $e
diff --git a/doc/quine-prj-3.txt b/doc/quine-prj-3.txt
new file mode 100644
index 0000000..e5b5708
--- /dev/null
+++ b/doc/quine-prj-3.txt
@@ -0,0 +1,13 @@
+#!/command/execlineb -P
+define e "#!/command/execlineb -P
+define e ${q}${E}${q}
+export E $e
+define q ${b}${q}
+define b ${b}${b}
+import E
+echo $e"
+export E $e
+define q \"
+define b \\
+import E
+echo $e
diff --git a/doc/quine-prj.txt b/doc/quine-prj.txt
new file mode 100644
index 0000000..8d2643f
--- /dev/null
+++ b/doc/quine-prj.txt
@@ -0,0 +1,13 @@
+#!/command/execlineb
+define e "#!/command/execlineb
+define e $q${E}${q}
+env e=$e
+define q ${b}${q}
+define b ${b}${b}
+importas E e
+echo $e"
+env e=$e
+define q \"
+define b \\
+importas E e
+echo $e
diff --git a/doc/redirfd.html b/doc/redirfd.html
new file mode 100644
index 0000000..fd29ef4
--- /dev/null
+++ b/doc/redirfd.html
@@ -0,0 +1,100 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the redirfd command</title>
+  <meta name="Description" content="execline: the redirfd command" />
+  <meta name="Keywords" content="execline command redirfd" />
+  <!-- <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> The <tt>redirfd</tt> program </h1>
+
+<p>
+<tt>redirfd</tt> redirects a given file descriptor to a file, then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     redirfd [ -r | -w | -u | -a | -c | -x ] [ -n | -b ] <em>fd</em> <em>file</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>redirfd</tt> redirects the file descriptor number <em>fd</em>
+to <em>file</em>, then execs into <em>prog...</em>.
+</p>
+
+<h2> Options </h2>
+
+<p>
+ One and only one of the -r, -w, -u, -a, -c, or -x options must be given;
+the -n and -b options may be added in any case.
+</p>
+
+<ul>
+ <li> <tt>-r</tt>&nbsp;: open <em>file</em> for reading. </li>
+ <li> <tt>-w</tt>&nbsp;: open <em>file</em> for writing, truncating it if it already exists. </li>
+ <li> <tt>-u</tt>&nbsp;: open <em>file</em> for reading and writing. </li>
+ <li> <tt>-a</tt>&nbsp;: open <em>file</em> for appending, creating it if it doesn't exist. </li>
+ <li> <tt>-c</tt>&nbsp;: open <em>file</em> for appending. Do not create it if it doesn't exist. </li>
+ <li> <tt>-x</tt>&nbsp;: open <em>file</em> for writing, creating it, failing if it already exists. </li>
+ <li> <tt>-n</tt>&nbsp;: open <em>file</em> in non-blocking mode. </li>
+ <li> <tt>-b</tt>&nbsp;: change mode of <em>file</em> after opening it:
+to non-blocking mode if the <tt>-n</tt> option was not given,
+to blocking mode if it was. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>redirfd -r <em>n</em> <em>file</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>n</em>&lt;<em>file</em>'</tt></li>
+ <li> <tt>redirfd -w <em>n</em> <em>file</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>n</em>&gt;<em>file</em>'</tt></li>
+ <li> <tt>redirfd -u <em>n</em> <em>file</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>n</em>&lt;&gt;<em>file</em>'</tt></li>
+ <li> <tt>redirfd -a <em>n</em> <em>file</em> prog...</tt> is roughly equivalent to
+<tt>sh -c 'exec prog... <em>n</em>&gt;&gt;<em>file</em>'</tt></li>
+ <li> <tt>redirfd -c <em>n</em> <em>file</em> prog...</tt> has no portable
+shell equivalent. Some shells provide the <em>noclobber</em> option for
+a similar feature. </li>
+ <li> <tt>redirfd -x <em>n</em> <em>file</em> prog...</tt> has no portable
+shell equivalent.</tt> </li>
+</ul>
+
+<h2> Special fifo handling </h2>
+
+<p>
+ The <tt>-n</tt> and <tt>-b</tt> options are especially useful with
+named pipes. 
+</p>
+
+<ul>
+ <li> Opening a fifo for reading, blocking if there is no writer:
+<tt>redirfd -r <em>n</em> <em>fifo</em> prog...</tt></li>
+ <li> Opening a fifo for reading, with instant success even if
+there is no writer, and blocking at the first attempt to read from it:
+<tt>redirfd -r -nb <em>n</em> <em>fifo</em> prog...</tt></li>
+ <li> Opening a fifo for writing, blocking if there is no reader:
+<tt>redirfd -w <em>n</em> <em>fifo</em> prog...</tt></li>
+ <li> Opening a fifo for writing, with instant success even if
+there is no reader:
+<tt>redirfd -w -nb <em>n</em> <em>fifo</em> prog...</tt>. Warning:
+the first attempt to write to the fifo will raise a SIGPIPE if there is
+still no reader at that time. The named pipe semantics normally do not
+allow a fifo to be open for writing without a reading end, and you
+should know what you are doing if you're using <tt>redirfd</tt>
+this way. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/runblock.html b/doc/runblock.html
new file mode 100644
index 0000000..6f5386e
--- /dev/null
+++ b/doc/runblock.html
@@ -0,0 +1,75 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the runblock program</title>
+    <meta name="Description" content="execline: the runblock program" />
+    <meta name="Keywords" content="execline command runblock" />
+    <!-- <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/">www.skarnet.org</a>
+</p>
+
+<h1> The <tt>runblock</tt> program </h1>
+
+<p>
+<tt>runblock</tt>'s purpose is to help you write execline commands
+in the execline language. It can only be used inside an execline
+script. If the script has been given blocks as arguments, <tt>runblock</tt>
+allows you to execute one of the blocks individually.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     runblock [ -P ] [ -n <em>argshift</em> ] [ -r ] <em>n</em>
+</pre>
+
+<ul>
+ <li> <tt>runblock</tt> skips the first <em>argshift</em> positional
+parameters. It does that to allow you to design commands that take simple
+arguments <em>and</em> blocks. </li>
+ <li> Then <tt>runblock</tt> looks for and parses
+<a href="el_semicolon.html">blocks</a> in the positional parameters. </li>
+ <li> If the <tt>-r</tt> option is present: <tt>runblock</tt> skips
+<em>n</em> blocks and execs into the remaining arguments. </li>
+ <li> Else it skips <em>n</em>-1 blocks and execs into the <em>n</em>th
+one. </li>
+ <li> Normally <tt>runblock</tt> <a href="el_pushenv.html#pop">pops</a>
+its environment frame before executing. If the <tt>-P</tt> option has
+been given, it <em>does not</em> pop. </li>
+ <li> Of course, if the block structure doesn't match, <tt>runblock</tt>
+exits 100 with an error message. </li>
+</ul>
+
+<h2> Example: implementing the <a href="ifelse.html">ifelse</a> command </h2>
+
+<p>
+ Suppose that we want to implement the <a href="ifelse.html">ifelse</a> command as
+an execline script, using the <a href="ifte.html">ifte</a> command.
+<tt>runblock</tt> allows us to do it in a simple way:
+</p>
+
+<pre>
+ #!/command/execlineb
+ ifte { runblock 2 } { runblock -r 2 } runblock 1
+</pre>
+
+<p>
+ That's it.
+</p>
+
+<h2> Credits </h2>
+
+<p>
+ The <tt>runblock</tt> idea, as well as the <tt>ifelse</tt> idea, comes
+from <a href="http://code.dogmap.org/">Paul Jarc</a>.
+</p>
+
+</body>
+</html>
diff --git a/doc/shift.html b/doc/shift.html
new file mode 100644
index 0000000..775e472
--- /dev/null
+++ b/doc/shift.html
@@ -0,0 +1,68 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: the shift program</title>
+    <meta name="Description" content="execline: the shift program" />
+    <meta name="Keywords" content="execline command shift" />
+    <!-- <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/">www.skarnet.org</a>
+</p>
+
+<h1> The <tt>shift</tt> program </h1>
+
+<p>
+<tt>shift</tt> shifts the positional parameters of an execline script.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     shift [ -n <em>argn</em> ] [ -b <em>blockn</em> ] <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>shift</tt> shifts <em>argn</em> positional parameters,
+then <em>blockn</em> blocks. It then execs <em>prog...</em>. </li>
+ <li> By default, <em>argn</em> and <em>blockn</em> are both zero;
+but if neither the <tt>-n</tt> nor the <tt>-b</tt> option is given,
+then <em>argn</em> is 1 and <em>blockn</em> is 0. </li>
+</ul>
+
+<h2> Details </h2>
+
+<ul>
+ <li> <tt>shift</tt> reads the number of "positional parameters" in the
+<tt>#</tt> environment variable. Let <em>n</em> be that number. </li>
+ <li> If the <tt>#</tt> environment variable is not set or does not
+contain a valid number, or one of the <tt>0</tt>, <tt>1</tt>, ...,
+<tt><em>n</em></tt> environment variables is not set, <tt>shift</tt>
+exits 100 with an error message. </li>
+ <li> <tt>shift</tt> calculates a shift value <em>m</em>, corresponding
+to <em>argn</em> arguments followed by enough arguments to make
+<em>blockn</em> blocks. </li>
+ <li> It shifts the positional parameters <em>m</em> times: the
+value of the <tt><em>m</em>+1</tt> variable becomes the value of the
+<tt>1</tt> variable, <tt><em>m</em>+2</tt> becomes <tt>2</tt> and so on,
+and <tt>#</tt> is set to <em>n</em>-<em>m</em> (floored at zero). </li>
+ <li> <tt>shift</tt> then execs into <em>prog...</em>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>shift</tt> is a standard shell builtin. Be careful if you
+want to use it outside of an execline script. </li>
+ <li> The <tt>-b</tt> option is only useful to implement execline
+commands in the execline language. You shouldn't normally have to
+use it. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/tryexec.html b/doc/tryexec.html
new file mode 100644
index 0000000..2fcc7b6
--- /dev/null
+++ b/doc/tryexec.html
@@ -0,0 +1,67 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the tryexec command</title>
+  <meta name="Description" content="execline: the tryexec command" />
+  <meta name="Keywords" content="execline command tryexec" />
+  <!-- <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> The <tt>tryexec</tt> program </h1>
+
+<p>
+<tt>tryexec</tt> executes into a command line, with a fallback.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     tryexec [ -n ] [ -c ] [ -l ] [ -a argv0 ] { <em>prog1...</em> } <em>prog2...</em>
+</pre>
+
+<ul>
+ <li> <tt>tryexec</tt> reads <em>prog1...</em> in a
+<a href="el_semicolon.html">block</a>. It then executes into it,
+completely forgetting <em>prog2...</em> </li>
+ <li> If for some reason the <tt>execve()</tt> fails - for instance,
+a non-executable <em>prog1</em> - then <tt>tryexec</tt> executes
+into <em>prog2...</em> instead. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-n</tt>&nbsp;: reverse <em>prog1...</em> and <em>prog2...</em>'s
+role. The latter becomes the main execution path and the former becomes
+the fallback. </li>
+</ul>
+
+<p>
+  The <tt>-c</tt>, <tt>-l</tt> and <tt>-a</tt> options have the same
+semantics as with the <a href="exec.html">exec</a> program.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> <tt>tryexec <em>prog1...</em> "" <em>prog2...</em></tt> would be
+equivalent to
+<tt>sh -c 'exec <em>prog1...</em> || exec <em>prog2...</em>'</tt>, if
+such a shell construct existed. Unfortunately, the shell language does
+not offer that functionality. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/umask.html b/doc/umask.html
new file mode 100644
index 0000000..5edf511
--- /dev/null
+++ b/doc/umask.html
@@ -0,0 +1,44 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the umask command</title>
+  <meta name="Description" content="execline: the umask command" />
+  <meta name="Keywords" content="execline command umask" />
+  <!-- <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> The <tt>umask</tt> program </h1>
+
+<p>
+<tt>umask</tt> sets the umask (file creation mask),
+then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     umask <em>mask</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>umask</tt> sets the current umask to <em>mask</em>,
+then execs into <em>prog...</em>.
+</p>
+
+<h2> Notes </h2>
+
+<p>
+<tt>umask</tt> is a standard shell builtin. Be careful if you want to
+use the <tt>umask</tt> command outside of an <tt>execline</tt> script.
+</p>
+
+</body>
+</html>
diff --git a/doc/unexport.html b/doc/unexport.html
new file mode 100644
index 0000000..331189c
--- /dev/null
+++ b/doc/unexport.html
@@ -0,0 +1,46 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the unexport command</title>
+  <meta name="Description" content="execline: the unexport command" />
+  <meta name="Keywords" content="execline command unexport environment" />
+  <!-- <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> The <tt>unexport</tt> program </h1>
+
+<p>
+<tt>unexport</tt> removes a variable from the environment, then
+executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     unexport <em>var</em> <em>prog...</em>
+</pre>
+
+<p>
+<tt>unexport</tt> removes the <em>var</em> variable from the
+environment, then execs into <em>prog</em> with
+its arguments.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> Unsetting <em>var</em> is quite different from setting it to an
+empty value. Shell scripts usually won't make the distinction;
+execline does. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/upgrade.html b/doc/upgrade.html
new file mode 100644
index 0000000..9cd795b
--- /dev/null
+++ b/doc/upgrade.html
@@ -0,0 +1,35 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>execline: how to upgrade</title>
+    <meta name="Description" content="execline: how to upgrade" />
+    <meta name="Keywords" content="execline installation upgrade" />
+    <!-- <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>
+
+
+<h2> to 2.0.0.0 </h2>
+
+<ul>
+ <li> The build system has completely changed. It is now a standard
+<tt>./configure &amp;&amp; make &amp; &amp; sudo make install</tt>
+build system. See the enclosed INSTALL file for details. </li>
+ <li> slashpackage is not activated by default. </li>
+ <li> shared libraries are neither built nor used by default. </li>
+ <li> skalibs dependency bumped to 2.0.0.0 </li>
+ <li> The obsolete -E option to backtick, forx and forbacktickx is not
+supported anymore. </li>
+ <li> multisubstitute does not support the "backtick" directive
+anymore. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/wait.html b/doc/wait.html
new file mode 100644
index 0000000..680cd78
--- /dev/null
+++ b/doc/wait.html
@@ -0,0 +1,53 @@
+<html>
+ <head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <meta http-equiv="Content-Language" content="en" />
+  <title>execline: the wait command</title>
+  <meta name="Description" content="execline: the wait command" />
+  <meta name="Keywords" content="execline command wait" />
+  <!-- <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> The <tt>wait</tt> program </h1>
+
+<p>
+<tt>wait</tt> waits for a set of children, then executes a program.
+</p>
+
+<h2> Interface </h2>
+
+<p>
+ In an <a href="execlineb.html">execlineb</a> script:
+</p>
+
+<pre>
+     wait [ -r ] { [ <em>pids...</em> ] } <em>prog...</em>
+</pre>
+
+<ul>
+ <li> <tt>wait</tt> reads a list of <em>pids</em> in a
+(possibly empty) <a href="el_semicolon.html">block</a>,
+and unquotes it. </li>
+ <li> <tt>wait</tt> waits for every child whose pid is
+listed in <em>pids...</em>. If <em>pids...</em> is an
+empty list, it waits for every child process it has. </li>
+ <li><tt>wait</tt> then execs into <em>prog...</em>. </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-r</tt>&nbsp;: reap mode. Do not pause until a child has
+exited; only reap all pending zombies. The read block must be empty
+for that option to be effective. </li>
+</ul>
+
+</body>
+</html>