git: e5c5d8f78ead - stable/13 - man: Add -l option

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Tue, 16 Sep 2025 13:59:24 UTC
The branch stable/13 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=e5c5d8f78eade3a78825caf395c86fb9e7dccc82

commit e5c5d8f78eade3a78825caf395c86fb9e7dccc82
Author:     Ingo Schwarze <schwarze@usta.de>
AuthorDate: 2025-09-07 20:52:09 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-09-16 13:55:22 +0000

    man: Add -l option
    
    Add a -l option which causes man to interpret all arguments as paths to
    open directly rather than man pages to search for in MANPATH.  See the
    PR for a detailed rationale.
    
    PR:             289245
    MFC after:      1 week
    Reviewed by:    ziaee, emaste
    Differential Revision:  https://reviews.freebsd.org/D52385
    
    (cherry picked from commit 14b61b2e931741281d0bfef426e9809f16006504)
---
 usr.bin/man/man.1  | 25 ++++++++++++++++++++-----
 usr.bin/man/man.sh | 31 +++++++++++++++++++++++--------
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1
index 4bab5d78eea2..e524258cfbb4 100644
--- a/usr.bin/man/man.1
+++ b/usr.bin/man/man.1
@@ -31,7 +31,7 @@
 .Nd display online manual documentation pages
 .Sh SYNOPSIS
 .Nm
-.Op Fl adho
+.Op Fl adhlo
 .Op Fl t | w
 .Op Fl M Ar manpath
 .Op Fl P Ar pager
@@ -133,6 +133,15 @@ Display short help message and exit.
 .It Fl k
 Emulate
 .Xr apropos 1 .
+.It Fl l
+Interpret all arguments as absolute or relative filename(s)
+of the manual page(s) to display.
+No search is done and the options
+.Fl M ,
+.Fl m ,
+and
+.Fl S
+are ignored.
 .It Fl m Ar arch Ns Op : Ns Ar machine
 Override the default architecture and machine settings allowing lookup of
 other platform specific manual pages.
@@ -258,12 +267,15 @@ will search the following paths when considering section 4 manual pages in
 .Pa /usr/share/man/man4
 .El
 .Ss Displaying Specific Manual Files
-The
+For compatibility reasons,
 .Nm
-utility also supports displaying a specific manual page if passed a path
-to the file as long as it contains a
+will interpret any argument containing at least one
 .Ql /
-character.
+character as an absolute or relative path to a manual page to be
+displayed.
+This heuristic, made redundant by the more widely supported
+.Fl l
+option, is now deprecated and may be removed in future releases.
 .Sh ENVIRONMENT
 The following environment variables affect the execution of
 .Nm :
@@ -390,6 +402,9 @@ manual page:
 $ man -w ls
 .Ed
 .Pp
+Show a manual page in the current working directory:
+.Pp
+.Dl $ man -l man.1
 .Sh SEE ALSO
 .Xr apropos 1 ,
 .Xr intro 1 ,
diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh
index 33be10cd5bd6..6bb260117078 100755
--- a/usr.bin/man/man.sh
+++ b/usr.bin/man/man.sh
@@ -495,13 +495,21 @@ man_display_page_groff() {
 # Usage: man_find_and_display page
 # Search through the manpaths looking for the given page.
 man_find_and_display() {
-	local found_page locpath p path sect
+	local found_page has_slash locpath p path sect
 
 	# Check to see if it's a file. But only if it has a '/' in
-	# the filename.
+	# the filename or if -l was specified.
 	case "$1" in
-	*/*)	if [ -f "$1" -a -r "$1" ]; then
+	*/*)	has_slash=yes
+		;;
+	esac
+	if [ -n "$has_slash" -o -n "$lflag" ]; then
+		if [ -f "$1" -a -r "$1" ]; then
 			decho "Found a usable page, displaying that"
+			if [ -z "$lflag" ]; then
+				echo "Opening a file directly is deprecated," \
+				    "use -l instead." >&2
+			fi
 			unset use_cat
 			manpage="$1"
 			setup_cattool "$manpage"
@@ -510,9 +518,12 @@ man_find_and_display() {
 				man_display_page
 			fi
 			return
+		elif [ -n "$lflag" ]; then
+			echo "Cannot read $1" >&2
+			ret=1
+			return
 		fi
-		;;
-	esac
+	fi
 
 	IFS=:
 	for sect in $MANSECT; do
@@ -580,7 +591,7 @@ man_parse_opts() {
 	local cmd_arg
 
 	OPTIND=1
-	while getopts 'M:P:S:adfhkm:op:tw' cmd_arg; do
+	while getopts 'M:P:S:adfhklm:op:tw' cmd_arg; do
 		case "${cmd_arg}" in
 		M)	MANPATH=$OPTARG ;;
 		P)	MANPAGER=$OPTARG ;;
@@ -590,6 +601,7 @@ man_parse_opts() {
 		f)	fflag=fflag ;;
 		h)	man_usage 0 ;;
 		k)	kflag=kflag ;;
+		l)	lflag=lflag ;;
 		m)	mflag=$OPTARG ;;
 		o)	oflag=oflag ;;
 		p)	MANROFFSEQ=$OPTARG ;;
@@ -602,12 +614,15 @@ man_parse_opts() {
 	shift $(( $OPTIND - 1 ))
 
 	# Check the args for incompatible options.
-	case "${fflag}${kflag}${tflag}${wflag}" in
+	case "${fflag}${kflag}${lflag}${tflag}${wflag}" in
 	fflagkflag*)	echo "Incompatible options: -f and -k"; man_usage ;;
+	fflag*lflag*)	echo "Incompatible options: -f and -l"; man_usage ;;
 	fflag*tflag*)	echo "Incompatible options: -f and -t"; man_usage ;;
 	fflag*wflag)	echo "Incompatible options: -f and -w"; man_usage ;;
-	*kflagtflag*)	echo "Incompatible options: -k and -t"; man_usage ;;
+	*kflaglflag*)	echo "Incompatible options: -k and -l"; man_usage ;;
+	*kflag*tflag*)	echo "Incompatible options: -k and -t"; man_usage ;;
 	*kflag*wflag)	echo "Incompatible options: -k and -w"; man_usage ;;
+	*lflag*wflag)	echo "Incompatible options: -l and -w"; man_usage ;;
 	*tflagwflag)	echo "Incompatible options: -t and -w"; man_usage ;;
 	esac