From nobody Fri Feb 6 00:31:51 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f6Zlr04lBz6RS7d for ; Fri, 06 Feb 2026 00:31:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f6Zlq3YvCz43qN for ; Fri, 06 Feb 2026 00:31:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770337911; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5LH5nIK31pjrZ5t1Liz5XpSGXaKllYEmKa/LpLF68Ys=; b=i/sAQIegxZPjtlWAcq2PAsk3x5spiOIdNPkoH4cwkZGrxofhll+x6CGqgYRGyaxIbnVo7e E2xQhlOFKiiOJOiob9/aK44QjaTAI1l4lwciVe8FJcH7tx+wl7xQMVjZ4V/uWXj7bagr3h EIjtW6u1fLEq/2eO6JzbTEPFD2DWf76PIcyxzRYs6iho8fOGljs7+U32C9x41Et1MqMcI9 mr7FN3y6BAUYIwNHJDIx6BqsACnPcPODMKfzQVXvF6E+N8OgL80CmJt2UaMgee9IV4aPG6 i0ec+ixSBKhO+ddKQZp0joasMVhCnDkfM1irIZ/NabuG1J6aLYOkbRnA08dgzQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1770337911; a=rsa-sha256; cv=none; b=lnpLHKURgwaWDR0p2e5TwmuidSpw3+RxIs67Khb42aBl6fWYbgkv/fODQIpQSGA6agYbbo +d8ABXasQplG/1t/OdtAU7lscdp9pIvjYDWz6itOgTATk23XTW2Sz1qlXz+HDGnD1uO27B r98Uiu6sTeqBzUVanejeQhELheaPFmanUstKJkg5arffmps3bQt+Mn3356AHllmBk9s+C1 cB6PLnXAAX1+hSkPdI+dervchRevuz/JXfoasbizpf5QfisVJj1ayyuwQSfF7C7KM6CiZA T6tKQNUrhQThwTJqEvroj4vth7UqAPcqDWhpJmKdnuI1MzKCIVNevdn2rluw6g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770337911; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5LH5nIK31pjrZ5t1Liz5XpSGXaKllYEmKa/LpLF68Ys=; b=duKofmwYth0sDdNK22UfgT9LD1UwA0TGobn6YVSPrlVO/lCeyFDjj9uX+yXJjdLsjk3FCt VZ0qZe+xFHxgiPafo4SHVIaSPUO5Eql6B/N7z0HeI5OlrzPQYnhOOwjf2wnMd0Pwc39nt+ vdJl4+BMPMNff6OdRiiBIuxXHl8ZcWc6oVmThxBMGd6ckKyZ3tGLSl+tDnQ64Te0SEGQb6 pYNShNzqFCgwBczSfkrUmcy1bULl7IYIHMZZCeE5UKNJ7WVdmfwuokAheDbntT5Vqedg45 l+BpyibF7ZtHbXK5r8/II8Ip0ZVBElXS0DsKoSQnu9WnPJ5J4hRF/jZ1A+h1Kw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f6Zlq2t4Dzt8W for ; Fri, 06 Feb 2026 00:31:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3136f by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 06 Feb 2026 00:31:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alexander Ziaee Subject: git: a1f4ccd6c794 - stable/14 - mandoc: Vendor import of upstream at 2025-07-27 List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ziaee X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: a1f4ccd6c79470eb0180f4d9a012b24c267d2574 Auto-Submitted: auto-generated Date: Fri, 06 Feb 2026 00:31:51 +0000 Message-Id: <69853677.3136f.67cd70e@gitrepo.freebsd.org> The branch stable/14 has been updated by ziaee: URL: https://cgit.FreeBSD.org/src/commit/?id=a1f4ccd6c79470eb0180f4d9a012b24c267d2574 commit a1f4ccd6c79470eb0180f4d9a012b24c267d2574 Author: Alexander Ziaee AuthorDate: 2025-08-15 19:03:22 +0000 Commit: Alexander Ziaee 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 +.\" Copyright (c) 2017, 2025 Ingo Schwarze .\" .\" 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 * Copyright (c) 2017 Michael Stapelberg - * Copyright (c) 2017 Ingo Schwarze * * 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 #include +#include #if HAVE_ERR #include #endif @@ -35,26 +36,44 @@ #else #include "compat_fts.h" #endif +#include +#include #include #include #include #include #include +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 .\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons -.\" Copyright (c) 2011-2015,2017-2020,2023 Ingo Schwarze .\" Copyright (c) 2017 Anthony Bentley .\" Copyright (c) 2010 Joerg Sonnenberger .\" @@ -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 ***