git: a1f4ccd6c794 - stable/14 - mandoc: Vendor import of upstream at 2025-07-27
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 06 Feb 2026 00:31:51 UTC
The branch stable/14 has been updated by ziaee:
URL: https://cgit.FreeBSD.org/src/commit/?id=a1f4ccd6c79470eb0180f4d9a012b24c267d2574
commit a1f4ccd6c79470eb0180f4d9a012b24c267d2574
Author: Alexander Ziaee <ziaee@FreeBSD.org>
AuthorDate: 2025-08-15 19:03:22 +0000
Commit: Alexander Ziaee <ziaee@FreeBSD.org>
CommitDate: 2026-02-06 00:30:48 +0000
mandoc: Vendor import of upstream at 2025-07-27
Groff Compat Edition -- Interesting changes:
+ italics in section/subsection headers are now also bold, like groff
+ display "LOCAL" in response to invalid section numbers, like groff
+ tbl(7) rendering has been tweaked to be more like groff
+ scaling has been improved to better render poorly generated manuals
+ display "UNTITLED" in response to invalid man(7) titles, like groff
+ improve mandocd error handling of broken pipes
+ manual footers now always show NAME(SECTION) on the right, like groff
MFC after: 3 days
(cherry picked from commit 06410c1b51637e5e1f392d553b5008948af58014)
---
contrib/mandoc/Makefile | 2 +-
contrib/mandoc/TODO | 11 +-
contrib/mandoc/catman.8 | 238 ++++++++++++++++++++++++++++++----
contrib/mandoc/catman.c | 231 +++++++++++++++++++++++++++++----
contrib/mandoc/gmdiff | 4 +-
contrib/mandoc/man.7 | 151 +++++++++++++---------
contrib/mandoc/man.options.1 | 9 +-
contrib/mandoc/man_html.c | 19 ++-
contrib/mandoc/man_term.c | 133 +++++++++----------
contrib/mandoc/man_validate.c | 18 ++-
contrib/mandoc/mandoc.1 | 31 ++---
contrib/mandoc/mandoc.css | 4 +-
contrib/mandoc/mandocd.8 | 26 +++-
contrib/mandoc/mandocd.c | 34 ++++-
contrib/mandoc/manpath.c | 11 +-
contrib/mandoc/mdoc_html.c | 15 ++-
contrib/mandoc/mdoc_man.c | 5 +-
contrib/mandoc/mdoc_markdown.c | 10 +-
contrib/mandoc/mdoc_term.c | 122 ++++++++++--------
contrib/mandoc/mdoc_validate.c | 10 +-
contrib/mandoc/out.c | 63 ++++++---
contrib/mandoc/out.h | 24 ++--
contrib/mandoc/roff.7 | 195 +++++++++++++++++++++-------
contrib/mandoc/roff_term.c | 31 +++--
contrib/mandoc/tbl.h | 16 +--
contrib/mandoc/tbl_html.c | 34 +----
contrib/mandoc/tbl_layout.c | 10 +-
contrib/mandoc/tbl_term.c | 287 +++++++++++++++++++++++------------------
contrib/mandoc/term.c | 201 ++++++++++++++++-------------
contrib/mandoc/term.h | 38 +++---
contrib/mandoc/term_ascii.c | 91 +++++++------
contrib/mandoc/term_ps.c | 18 +--
contrib/mandoc/term_tab.c | 27 +---
33 files changed, 1365 insertions(+), 754 deletions(-)
diff --git a/contrib/mandoc/Makefile b/contrib/mandoc/Makefile
index 7ec34a560504..0830c9f289a3 100644
--- a/contrib/mandoc/Makefile
+++ b/contrib/mandoc/Makefile
@@ -15,7 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-VERSION = 1.14.6s20250613
+VERSION = 1.14.6s20250727
# === LIST OF FILES ====================================================
diff --git a/contrib/mandoc/TODO b/contrib/mandoc/TODO
index 3f5a449af68f..5d582b85b154 100644
--- a/contrib/mandoc/TODO
+++ b/contrib/mandoc/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.337 2025/04/08 21:53:14 schwarze Exp $
+* $Id: TODO,v 1.338 2025/07/22 13:36:54 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -505,6 +505,15 @@ are mere guesses, and some may be wrong.
re-reported by tb@ Mon, 16 Mar 2015 16:47:21 +0100
loc ** exist ** algo ** size * imp **
+- Check for bad line breaks caused by PostScript and PDF using variable-
+ width fonts, for example in .Bl -width "string". The difficulty line
+ below describes a naive solution by simply scaling up widths internally
+ or adding default spacing (like in terminal output). If fixes are
+ needed in width measurements, it might be a bit harder, but likely
+ not unreasonably so.
+ reported by Jan Stary 20 May 2024 10:19:01 +0200
+ loc * exist * algo ** size * imp **
+
--- HTML issues --------------------------------------------------------
- support the idiom .TP .IP .TP for multi-paragraph list item bodies
diff --git a/contrib/mandoc/catman.8 b/contrib/mandoc/catman.8
index 903fa1fa82c9..c0f14872afc6 100644
--- a/contrib/mandoc/catman.8
+++ b/contrib/mandoc/catman.8
@@ -1,6 +1,6 @@
-.\" $Id: catman.8,v 1.8 2017/03/18 19:56:01 schwarze Exp $
+.\" $Id: catman.8,v 1.15 2025/07/13 14:15:26 schwarze Exp $
.\"
-.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: March 18 2017 $
+.Dd $Mdocdate: July 13 2025 $
.Dt CATMAN 8
.Os
.Sh NAME
@@ -37,9 +37,9 @@ and
format and formats all of them, storing the formatted versions in
the same relative paths below
.Ar dstdir .
-Subdirectories of
+Unless they already exist,
.Ar dstdir
-are created as needed.
+itself and any required subdirectories are created.
Existing files are not explicitly deleted, but possibly overwritten.
.Pp
The options are as follows:
@@ -71,6 +71,18 @@ output mode, the
.Cm fragment
output option is implied.
Other output options are not supported.
+.It Fl v
+Verbose mode, printing additional information to standard error output.
+Specifying this once prints a summary about the number of files
+and directories processed at the end of the iteration.
+Specifying it twice additionally prints debugging information
+about the backchannel from
+.Xr mandocd 8
+to
+.Nm
+that is used to limit the number of files in flight at any given time.
+For details, see
+.Sx DIAGNOSTICS .
.El
.Sh IMPLEMENTATION NOTES
Since this version avoids
@@ -87,33 +99,209 @@ implementations.
.Sh EXIT STATUS
.Ex -std
.Pp
-Possible errors include:
-.Bl -bullet
-.It
-missing, invalid, or excessive command line arguments
-.It
-failure to change the current working directory to
+Failures while trying to open individual manual pages for reading,
+to save individual formatted files to the file system,
+or even to read or create subdirectories do not cause
+.Nm
+to return an error exit status.
+In such cases,
+.Nm
+simply continues with the next file or subdirectory.
+.Sh DIAGNOSTICS
+Some fatal errors cause
+.Nm
+to exit before the iteration over input files is even started:
+.Bl -tag -width Ds -offset indent
+.It unknown option \-\- Ar option
+An invalid option was passed on the command line.
+.It missing arguments: srcdir and dstdir
+No argument was provided.
+Both
.Ar srcdir
-.It
-failure to open
+and
.Ar dstdir
-.It
-communication failure with
+are mandatory.
+.It missing argument: dstdir
+Only one argument was provided.
+The second argument,
+.Ar dstdir ,
+is mandatory, too.
+.It too many arguments: Ar third argument
+Three or more arguments were provided, but only two are supported.
+.It Sy socketpair : Ar reason
+The sockets needed for communication with
+.Xr mandocd 8
+could not be created, for example due to file descriptor or memory exhaustion.
+.It Sy fork : Ar reason
+The new process needed to run
.Xr mandocd 8
-.It
-resource exhaustion, for example file descriptor, process table,
-or memory exhaustion
+could not be created, for example due to process table exhaustion
+or system resource limits.
+.It Sy exec Ns Po Sy mandocd Pc : Ar reason
+The
+.Xr mandocd 8
+child program could not be started, for example because it is not in the
+.Ev PATH
+or has no execute permission.
+.It Sy mkdir No destination Ar dstdir : reason
+The
+.Ar dstdir
+does not exist and could not be created, for example because
+the parent directory does not exist or permission is denied.
+.It Sy open No destination Ar dstdir : reason
+The
+.Ar dstdir
+could not be opened for reading, for example because
+it is not a directory or permission is denied.
+.It Sy chdir No to source Ar srcdir : reason
+The current working directory could not be changed to
+.Ar srcdir ,
+for example because it does not exist, it is not a directory,
+or permission is denied.
+.It Sy fts_open : Ar reason
+Starting the iteration was attempted but failed,
+for example due to memory exhaustion.
.El
.Pp
-Except for memory exhaustion and similar system-level failures,
-failures while trying to open, read, parse, or format individual
-manual pages, to save individual formatted files to the file system,
-or even to create directories do not cause
+Some fatal errors cause the iteration over input files to be aborted
+prematurely:
+.Bl -tag -width Ds -offset indent
+.It FATAL: Sy fts_read : Ar reason
+A call to
+.Xr fts_read 3
+returned
+.Dv NULL ,
+meaning that the iteration failed before being complete.
+.It FATAL: mandocd child died: got Ar SIGNAME
+This message appears if
.Nm
-to return an error exit status.
-In such cases,
+gets the
+.Dv SIGCHLD
+or
+.Dv SIGPIPE
+signal, most likely due to a fatal bug in
+.Xr mandocd 8 .
+.It FATAL: Sy sendmsg : Ar reason
+The file descriptors needed to process one of the manual pages
+could not be sent to
+.Xr mandocd 8 ,
+for example because
+.Xr mandocd 8
+could not be started or died unexpectedly.
+.It FATAL: Sy recv : Ar reason
+Trying to read a reply message from
+.Xr mandocd 8
+failed, most likely because
+.Xr mandocd 8
+unexpectedly died or closed the socket.
+.It FATAL: signal Ar SIGNAME
+This message appears if
+.Nm
+gets a
+.Dv SIGHUP ,
+.Dv SIGINT ,
+or
+.Dv SIGTERM
+signal, for example because the user deliberately killed it.
+.El
+.Pp
+Some non-fatal errors cause a single subdirectory to be skipped.
+The iteration is not aborted but continues with the next subdirectory,
+and the exit status is unaffected:
+.Bl -tag -width Ds -offset indent
+.It directory Ar subdirectory No unreadable : Ar reason
+A directory below
+.Ar srcdir
+could not be read and is skipped.
+.It directory Ar subdirectory No causes cycle
+A directory below
+.Ar srcdir
+is skipped because it would cause cyclic processing.
+.It Sy mkdirat Ar subdirectory : reason
+A required directory below
+.Ar dstdir
+does not exist and could not be created.
+The corresponding subdirectory below
+.Ar srcdir
+is skipped.
+.El
+.Pp
+Some non-fatal errors cause a single source file to be skipped.
+The iteration is not aborted but continues with the next file,
+and the exit status is unaffected:
+.Bl -tag -width Ds -offset indent
+.It file Ar filename : reason
+The function
+.Xr fts_read 3
+reported a non-fatal error with respect to
+.Ar filename .
+.It file Ar filename : No not a regular file
+For example, it might be a symbolic link or a device file.
+.It Sy open Ar filename No for reading : Ar reason
+A file below
+.Ar srcdir
+could not be read, for example due to permission problems.
+.It Sy openat Ar filename No for writing : Ar reason
+A file below
+.Ar dstdir
+could not be created or truncated, for example due to permission problems.
+.El
+.Pp
+If errors occur, the applicable summary messages appear
+after the end of the iteration:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It skipped Ar number No directories due to errors
+.It skipped Ar number No files due to errors
+.It processing aborted due to fatal error
+.El
+.Pp
+If the
+.Fl v
+flag is specified, the following summary message also appears:
+.Bl -tag -width Ds -offset indent
+.It processed Ar nfiles No files in Ar ndirs No directories
+A file is counted if it could be opened for reading and the
+corresponding output file could be opened for writing;
+this does not necessarily mean that it is a useful manual page.
+A directory is counted if it could be opened for reading and the
+corresponding output directory existed or could be created;
+this does not necessarily mean that any files could be
+processed inside.
+.El
+.Pp
+If the
+.Fl v
+flag is specified twice, the following messages also appear:
+.Bl -tag -width Ds -offset indent
+.It allowing up to Ar number No files in flight
+This is printed at the beginning of the iteration,
+showing the maximum number of files that
+.Nm
+allows to be in flight at any given time.
+.It files in flight: Ar old No \- Ar decrement No = Ar new
+This message is printed when
+.Nm
+learns about
+.Xr mandocd 8
+accepting more than one file at the same time.
+The three numbers printed are the old number of files in flight,
+the amount this number is being reduced, and the resulting
+new number of files in flight.
+.It waiting for Ar number No files in flight
+This message is printed at the end of the iteration, after
+.Nm
+has submitted all files to
+.Xr mandocd 8
+that it intends to.
+THe message informs about the number of files still in flight
+at this point.
+The
.Nm
-will simply continue with the next file or subdirectory.
+program then waits until
+.Xr mandocd 8
+has accepted them all or until an error occurs.
+.El
.Sh SEE ALSO
.Xr mandoc 1 ,
.Xr mandocd 8
diff --git a/contrib/mandoc/catman.c b/contrib/mandoc/catman.c
index e46613eb0e8c..c9eda18bf71c 100644
--- a/contrib/mandoc/catman.c
+++ b/contrib/mandoc/catman.c
@@ -1,7 +1,7 @@
-/* $Id: catman.c,v 1.23 2021/10/15 15:04:02 schwarze Exp $ */
+/* $Id: catman.c,v 1.30 2025/07/13 14:15:26 schwarze Exp $ */
/*
+ * Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
- * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -25,6 +25,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
+#include <assert.h>
#if HAVE_ERR
#include <err.h>
#endif
@@ -35,26 +36,44 @@
#else
#include "compat_fts.h"
#endif
+#include <signal.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
+int verbose_flag = 0;
+sig_atomic_t got_signal = 0;
+
int process_manpage(int, int, const char *);
int process_tree(int, int);
void run_mandocd(int, const char *, const char *)
__attribute__((__noreturn__));
+void signal_handler(int);
ssize_t sock_fd_write(int, int, int, int);
void usage(void) __attribute__((__noreturn__));
+void
+signal_handler(int signum)
+{
+ got_signal = signum;
+}
+
void
run_mandocd(int sockfd, const char *outtype, const char* defos)
{
char sockfdstr[10];
+ int len;
- if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)
+ len = snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd);
+ if (len >= (int)sizeof(sockfdstr)) {
+ errno = EOVERFLOW;
+ len = -1;
+ }
+ if (len < 0)
err(1, "snprintf");
if (defos == NULL)
execlp("mandocd", "mandocd", "-T", outtype,
@@ -109,10 +128,11 @@ sock_fd_write(int fd, int fd0, int fd1, int fd2)
* to neither cause more than a handful of retries
* in normal operation nor unnecessary delays.
*/
- for (;;) {
- if ((sz = sendmsg(fd, &msg, 0)) != -1 ||
- errno != EAGAIN)
+ while ((sz = sendmsg(fd, &msg, 0)) == -1) {
+ if (errno != EAGAIN) {
+ warn("FATAL: sendmsg");
break;
+ }
nanosleep(&timeout, NULL);
}
return sz;
@@ -125,14 +145,16 @@ process_manpage(int srv_fd, int dstdir_fd, const char *path)
int irc;
if ((in_fd = open(path, O_RDONLY)) == -1) {
- warn("open(%s)", path);
+ warn("open %s for reading", path);
+ fflush(stderr);
return 0;
}
if ((out_fd = openat(dstdir_fd, path,
O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
- warn("openat(%s)", path);
+ warn("openat %s for writing", path);
+ fflush(stderr);
close(in_fd);
return 0;
}
@@ -142,20 +164,22 @@ process_manpage(int srv_fd, int dstdir_fd, const char *path)
close(in_fd);
close(out_fd);
- if (irc < 0) {
- warn("sendmsg");
- return -1;
- }
- return 0;
+ return irc;
}
int
process_tree(int srv_fd, int dstdir_fd)
{
+ const struct timespec timeout = { 0, 10000000 }; /* 0.01 s */
+ const int max_inflight = 16;
+
FTS *ftsp;
FTSENT *entry;
const char *argv[2];
const char *path;
+ int inflight, irc, decr, fatal;
+ int gooddirs, baddirs, goodfiles, badfiles;
+ char dummy[1];
argv[0] = ".";
argv[1] = (char *)NULL;
@@ -166,13 +190,59 @@ process_tree(int srv_fd, int dstdir_fd)
return -1;
}
- while ((entry = fts_read(ftsp)) != NULL) {
+ if (verbose_flag >= 2) {
+ warnx("allowing up to %d files in flight", max_inflight);
+ fflush(stderr);
+ }
+ inflight = fatal = gooddirs = baddirs = goodfiles = badfiles = 0;
+ while (fatal == 0 && got_signal == 0 &&
+ (entry = fts_read(ftsp)) != NULL) {
+ if (inflight >= max_inflight) {
+ while (recv(srv_fd, dummy, sizeof(dummy), 0) == -1) {
+ if (errno != EAGAIN) {
+ warn("FATAL: recv");
+ fatal = errno;
+ break;
+ }
+ nanosleep(&timeout, NULL);
+ }
+ if (fatal != 0)
+ break;
+ decr = 1;
+ while ((irc = recv(srv_fd, dummy, sizeof(dummy),
+ MSG_DONTWAIT)) > 0)
+ decr++;
+ assert(inflight >= decr);
+ if (verbose_flag >= 2 && decr > 1) {
+ warnx("files in flight: %d - %d = %d",
+ inflight, decr, inflight - decr);
+ fflush(stderr);
+ }
+ inflight -= decr;
+ if (irc == 0) {
+ errno = ECONNRESET;
+ inflight = -1;
+ }
+ if (errno != EAGAIN) {
+ warn("FATAL: recv");
+ fatal = errno;
+ break;
+ }
+ }
path = entry->fts_path + 2;
switch (entry->fts_info) {
case FTS_F:
- if (process_manpage(srv_fd, dstdir_fd, path) == -1) {
- fts_close(ftsp);
- return -1;
+ switch (process_manpage(srv_fd, dstdir_fd, path)) {
+ case -1:
+ fatal = errno;
+ break;
+ case 0:
+ badfiles++;
+ break;
+ default:
+ goodfiles++;
+ inflight++;
+ break;
}
break;
case FTS_D:
@@ -180,25 +250,96 @@ process_tree(int srv_fd, int dstdir_fd)
mkdirat(dstdir_fd, path, S_IRWXU | S_IRGRP |
S_IXGRP | S_IROTH | S_IXOTH) == -1 &&
errno != EEXIST) {
- warn("mkdirat(%s)", path);
+ warn("mkdirat %s", path);
+ fflush(stderr);
(void)fts_set(ftsp, entry, FTS_SKIP);
- }
+ baddirs++;
+ } else
+ gooddirs++;
break;
case FTS_DP:
break;
+ case FTS_DNR:
+ warnx("directory %s unreadable: %s",
+ path, strerror(entry->fts_errno));
+ fflush(stderr);
+ baddirs++;
+ break;
+ case FTS_DC:
+ warnx("directory %s causes cycle", path);
+ fflush(stderr);
+ baddirs++;
+ break;
+ case FTS_ERR:
+ case FTS_NS:
+ warnx("file %s: %s",
+ path, strerror(entry->fts_errno));
+ fflush(stderr);
+ badfiles++;
+ break;
default:
- warnx("%s: not a regular file", path);
+ warnx("file %s: not a regular file", path);
+ fflush(stderr);
+ badfiles++;
break;
}
}
+ if (got_signal != 0) {
+ switch (got_signal) {
+ case SIGCHLD:
+ warnx("FATAL: mandocd child died: got SIGCHLD");
+ break;
+ case SIGPIPE:
+ warnx("FATAL: mandocd child died: got SIGPIPE");
+ break;
+ default:
+ warnx("FATAL: signal SIG%s", sys_signame[got_signal]);
+ break;
+ }
+ inflight = -1;
+ fatal = 1;
+ } else if (fatal == 0 && (fatal = errno) != 0)
+ warn("FATAL: fts_read");
fts_close(ftsp);
- return 0;
+ if (verbose_flag >= 2 && inflight > 0) {
+ warnx("waiting for %d files in flight", inflight);
+ fflush(stderr);
+ }
+ while (inflight > 0) {
+ irc = recv(srv_fd, dummy, sizeof(dummy), 0);
+ if (irc > 0)
+ inflight--;
+ else if (irc == -1 && errno == EAGAIN)
+ nanosleep(&timeout, NULL);
+ else {
+ if (irc == 0)
+ errno = ECONNRESET;
+ warn("recv");
+ inflight = -1;
+ }
+ }
+ if (verbose_flag)
+ warnx("processed %d files in %d directories",
+ goodfiles, gooddirs);
+ if (baddirs > 0)
+ warnx("skipped %d %s due to errors", baddirs,
+ baddirs == 1 ? "directory" : "directories");
+ if (badfiles > 0)
+ warnx("skipped %d %s due to errors", badfiles,
+ badfiles == 1 ? "file" : "files");
+ if (fatal != 0) {
+ warnx("processing aborted due to fatal error, "
+ "results are probably incomplete");
+ inflight = -1;
+ }
+ return inflight;
}
int
main(int argc, char **argv)
{
+ struct sigaction sa;
const char *defos, *outtype;
int srv_fds[2];
int dstdir_fd;
@@ -207,7 +348,7 @@ main(int argc, char **argv)
defos = NULL;
outtype = "ascii";
- while ((opt = getopt(argc, argv, "I:T:")) != -1) {
+ while ((opt = getopt(argc, argv, "I:T:v")) != -1) {
switch (opt) {
case 'I':
defos = optarg;
@@ -215,6 +356,9 @@ main(int argc, char **argv)
case 'T':
outtype = optarg;
break;
+ case 'v':
+ verbose_flag += 1;
+ break;
default:
usage();
}
@@ -224,8 +368,36 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
}
- if (argc != 2)
+ if (argc != 2) {
+ switch (argc) {
+ case 0:
+ warnx("missing arguments: srcdir and dstdir");
+ break;
+ case 1:
+ warnx("missing argument: dstdir");
+ break;
+ default:
+ warnx("too many arguments: %s", argv[2]);
+ break;
+ }
usage();
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = &signal_handler;
+ sa.sa_flags = SA_NOCLDWAIT;
+ if (sigfillset(&sa.sa_mask) == -1)
+ err(1, "sigfillset");
+ if (sigaction(SIGHUP, &sa, NULL) == -1)
+ err(1, "sigaction(SIGHUP)");
+ if (sigaction(SIGINT, &sa, NULL) == -1)
+ err(1, "sigaction(SIGINT)");
+ if (sigaction(SIGPIPE, &sa, NULL) == -1)
+ err(1, "sigaction(SIGPIPE)");
+ if (sigaction(SIGTERM, &sa, NULL) == -1)
+ err(1, "sigaction(SIGTERM)");
+ if (sigaction(SIGCHLD, &sa, NULL) == -1)
+ err(1, "sigaction(SIGCHLD)");
if (socketpair(AF_LOCAL, SOCK_STREAM, AF_UNSPEC, srv_fds) == -1)
err(1, "socketpair");
@@ -242,11 +414,18 @@ main(int argc, char **argv)
}
close(srv_fds[1]);
- if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)
- err(1, "open(%s)", argv[1]);
+ if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1) {
+ if (errno != ENOENT)
+ err(1, "open destination %s", argv[1]);
+ if (mkdir(argv[1], S_IRWXU |
+ S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
+ err(1, "mkdir destination %s", argv[1]);
+ if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)
+ err(1, "open destination %s", argv[1]);
+ }
if (chdir(argv[0]) == -1)
- err(1, "chdir(%s)", argv[0]);
+ err(1, "chdir to source %s", argv[0]);
return process_tree(srv_fds[0], dstdir_fd) == -1 ? 1 : 0;
}
diff --git a/contrib/mandoc/gmdiff b/contrib/mandoc/gmdiff
index 69431f703aaf..54025e4cd450 100644
--- a/contrib/mandoc/gmdiff
+++ b/contrib/mandoc/gmdiff
@@ -45,8 +45,8 @@ while [ -n "$1" ]; do
file=$1
shift
echo " ========== $file ========== "
- $ROFF -mandoc $file | $COLPIPE 2> /tmp/roff.err > /tmp/roff.out
- ${MANDOC:=mandoc} $MOPT $file | $COLPIPE \
+ ($ROFF -mandoc $file | $COLPIPE) 2> /tmp/roff.err > /tmp/roff.out
+ (${MANDOC:=mandoc} $MOPT $file | $COLPIPE) \
2> /tmp/mandoc.err > /tmp/mandoc.out
for i in roff mandoc; do
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
diff --git a/contrib/mandoc/man.7 b/contrib/mandoc/man.7
index 4d27c76ba110..91eafbb35f70 100644
--- a/contrib/mandoc/man.7
+++ b/contrib/mandoc/man.7
@@ -1,7 +1,8 @@
-.\" $Id: man.7,v 1.150 2023/10/23 22:57:54 schwarze Exp $
+.\" $Id: man.7,v 1.154 2025/08/05 21:16:20 schwarze Exp $
.\"
+.\" Copyright (c) 2011-2015, 2017-2020, 2023, 2025
+.\" Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2011-2015,2017-2020,2023 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2017 Anthony Bentley <bentley@openbsd.org>
.\" Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
.\"
@@ -17,7 +18,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 23 2023 $
+.Dd $Mdocdate: August 5 2025 $
.Dt MAN 7
.Os
.Sh NAME
@@ -89,7 +90,7 @@ but can be found in the alphabetical reference below.
.Ss Page header and footer meta-data
.Bl -column "RS, RE" description
.It Ic TH Ta set the title: Ar name section date Op Ar source Op Ar volume
-.It Ic AT Ta display AT&T UNIX version in the page footer (<= 1 argument)
+.It Ic AT Ta display AT&T UNIX version in the page footer (<= 2 arguments)
.It Ic UC Ta display BSD version in the page footer (<= 1 argument)
.El
.Ss Sections and paragraphs
@@ -99,6 +100,7 @@ but can be found in the alphabetical reference below.
.It Ic PP Ta start an undecorated paragraph (no arguments)
.It Ic IP Ta indented paragraph: Op Ar head Op Ar width
.It Ic TP Ta tagged paragraph: Op Ar width
+.It Ic HP Ta hanged paragraph: Op Ar width
.It Ic PD Ta set vertical paragraph distance: Op Ar height
.It Ic EX , EE Ta display an example (no arguments)
.It Ic RS , RE Ta reset the left margin: Op Ar width
@@ -198,11 +200,6 @@ argument is a
scaling width.
If specified, it's saved for later paragraph left margins;
if unspecified, the saved or default width is used.
-.Pp
-This macro is portable, but deprecated
-because it has no good representation in HTML output,
-usually ending up indistinguishable from
-.Ic PP .
.It Ic I
Text is rendered in italics.
.It Ic IB
@@ -239,6 +236,17 @@ A synonym for
End a mailto block started with
.Ic MT .
This is a GNU extension.
+.It Ic MR
+Reference another manual page.
+This is a Plan 9 extension also supported by GNU.
+It has the following syntax:
+.Pp
+.D1 Pf . Ic MR Ar name section Op Ar suffix
+.Pp
+The optional, single
+.Ar suffix
+argument is appended without preceding whitespace
+and typically used for trailing punctuation.
.It Ic MT
Begin a mailto block.
This is a GNU extension.
@@ -250,8 +258,12 @@ link description to be shown
.Ed
.It Ic OP
Optional command-line argument.
-This is a rarely used DWB extension.
-It has the following syntax:
+This is a deprecated GNU extension.
+The name and purpose of the macro match an earlier DWB extension,
+but both the syntax and semantics are incompatible.
+In GNU and
+.Xr mandoc 1 ,
+it has the following syntax:
.Pp
.D1 Pf . Ic OP Ar key Op Ar value
.Pp
@@ -503,43 +515,56 @@ raised.
.Pp
The syntax is as follows:
.Bd -literal -offset indent
-\&.YO \(lBbody...\(rB
-\(lBbody...\(rB
+\&.\e" current-line syntax
+\&.YO \(lBbody ...\(rB
+
+\&.\e" next-line syntax
+\&.YO
+body ...
.Ed
-.Bl -column "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX" -offset indent
-.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
-.It Ic AT Ta <=1 Ta current Ta \&
-.It Ic B Ta n Ta next-line Ta \&
-.It Ic BI Ta n Ta current Ta \&
-.It Ic BR Ta n Ta current Ta \&
-.It Ic DT Ta 0 Ta current Ta \&
-.It Ic EE Ta 0 Ta current Ta Version 9 At
-.It Ic EX Ta 0 Ta current Ta Version 9 At
-.It Ic I Ta n Ta next-line Ta \&
-.It Ic IB Ta n Ta current Ta \&
-.It Ic IR Ta n Ta current Ta \&
-.It Ic OP Ta >=1 Ta current Ta DWB
-.It Ic PD Ta 1 Ta current Ta \&
-.It Ic RB Ta n Ta current Ta \&
-.It Ic RI Ta n Ta current Ta \&
-.It Ic SB Ta n Ta next-line Ta \&
-.It Ic SM Ta n Ta next-line Ta \&
-.It Ic TH Ta >1, <6 Ta current Ta \&
-.It Ic UC Ta <=1 Ta current Ta \&
-.It Ic in Ta 1 Ta current Ta Xr roff 7
+.Bl -column -offset indent\
+ "Macro" "Arguments" "curr and next" "Version 9 AT&T UNIX"
+.It Em Macro Ta Em Arguments Ta Em Line Scope Ta Em Notes
+.It Ic AT Ta 0 to 2 Ta current Ta \&
+.It Ic B Ta 1 or more Ta curr or next Ta \&
+.It Ic BI Ta 2 or more Ta current Ta \&
+.It Ic BR Ta 2 or more Ta current Ta \&
+.It Ic DT Ta 0 Ta none Ta \&
+.It Ic EE Ta 0 Ta none Ta Version 9 At
+.It Ic EX Ta 0 Ta none Ta Version 9 At
+.It Ic I Ta 1 or more Ta curr or next Ta \&
+.It Ic IB Ta 2 or more Ta current Ta \&
+.It Ic IR Ta 2 or more Ta current Ta \&
+.It Ic MR Ta 2 or 3 Ta current Ta Plan 9
+.It Ic OP Ta 1 or 2 Ta current Ta GNU
+.It Ic PD Ta 0 or 1 Ta current Ta \&
+.It Ic RB Ta 2 or more Ta current Ta \&
+.It Ic RI Ta 2 or more Ta current Ta \&
+.It Ic SB Ta 1 or more Ta curr or next Ta \&
+.It Ic SM Ta 1 or more Ta curr or next Ta \&
+.It Ic TH Ta 3 to 5 Ta current Ta \&
+.It Ic UC Ta 0 or 1 Ta current Ta \&
+.It Ic in Ta 0 or 1 Ta current Ta Xr roff 7
.El
.Ss Block Macros
Block macros comprise a head and body.
-As with in-line macros, the head is scoped to the current line and, in
-one circumstance, the next line (the next-line stipulations as in
+As with in-line macros, the head is scoped to the current line or,
+for some macros, to the next line (the next-line stipulations as in
.Sx Line Macros
apply here as well).
.Pp
The syntax is as follows:
.Bd -literal -offset indent
-\&.YO \(lBhead...\(rB
-\(lBhead...\(rB
-\(lBbody...\(rB
+\&.\e" current-line syntax
+\&.YO \(lBhead ...\(rB
+body ...
+\&...
+
+\&.\e" next-line syntax
+\&.YO \(lBhead\(rB
+head ...
+body ...
+\&...
.Ed
.Pp
The closure of body scope may be to the section, where a macro is closed
@@ -547,40 +572,42 @@ by
.Ic SH ;
sub-section, closed by a section or
.Ic SS ;
-or paragraph, closed by a section, sub-section,
+paragraph, closed by a section, sub-section,
.Ic HP ,
.Ic IP ,
.Ic LP ,
.Ic P ,
.Ic PP ,
-.Ic RE ,
+.Ic RS ,
.Ic SY ,
+.Ic TP ,
or
-.Ic TP .
-No closure refers to an explicit block closing macro.
+.Ic TQ ;
+or to an explicit block closing macro.
.Pp
As a rule, block macros may not be nested; thus, calling a block macro
while another block macro scope is open, and the open scope is not
implicitly closed, is syntactically incorrect.
-.Bl -column "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX" -offset indent
-.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
-.It Ic HP Ta <2 Ta current Ta paragraph Ta \&
-.It Ic IP Ta <3 Ta current Ta paragraph Ta \&
-.It Ic LP Ta 0 Ta current Ta paragraph Ta \&
-.It Ic ME Ta 0 Ta none Ta none Ta GNU
-.It Ic MT Ta 1 Ta current Ta to \&ME Ta GNU
-.It Ic P Ta 0 Ta current Ta paragraph Ta \&
-.It Ic PP Ta 0 Ta current Ta paragraph Ta \&
-.It Ic RE Ta <=1 Ta current Ta none Ta \&
-.It Ic RS Ta 1 Ta current Ta to \&RE Ta \&
-.It Ic SH Ta >0 Ta next-line Ta section Ta \&
-.It Ic SS Ta >0 Ta next-line Ta sub-section Ta \&
-.It Ic SY Ta 1 Ta current Ta to \&YS Ta GNU
-.It Ic TP Ta n Ta next-line Ta paragraph Ta \&
-.It Ic TQ Ta n Ta next-line Ta paragraph Ta GNU
-.It Ic UE Ta 0 Ta current Ta none Ta GNU
-.It Ic UR Ta 1 Ta current Ta part Ta GNU
-.It Ic YS Ta 0 Ta none Ta none Ta GNU
*** 3592 LINES SKIPPED ***