[indiana-discuss] Fwd: Code Review: PSARC/2007/688 manwhich: Deriving MANPATH from PATH
Mike Gerdts
mgerdts at gmail.com
Wed Jan 9 20:25:47 PST 2008
I've made some enhancements to man(1), partly inspired by the default
PATH in the October developer preview release. Aside from updating
the copyright year, I believe the code is ready for putback. So far I
have had little luck with the folks at opensolaris-code to get code
reviews[1]. If your priorities are more aligned to have a more
friendly man(1) in the next Indiana release, please take a look and
get me your feedback.
Mike
1. I am, however, very thankful for the discussion on opensolaris-code
before I drafted the ARC case and the feedback on psarc-ext
afterwards. It certainly helped generate ideas for other closely
related improvements that were incorporated.
---------- Forwarded message ----------
From: Mike Gerdts <mgerdts at gmail.com>
Date: Dec 19, 2007 9:40 PM
Subject: Code Review: PSARC/2007/688 manwhich: Deriving MANPATH from PATH
To: OpenSolaris Code <opensolaris-code at opensolaris.org>, John Plocher
<John.Plocher at sun.com>, Sam Falkner <Sam.Falkner at sun.com>
I have posted an updated webrev for:
PSARC/2007/688 manwhich: Deriving MANPATH from PATH
6634079 man should take hints from PATH when MANPATH not set
at http://cr.opensolaris.org/~mgerdts/manpath-from-path/.
I'm posting the code review request just a few hours before the
FastTrack ARC review expires and as such the case materials have not
been posted yet. When they are available, they will be at
http://opensolaris.org/os/community/arc/caselog/2007/688/.
Since there are man page changes, I could use some guidance as to how
I go about getting them in place. Should I be working with the docs
community and providing diffs to the *roff source? Or is there some
magic queue that I submit the relevant spec section to and some *roff
wizard takes over?
The latest edition of the spec appears below.
2. Project Summary
2.1. Project Description:
When projects such as Indiana or individuals customize PATH,
MANPATH is often left unset. This leads to confusion because man(1)
will display the manual page for the wrong variant of a command.
For example, if /usr/gnu/bin is at the front of the path, the
default behavior of man(1) would most appropriately be to display a
manual page from /usr/gnu/share/man rather than /usr/share/man.
Similar, but slightly more complex, considerations are made for
/usr/ucb and for invocations of man(1) that specify the path to the
executable for which a man page is sought.
2.2. Risks and Assumptions:
Traditional behavior and expectation is that /usr/share/man is the
only directory searched in the case that the MANPATH environment
variable is undefined. This behavior is documented in the man page
for man.
To allow behavior that closely resembles the legacy behavior of
man(1), setting MANPATH and using name arguments that do not
contain the "/" character will not invoke any PATH to MANPATH
translations.
4. Technical Description:
4.1. Details:
4.1.1. Transformations
The source file man.c will be enhanced to refer to PATH only in the
absence of MANPATH. Each element of PATH will be transformed based
into the appropriate MANPATH element based upon the following
priorities:
- Explicit transformation rule. For example, /usr/ucb in PATH
transforms to /usr/share/man,1b. See below for details.
- The parent directory of the PATH directory with /man
appended. For example, /opt/VRTSvcs/bin becomes
/opt/VRTSvcs/man, assuming /opt/VRTSvcs/man exists.
- The parent directory of the PATH directory with /share/man
appended. For example, /usr/gnu/bin becomes
/usr/gnu/share/man because /usr/gnu/man does not exist.
In addition and higher precedence to the above, if man is invoked
referring to particular instance of a command (e.g. "man ./ls" or
"man /usr/ucb/ps") the path transformation rules are applied using
the directory component of the argument.
In all cases where MANPATH is not defined and the path to a command
is not specified /usr/share/man will be appended to MANPATH if it
is not otherwise included based upon PATH transform rules. This
ensures that sections other than 1* are accessible.
The PATH to MANPATH transformations are as follows:
PATH element MANPATH element
---------------- -------------------------------
/sbin /usr/share/man,1m
/usr/sbin /usr/share/man,1m
/usr/ucb /usr/share/man,1b
/usr/bin /usr/share/man,1,1m,1s,1t,1c,1f
/usr/xpg4/bin /usr/share/man,1
/usr/xpg6/bin /usr/share/man,1
Sections within each directory are explicitely set to ensure proper
ordering of results for invocations such as "man -l", "man -a",
whatis(1), etc.
The transformation rules are stored in a data structure within
man.c. The use of such a static mapping instead of a configuration
file is chosen based upon the following:
- The rules to use <prefix>/man or <prefix>/share/man directories
will accomodate the vast majority of add-on software.
- The alternative would be to create a configuration file to
store the mappings. History has shown that providers of add-on
software do not do a good job of modifying configuration files
properly during installation and removal of software. In
contrast, add-on software providers can easily create
strategically placed symbolic links to trigger the automatic
<prefix>/man or <prefix>/share/man translation.
- Providing a command to update the configuration file would be
significant work for a presumably very small number of edge
cases.
- If demand is shown, a configuration file can be added with very
little rework in the future.
4.1.2. New option to print effective MANPATH
To facilitate debugging and to provide a means for users to augment
the derived MANPATH the -p (mnemonic: print MANPATH) option will be
added. When "man -p" is invoked with no name options, the output
will be suitable for use as part of a user's MANPATH environment
variable. For example a user may choose to have a .profile with
the following:
PATH=/usr/bin:/usr/gnu/bin:/usr/sbin:/usr/ucb
export PATH
unset MANPATH
MANPATH=`man -p`:$HOME/myman
export MANPATH
This provides the ability to leverage the derived MANPATH without
having to sacrifice the ability to use man directories that have no
associated bin directory or would otherwise be missed by standard
transformation rules.
4.1.3. Prototype
A prototype of this behavior (sans -p option) has been implemented
and is available for review at
http://cr.opensolaris.org/~mgerdts/manpath-from-path/.
4.3. In Scope:
Described above.
4.4. Out of Scope:
GNU utilities often times provide only stub man pages and more
complete documentation using an alternative format known as "info".
While translators from info to man do exist, this project does not
seek to bridge this gap.
4.5. Interfaces
The interface stability of man(1) is documented as "Standard"
("Comitted", in updated terminology). This project alters the
documented "Search Path" behavior when MANPATH is not set.
This project also extends the documented interface to man(1) such
that "name" arguments that specify a fully qualified or relative
path (with at least one '/' character) alter the documented "Search
Path" behavior.
Corresponding interface changes apply to whatis(1), catman(1M), and
apropos(1) which are all hard links to man(1).
4.6. Doc Impact
4.6.1. man(1) manual page
The man(1) manual page will be enhanced as follows.
OPTIONS
The following options are supported:
. . .
-M path Specifies an alternate search path for
. . .
one for each section. This option over-
rides the MANPATH environment variable
and any MANPATH derived from PATH for
operands that do not have a '/'
character.
-p Prints the effective MANPATH. If no name
operands are used, the MANPATH used to
search for name operands without a '/'
character is displayed in a format
suitable for use as the MANPATH
environment variable. If one or more
name operands is used, each name operand
and its associated effective MANPATH are
printed. One line of output exists for
each name operand.
. . .
OPERANDS
The following operand is supported:
name The name of a standard utility or a keyword. If the
name contains a '/' character, the search path (See
"Search Path") is altered to search only the man
directory corresponding to the name argument. For
example, if name is "/usr/ucb/ps" man will behave as
if the MANPATH environment variable is set to
/usr/share/man,1b.
. . .
Search Path
Before searching for a given name, man constructs a list of
candidate directories and sections. man searches for name in
the directories specified by the MANPATH environment vari-
able. If this variable is not set and the -M option is not
used, a substitute MANPATH is constructed based upon the
PATH environment variable. In all cases, except as described
above when the name operand has a "/" character,
/usr/share/man is searched.
For each name operand that contains a "/" character, neither
MANPATH nor PATH are used to construct the search path.
. . .
ENVIRONMENT VARIABLES
. . .
MANPATH A colon-separated list of directories; each
directory can be followed by a comma-separated
list of sections. If set, its value overrides
the default directory search path, and man.cf as
the default section search path. The -M and -s
flags, in turn, override these values. The
default directory search path is constructed
based upon the contents of the PATH environment
variable with /usr/share/man appended, as
necessary.
PATH The search path for commands. If MANPATH is not
set, MANPATH is derived from PATH.
. . .
EXAMPLES
. . .
Example 3 Displaying the man page for /usr/ucb/ps
The following example displays the man page for
/usr/ucb/ps, regardless of the values of MANPATH and
PATH.
man /usr/ucb/ps
This is an alternative to using the -l option to find all
man pages for ps then selecting the one most likely to
correspond to /usr/ucb/ps.
Example 4 Setting shell using customized derived MANPATH
The following example shows commands that can be added to
profile(4) to use the MANPATH derived from PATH in
addition to man directories not associated with PATH
directories.
PATH=/usr/bin:/usr/gnu/bin:/usr/ucb
export PATH
unset MANPATH
MANPATH=`man -p`:$HOME/myman
export MANPATH
The environment created using this example will derive
MANPATH once and subsequent invocations of man(1) will
use the value in the MANPATH environment variable.
SEE ALSO
apropos(1), cat(1), col(1), dpost(1), eqn(1), more(1),
nroff(1), refer(1), tbl(1), troff(1), vgrind(1), whatis(1),
catman(1M), profile(4), attributes(5), environ(5),
eqnchar(5), filesystem(5), man(5), sgml(5), standards(5)
NOTES
When deriving PATH elements to MANPATH elements, man(1) first
attempts to transform <prefix>/bin or <prefix>/sbin to
<prefix>/man, as filesystem(5) indicates that add-on software
should use /opt/packagename/man for manual pages. In the
event that <prefix>/man does not exist but <prefix>/share/man
does exist, <prefix>/share/man will be searched. Searching
<prefix>/share/man is intended for legacy compatibility only.
4.6.2. catman(1M) manaul page changes
The catman(1M) manual page will change as follows:
DESCRIPTION
. . .
catman also creates the windex database file in the direc-
tories specified by the MANPATH, the -M option, or MANPATH
derived from PATH. The windex database file is a three
. . .
OPTIONS
. . .
-M directory Update manual pages located in the
specified directory (see "Search Path"
in man(1) for default). If the -M
option is specified, the directory
argument must not contain a `,' (comma),
since a comma is used to delineate
section numbers. See man(1).
ENVIRONMENT VARIABLES
. . .
MANPATH A colon-separated list of directories; each
directory can be followed by a comma-separated
list of sections. If set, its value overrides
the default directory search path, and man.cf as
the default section search path. The -M and -s
flags, in turn, override these values. The
default directory search path is constructed
based upon the contents of the PATH environment
variable with /usr/share/man appended, as
necessary.
PATH The search path for commands. If MANPATH is not
set, MANPATH is derived from PATH.
4.6.3. Related manual pages not changing
While the behavior of whatis(1) changes in the event that MANPATH
is not set or a relative or absolute command path provided, the
whatis(1) man page is sufficiently vague as to not require any
changes to remain accurate. whatis(1) indicates that it is
equivalent to "the -f option of the man(1) command" and as such
refers users to more complete documentation.
Similarly, the behavior of apropos(1) changes in the event that
MANPATH is not set. However, the man page for apropos(1) is
sufficiently vague to as to not require any changes to remain
accurate. apropos(1) indicates "apropos is actually just the -k
option to the man(1) command" and as such refers users to more
complete documentation.
--
Mike Gerdts
http://mgerdts.blogspot.com/
--
Mike Gerdts
http://mgerdts.blogspot.com/
More information about the indiana-discuss
mailing list