Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Sep 2007 06:01:49 GMT
From:      Ighighi <ighighi@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/116702: [patch]: add ability to run man on a local file (was in TODO list)
Message-ID:  <200709280601.l8S61njH017814@www.freebsd.org>
Resent-Message-ID: <200709280610.l8S6A2W1075333@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         116702
>Category:       bin
>Synopsis:       [patch]: add ability to run man on a local file (was in TODO list)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 28 06:10:01 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Ighighi
>Release:        6.2-STABLE
>Organization:
>Environment:
FreeBSD orion 6.2-STABLE FreeBSD 6.2-STABLE #0: Thu Sep 27 03:31:00 VET 2007     root@orion:/usr/obj/usr/src/sys/CUSTOM  i386
>Description:
It has long been in the TODO file and I think it's a feature that comes in handy
to both developers and users alike when creating and browsing manpages...
The semantics are simple: if the argument contains a directory separator ('/'),
then open that file and forget about $MANPATH.  To open a manpage in the current
directory, all the user has to do is prepend a "./".
Note: if this patch is eventually merged, I could add the relevant notes to man(1)
as well...

The attached patch has been successfully built and tested on FreeBSD 6.2-STABLE
and known to patch on -CURRENT.
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- src/gnu/usr.bin/man/lib/util.c.orig	1999-05-13 11:59:27.000000000 -0400
+++ src/gnu/usr.bin/man/lib/util.c	2007-09-28 00:43:59.530668009 -0400
@@ -120,6 +120,24 @@
 }
 
 /*
+ * Is path a regular file?
+ */
+int
+is_file (path)
+     char *path;
+{
+  struct stat sb;
+  register int status;
+
+  status = stat (path, &sb);
+
+  if (status != 0)
+    return -1;
+
+  return ((sb.st_mode & S_IFREG) == S_IFREG);
+}
+
+/*
  * Attempt a system () call.  Return 1 for success and 0 for failure
  * (handy for counting successes :-).
  */
--- src/gnu/usr.bin/man/man/man.c.orig	2007-09-27 23:53:06.000000000 -0400
+++ src/gnu/usr.bin/man/man/man.c	2007-09-28 00:43:59.535668086 -0400
@@ -29,6 +29,7 @@
 #ifdef __FreeBSD__
 #include <locale.h>
 #include <langinfo.h>
+#include <libgen.h>
 #endif
 #include <stdio.h>
 #include <string.h>
@@ -69,6 +70,7 @@
 extern char **glob_filename ();
 extern int is_newer ();
 extern int is_directory ();
+extern int is_file ();
 extern int do_system_command ();
 
 char *prognam;
@@ -85,6 +87,7 @@
 static int whatis;
 static int findall;
 static int print_where;
+static char *ultimate_source ();
 
 #ifdef __FreeBSD__
 static char *locale, *locale_opts, *locale_nroff, *locale_codeset;
@@ -201,10 +204,17 @@ main (argc, argv)
       }
       else
 	{
-	  status = man (nextarg);
+	  if (strchr(nextarg, '/') != NULL && is_file(nextarg) == 1) {
+	    char *dir = dirname(nextarg);
+	    char *srcfile = ultimate_source(nextarg, dir);
+	    format_and_display(dirname(srcfile), srcfile, NULL);
+	  }
+	  else {
+	    status = man (nextarg);
 
-	  if (status == 0)
-	    gripe_not_found (nextarg, longsec);
+	    if (status == 0)
+	      gripe_not_found (nextarg, longsec);
+	  }
 	}
     }
   return (status==0);         /* status==1 --> exit(0),
@@ -1391,14 +1401,21 @@ format_and_display (path, man_file, cat_
   if (access (man_file, R_OK) != 0)
     return 0;
 
-  if (troff)
+  if (troff || cat_file == NULL)
     {
       roff_command = make_roff_command (man_file);
       if (roff_command == NULL)
 	return 0;
-      else
+      else if (cat_file != NULL)
 	snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command);
-
+      else
+	{
+	   if (strchr(man_file, '/') != NULL)
+    	     snprintf (command, sizeof(command), "%s | %s", roff_command, pager);
+	   else
+    	     snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path,
+		      roff_command, pager);
+	}
       found = do_system_command (command);
     }
   else
--- src/gnu/usr.bin/man/TODO.orig	1993-07-07 19:06:59.000000000 -0400
+++ src/gnu/usr.bin/man/TODO	2007-09-28 00:46:00.179509691 -0400
@@ -105,8 +105,6 @@ XX  I've been using your man(1) package 
     file names used by Motif.  Maybe there's a better way to handle
     this?
 
-15. Add ability to run man on a local file
-
 16. Handle per-tree tmac macros
     
 XX  Allow user-definable section search order via -S or $MANSECT.


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709280601.l8S61njH017814>