Sorry, I didn't reviewed the code well. The first diff has some bugs. As follows the stable diff (please, review):
Index: main.c =================================================================== RCS file: /cvs/src/usr.bin/mandoc/main.c,v retrieving revision 1.252 diff -u -p -r1.252 main.c --- main.c 11 Jun 2020 16:12:14 -0000 1.252 +++ main.c 15 Jun 2020 01:05:12 -0000 @@ -107,8 +107,8 @@ static void parse(struct mparse *, in static void passthrough(int, int); static void process_onefile(struct mparse *, struct manpage *, int, struct outstate *, struct manconf *); -static void run_pager(struct tag_files *, char *); -static pid_t spawn_pager(struct tag_files *, char *); +static void run_pager(struct tag_files *, char *, int use_furl); +static pid_t spawn_pager(struct tag_files *, char *, int use_furl); static void usage(enum argmode) __attribute__((__noreturn__)); static int woptions(char *, enum mandoc_os *, int *); @@ -140,6 +140,7 @@ main(int argc, char *argv[]) size_t i, ib, ssz; int options; /* Parser options. */ int show_usage; /* Invalid argument: give up. */ + int use_furl; /* Use file:///tmp/man.XXXXXXXX URL scheme */ int prio, best_prio; int startdir; int c; @@ -183,6 +184,7 @@ main(int argc, char *argv[]) options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; os_e = MANDOC_OS_OTHER; os_s = NULL; + use_furl = 0; /* Formatter options. */ @@ -195,7 +197,7 @@ main(int argc, char *argv[]) outmode = OUTMODE_DEF; while ((c = getopt(argc, argv, - "aC:cfhI:iK:klM:m:O:S:s:T:VW:w")) != -1) { + "aC:cfhI:iK:klM:m:O:S:s:T:VW:wU")) != -1) { if (c == 'i' && search.argmode == ARG_EXPR) { optind--; break; @@ -301,6 +303,9 @@ main(int argc, char *argv[]) case 'w': outmode = OUTMODE_FLN; break; + case 'U': + use_furl = 1; + break; default: show_usage = 1; break; @@ -621,7 +626,7 @@ out: if (outst.tag_files != NULL) { if (term_tag_close() != -1) - run_pager(outst.tag_files, conf.output.tag); + run_pager(outst.tag_files, conf.output.tag, use_furl); term_tag_unlink(); } else if (outst.had_output && outst.outtype != OUTT_LINT) mandoc_msg_summary(); @@ -639,7 +644,7 @@ usage(enum argmode argmode) "\t [-T output] [-W level] [file ...]\n", stderr); break; case ARG_NAME: - fputs("usage: man [-acfhklw] [-C file] [-M path] " + fputs("usage: man [-acfhklwU] [-C file] [-M path] " "[-m path] [-S subsection]\n" "\t [[-s] section] name ...\n", stderr); break; @@ -1122,7 +1127,7 @@ woptions(char *arg, enum mandoc_os *os_e * then fork the pager and wait for the user to close it. */ static void -run_pager(struct tag_files *tag_files, char *tag_target) +run_pager(struct tag_files *tag_files, char *tag_target, int use_furl) { int signum, status; pid_t man_pgid, tc_pgid; @@ -1155,7 +1160,7 @@ run_pager(struct tag_files *tag_files, c (void)tcsetpgrp(STDOUT_FILENO, pager_pid); kill(pager_pid, SIGCONT); } else - pager_pid = spawn_pager(tag_files, tag_target); + pager_pid = spawn_pager(tag_files, tag_target, use_furl); /* Wait for the pager to stop or exit. */ @@ -1176,11 +1181,14 @@ run_pager(struct tag_files *tag_files, c } static pid_t -spawn_pager(struct tag_files *tag_files, char *tag_target) +spawn_pager(struct tag_files *tag_files, char *tag_target, int use_furl) { const struct timespec timeout = { 0, 100000000 }; /* 0.1s */ #define MAX_PAGER_ARGS 16 +#define MAX_FILE_TAG 30 +#define MAX_FILE_URL 33 /* 33 is file:///tmp/man.XXXXX...#\0 */ char *argv[MAX_PAGER_ARGS]; + char ofurl[MAX_FILE_URL + MAX_FILE_TAG]; const char *pager; char *cp; size_t cmdlen; @@ -1230,8 +1238,22 @@ spawn_pager(struct tag_files *tag_files, } } } - if (use_ofn) - argv[argc++] = tag_files->ofn; + + if (use_ofn) { + if (use_furl) { + strncpy(ofurl, "file://", MAX_FILE_URL); + strncat(ofurl, tag_files->ofn, MAX_FILE_URL); + if (tag_target != NULL) { + ofurl[strlen(ofurl)] = '#'; + ofurl[strlen(ofurl) + 1] = 0; + strncat(ofurl, tag_target, MAX_FILE_TAG); + } + argv[argc++] = ofurl; + } else { + argv[argc++] = tag_files->ofn; + } + } + argv[argc] = NULL; switch (pager_pid = fork()) {