* lib/pipeline.c: New pipeline library, adapted from that in groff.
The interface isn't complete yet; in particular, it can't be a
replacement for popen() at the moment.
* lib/pipeline.h: New file with pipeline library interface.
* lib/Makefile.in (ALLSRCS, ALL): Build pipeline.
Add support in pipeline library for writing input to or reading
output from the whole pipeline.

* lib/pipeline.c (pipeline_new): Initialize writeto, readfrom,
writefd, and readfd.
(pipeline_start): Create extra pipes as necessary.
(pipeline_wait): Expand TODO comment. Close file descriptors from
extra pipes if necessary.
* lib/pipeline.h (struct pipeline): Add writeto, readfrom, writefd,
and readfd.
* lib/pipeline.h (struct pipeline): The writeto, readfrom, writefd,
and readfd names turn out to be confusing in calling code. Rename
to want_in, want_out, infd, and outfd respectively.
* lib/pipeline.c (pipeline_new, pipeline_start, pipeline_wait): Use
new names.
* lib/pipeline.c (command_dup): New function to duplicate a command.
(pipeline_join): New function to join two pipelines together.
* lib/pipeline.h: Prototype these.
* lib/pipeline.c (argstr_get_word, command_new_argstr,
command_argstr, pipeline_command_argstr): New functions to handle
constructing commands from shell-quoted strings, such as those
found in man-db configuration files. They deliberately handle only
a safe subset of shell syntax.
* lib/pipeline.h: Prototype command_new_argstr(), command_argstr(),
and pipeline_command_argstr().
* lib/pipeline.c (pipeline_start): Pop all cleanups in child.
* lib/pipeline.h (struct command): New 'nice' member.
* lib/pipeline.c (command_new): Initialize nice.
(pipeline_start): Change child process priority if nice is set.
infd and outfd should now only be set by pipeline_start(). Positive
values in want_in and want_out now indicate caller-supplied file
descriptors, while negative values indicate a request for
pipeline_start() to create a pipe.

* lib/pipeline.h (struct pipeline): Document this.
* lib/pipeline.c (pipeline_start): Implement it. Caller-supplied
input and output file descriptors previously didn't work properly.
(pipeline_wait): Update TODO comment.
* lib/pipeline.c (pipeline_start): Use dup2() instead of close()
then dup().
Add support for getting stdio streams for input and output. Needs
library support because pipeline_wait() needs to know to close the
stream rather than the underlying file descriptor.

* lib/pipeline.h (struct pipeline): New infile and outfile members.
(pipeline_get_infile, pipeline_get_outfile): Add prototypes.
* lib/pipeline.c (pipeline_new): Initialize infile and outfile.
(pipeline_join): Likewise.
(pipeline_get_infile, pipeline_get_outfile): New functions.
(pipeline_wait): Check for infile and outfile and fclose() them in
preference to close()ing infd and outfd. Check for errors on
close().
* lib/pipeline.c (pipeline_wait): The return value was a bit
groff-specific. Now just return the status of the last command in
the pipeline, as reported by wait().
* lib/pipeline.c (argstr_get_word): Plug some memory leaks.
* lib/pipeline.c (pipeline_dump): New function to dump a printable
representation of a pipeline to a stream.
(pipeline_tostring): Likewise, but to a newly allocated string.
* lib/pipeline.h: Prototype these.
* lib/pipeline.c (command_dup): Terminate argv with a NULL.
(command_dup, command_arg): Assert that argc < argv_max after
changing either.
* lib/pipeline.c (command_dup): Copy cmd->nice.
(pipeline_command): Correct condition for growing commands array.
Replace the old "wait() for one child at a time" approach with a
SIGCHLD-handling edifice that collects children's exit statuses as
they die.

* lib/pipeline.c (pipeline_new): Initialize statuses.
(pipeline_join): Set statuses to NULL in joined pipeline.
(pipeline_join, pipeline_get_infile, pipeline_get_outfile,
pipeline_start, pipeline_wait): Assert that statuses field is NULL
or non-NULL as appropriate.
(pipeline_free): Free statuses if necessary.

(pipeline_start): Add p to a new active_pipelines array, to be
used while reaping children. Initialize statuses elements to -1.
Block SIGCHLD while forking children.
(reap_children): New function. Delivers collected exit statuses
into statuses fields of entries in active_pipelines.
(pipeline_wait): Rather than wait()ing manually here, check
whether any statuses have been picked up by the SIGCHLD handler,
and if not call reap_children(). Remove now-obsolete TODO comment.
(pipeline_sigchld): New function, the SIGCHLD handler.
(pipeline_install_sigchld): New function, to be called once per
program.

(pipeline_start, pipeline_wait): Add minimal debugging
information.

* lib/pipeline.h: Prototype new functions.
(struct pipeline): New statuses member.
* include/manconfig.h.in: Remove incorrect prototype of basename()
which was hiding several bugs.
* configure.in: Check for <libgen.h>.
* lib/pipeline.c, src/accessdb.c, src/catman.c, src/check_mandirs.c,
src/filenames.c, src/lexgrog.l, src/man.c, src/mandb.c,
src/manpath.c, src/straycats.c, src/whatis.c, zsoelim/zsoelim.l:
Include <libgen.h> instead of relying on basename() prototype in
manconfig.h.
* src/check_mandirs.c (test_manfile), src/man.c (local_man_loop),
src/straycats.c (check_for_stray): Copy strings before calling
basename() on them.
* lib/pipeline.c (pipeline_start): Change "couldn't exec %s" to
"can't execute %s" in line with src/man.c, to make translators'
lives easier.
(pipeline_wait): Separate "%s: %s%s" into two translatable
strings: the "(core dumped)" portion should definitely be
translated.
* src/accessdb.c (usage): Clarify "man_database" to "(The) man
database".
* lib/pipeline.c (pipeline_start): Dump pipeline in debugging mode.
* lib/pipeline.c (pipeline_dump): Show caller-supplied input and
output file descriptors.

* lib/pipeline.c (command_free, pipeline_free): Return safely if
argument is NULL.
* lib/pipeline.h (command_free, pipeline_free): Document NULL
arguments as a safe no-op, like free().