Files
patches/mandoc/mandoc-1.14.6-zstd-manpages.patch
T
SFG545 accdf3d3fb Add runtime compatibility patch set
Add an LLVM 22.1.6 runtimes patch for building libc++, libc++abi, and llvm-libgcc together. The patch lets libc++abi accept llvm-libgcc as the provider of the LLVM unwinder, keeps the libgcc_s version script private to libunwind so it does not leak into libc++abi links, and adds an opt-out for building compiler-rt inside llvm-libgcc when an exported external builtins archive is available.

Add libxcrypt patches for current Clang/glibc builds: avoid treating Clang as old GCC in yescrypt assembly selection and adjust yescrypt strchr call sites for the newer glibc const-correct prototype behavior.

Add a mandoc 1.14.6 patch for zstd-compressed manual pages, including configure checks, linker flags, documentation, section matching, and decompression handling.

Remove the obsolete Perl 5.42.2 LBI patch from the patch set.
2026-05-29 22:23:57 -05:00

461 lines
12 KiB
Diff

diff -ruN a/INSTALL b/INSTALL
--- a/INSTALL 2021-09-23 13:03:23.000000000 -0500
+++ b/INSTALL 2026-05-29 18:09:12.237717849 -0500
@@ -103,7 +103,9 @@
1. zlib for decompressing gzipped manual pages.
-2. The fts(3) directory traversion functions.
+2. libzstd for decompressing zstd-compressed manual pages.
+
+3. The fts(3) directory traversion functions.
If your system does not have them, the bundled compatibility version
will be used, so you need not worry in that case. But be careful: old
glibc versions of fts(3) were known to be broken on 32bit platforms,
@@ -111,7 +113,7 @@
That was presumably fixed in glibc-2.23.
If you run into that problem, set "HAVE_FTS=0" in configure.local.
-3. Marc Espie's ohash(3) library.
+4. Marc Espie's ohash(3) library.
If your system does not have it, the bundled compatibility version
will be used, so you probably need not worry about it.
diff -ruN a/Makefile b/Makefile
--- a/Makefile 2021-09-23 13:03:23.000000000 -0500
+++ b/Makefile 2026-05-29 18:06:59.682203510 -0500
@@ -54,7 +54,8 @@
test-strsep.c \
test-strtonum.c \
test-vasprintf.c \
- test-wchar.c
+ test-wchar.c \
+ test-zstd.c
SRCS = arch.c \
att.c \
diff -ruN a/configure b/configure
--- a/configure 2021-09-23 13:03:23.000000000 -0500
+++ b/configure 2026-05-29 18:06:59.682203510 -0500
@@ -50,6 +50,7 @@
LD_NANOSLEEP=
LD_OHASH=
LD_RECVMSG=
+LD_ZSTD=-lzstd
STATIC=
BUILD_CGI=0
@@ -94,6 +95,7 @@
HAVE_SYS_ENDIAN=
HAVE_VASPRINTF=
HAVE_WCHAR=
+HAVE_ZSTD=
NEED_GNU_SOURCE=0
NEED_OPENBSD_SOURCE=0
@@ -331,6 +333,7 @@
runtest strsep STRSEP || true
runtest strtonum STRTONUM "" -D_OPENBSD_SOURCE || true
runtest vasprintf VASPRINTF "" -D_GNU_SOURCE || true
+runtest zstd ZSTD "${LD_ZSTD}" || true
# --- fts ---
if [ "${1}" = "-depend" ]; then
@@ -415,6 +418,11 @@
echo "FATAL: nanosleep: no" 1>&3
FATAL=1
fi
+if [ "${HAVE_ZSTD}" -eq 0 ]; then
+ echo "FATAL: zstd: no" 1>&2
+ echo "FATAL: zstd: no" 1>&3
+ FATAL=1
+fi
if [ ${BUILD_CATMAN} -gt 0 -a "${HAVE_RECVMSG}" -eq 0 ]; then
echo "FATAL: recvmsg: no" 1>&2
echo "FATAL: recvmsg: no" 1>&3
@@ -430,7 +438,7 @@
[ "${FATAL}" -eq 0 ] || exit 1
# --- LDADD ---
-LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz"
+LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz ${LD_ZSTD}"
echo "selected LDADD=\"${LDADD}\"" 1>&2
echo "selected LDADD=\"${LDADD}\"" 1>&3
echo 1>&3
@@ -506,6 +514,7 @@
#define HAVE_SYS_ENDIAN ${HAVE_SYS_ENDIAN}
#define HAVE_VASPRINTF ${HAVE_VASPRINTF}
#define HAVE_WCHAR ${HAVE_WCHAR}
+#define HAVE_ZSTD ${HAVE_ZSTD}
#define HAVE_OHASH ${HAVE_OHASH}
#define NEED_XPG4_2 ${NEED_XPG4_2}
diff -ruN a/main.c b/main.c
--- a/main.c 2021-09-23 13:03:23.000000000 -0500
+++ b/main.c 2026-05-29 18:08:19.108307544 -0500
@@ -538,7 +538,10 @@
prio += 10; /* Wrong dir name. */
if (search.sec != NULL) {
ep = strchr(sec, '\0');
- if (ep - sec > 3 &&
+ if (ep - sec > 4 &&
+ strncmp(ep - 4, ".zst", 4) == 0)
+ ep -= 4;
+ else if (ep - sec > 3 &&
strncmp(ep - 3, ".gz", 3) == 0)
ep -= 3;
if ((size_t)(ep - sec) < ssz + 3 ||
diff -ruN a/mandoc.3 b/mandoc.3
--- a/mandoc.3 2021-09-23 13:03:23.000000000 -0500
+++ b/mandoc.3 2026-05-29 18:09:19.497910732 -0500
@@ -273,10 +273,14 @@
If that fails and
.Fa fname
does not already end in
-.Ql .gz ,
+.Ql .gz
+or
+.Ql .zst ,
try again after appending
-.Ql .gz .
-Save the information whether the file is zipped or not.
+.Ql .gz
+and
+.Ql .zst .
+Save the information whether the file is compressed or not.
Return a file descriptor open for reading or -1 on failure.
It can be passed to
.Fn mparse_readfd
diff -ruN a/mandocdb.c b/mandocdb.c
--- a/mandocdb.c 2021-09-23 13:03:23.000000000 -0500
+++ b/mandocdb.c 2026-05-29 18:09:00.199398109 -0500
@@ -102,7 +102,7 @@
char *fsec; /* section from file name suffix */
struct mlink *next; /* singly linked list */
struct mpage *mpage; /* parent */
- int gzip; /* filename has a .gz suffix */
+ int gzip; /* filename has a compression suffix */
enum form dform; /* format from directory */
enum form fform; /* format from file name suffix */
};
@@ -580,7 +580,7 @@
FTS *f;
FTSENT *ff;
struct mlink *mlink;
- int gzip;
+ int compressed;
enum form dform;
char *dsec, *arch, *fsec, *cp;
const char *path;
@@ -645,13 +645,15 @@
say(path, "Extraneous file");
continue;
}
- gzip = 0;
+ compressed = 0;
fsec = NULL;
while (fsec == NULL) {
fsec = strrchr(ff->fts_name, '.');
- if (fsec == NULL || strcmp(fsec+1, "gz"))
+ if (fsec == NULL ||
+ (strcmp(fsec + 1, "gz") &&
+ strcmp(fsec + 1, "zst")))
break;
- gzip = 1;
+ compressed = 1;
*fsec = '\0';
fsec = NULL;
}
@@ -697,7 +699,7 @@
mlink->arch = arch;
mlink->name = ff->fts_name;
mlink->fsec = fsec;
- mlink->gzip = gzip;
+ mlink->gzip = compressed;
mlink_add(mlink, ff->fts_statp);
continue;
@@ -962,9 +964,19 @@
* Now check the file suffix.
* Suffix of `.0' indicates a catpage, `.1-9' is a manpage.
*/
- p = strrchr(start, '\0');
- while (p-- > start && *p != '/' && *p != '.')
- continue;
+ if ((p = strrchr(start, '/')) == NULL)
+ p = start;
+ else
+ p++;
+ if ((p = strrchr(p, '.')) != NULL &&
+ (strcmp(p + 1, "gz") == 0 || strcmp(p + 1, "zst") == 0))
+ *p = '\0';
+
+ for (p = strchr(start, '\0'); p > start; ) {
+ p--;
+ if (*p == '/' || *p == '.')
+ break;
+ }
if (*p == '.') {
*p++ = '\0';
@@ -1213,6 +1225,12 @@
mlink_dest = ohash_find(&mlinks,
ohash_qlookup(&mlinks, cp));
free(cp);
+ }
+ if (mlink_dest == NULL) {
+ mandoc_asprintf(&cp, "%s.zst", meta->sodest);
+ mlink_dest = ohash_find(&mlinks,
+ ohash_qlookup(&mlinks, cp));
+ free(cp);
}
if (mlink_dest != NULL) {
diff -ruN a/read.c b/read.c
--- a/read.c 2021-09-23 13:03:23.000000000 -0500
+++ b/read.c 2026-05-29 18:09:41.222488117 -0500
@@ -38,6 +38,7 @@
#include <string.h>
#include <unistd.h>
#include <zlib.h>
+#include <zstd.h>
#include "mandoc_aux.h"
#include "mandoc.h"
@@ -60,6 +61,7 @@
const char *os_s; /* default operating system */
int options; /* parser options */
int gzip; /* current input file is gzipped */
+ int zstd; /* current input file is zstd-compressed */
int filenc; /* encoding of the current file */
int reparse_count; /* finite interp. stack */
int line; /* line number in the file */
@@ -70,6 +72,7 @@
static void resize_buf(struct buf *, size_t);
static int mparse_buf_r(struct mparse *, struct buf, size_t, int);
static int read_whole_file(struct mparse *, int, struct buf *, int *);
+static int read_zstd_file(struct mparse *, int, struct buf *);
static void mparse_end(struct mparse *);
@@ -432,6 +435,89 @@
}
static int
+read_zstd_file(struct mparse *curp, int fd, struct buf *fb)
+{
+ ZSTD_DStream *zds;
+ ZSTD_inBuffer zin;
+ ZSTD_outBuffer zout;
+ char *ibuf;
+ size_t ibufsz, off, ret;
+ ssize_t ssz;
+ int eof, retval;
+
+ if ((zds = ZSTD_createDStream()) == NULL) {
+ mandoc_msg(MANDOCERR_READ, 0, 0,
+ "zstd: unable to allocate decompressor");
+ return -1;
+ }
+
+ ibufsz = ZSTD_DStreamInSize();
+ ibuf = mandoc_malloc(ibufsz);
+ zin.src = ibuf;
+ zin.size = 0;
+ zin.pos = 0;
+
+ fb->sz = 0;
+ fb->buf = NULL;
+ off = 0;
+ ret = 1;
+ eof = 0;
+ retval = -1;
+
+ while (eof == 0 || zin.pos < zin.size) {
+ if (zin.pos == zin.size && eof == 0) {
+ if ((ssz = read(fd, ibuf, ibufsz)) == -1) {
+ mandoc_msg(MANDOCERR_READ, 0, 0,
+ "%s", strerror(errno));
+ goto out;
+ }
+ if (ssz == 0) {
+ eof = 1;
+ continue;
+ }
+ zin.size = (size_t)ssz;
+ zin.pos = 0;
+ }
+
+ if (off == fb->sz) {
+ if (fb->sz == (1U << 31)) {
+ mandoc_msg(MANDOCERR_TOOLARGE, 0, 0, NULL);
+ goto out;
+ }
+ resize_buf(fb, 65536);
+ }
+
+ zout.dst = fb->buf + off;
+ zout.size = fb->sz - off;
+ zout.pos = 0;
+ ret = ZSTD_decompressStream(zds, &zout, &zin);
+ if (ZSTD_isError(ret)) {
+ mandoc_msg(MANDOCERR_READ, 0, 0,
+ "zstd: %s", ZSTD_getErrorName(ret));
+ goto out;
+ }
+ off += zout.pos;
+ }
+
+ if (ret != 0)
+ mandoc_msg(MANDOCERR_READ, 0, 0,
+ "zstd: unexpected end of file");
+ else {
+ fb->sz = off;
+ retval = 0;
+ }
+
+out:
+ free(ibuf);
+ ZSTD_freeDStream(zds);
+ if (retval == -1) {
+ free(fb->buf);
+ fb->buf = NULL;
+ }
+ return retval;
+}
+
+static int
read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
{
struct stat st;
@@ -452,7 +538,7 @@
* concerned that this is going to tank any machines.
*/
- if (curp->gzip == 0 && S_ISREG(st.st_mode)) {
+ if (curp->gzip == 0 && curp->zstd == 0 && S_ISREG(st.st_mode)) {
if (st.st_size > 0x7fffffff) {
mandoc_msg(MANDOCERR_TOOLARGE, 0, 0, NULL);
return -1;
@@ -464,6 +550,11 @@
return 0;
}
+ if (curp->zstd) {
+ *with_mmap = 0;
+ return read_zstd_file(curp, fd, fb);
+ }
+
if (curp->gzip) {
/*
* Duplicating the file descriptor is required
@@ -557,7 +648,7 @@
struct buf blk;
struct buf *save_primary;
- const char *save_filename, *cp;
+ const char *save_filename, *cp, *ep;
size_t offset;
int save_filenc, save_lineno;
int with_mmap;
@@ -565,12 +656,26 @@
if (recursion_depth > 64) {
mandoc_msg(MANDOCERR_ROFFLOOP, curp->line, 0, NULL);
return;
- } else if (recursion_depth == 0 &&
- (cp = strrchr(filename, '.')) != NULL &&
- cp[1] >= '1' && cp[1] <= '9')
- curp->man->filesec = cp[1];
- else
- curp->man->filesec = '\0';
+ } else if (recursion_depth == 0) {
+ ep = strrchr(filename, '.');
+ if (ep != NULL &&
+ (strcmp(ep + 1, "gz") == 0 ||
+ strcmp(ep + 1, "zst") == 0)) {
+ for (cp = ep; cp > filename; cp--)
+ if (cp[-1] == '.') {
+ cp--;
+ break;
+ }
+ if (cp == filename)
+ cp = NULL;
+ } else
+ cp = ep;
+ if (cp != NULL && cp[1] >= '1' && cp[1] <= '9')
+ curp->man->filesec = cp[1];
+ else
+ curp->man->filesec = '\0';
+ } else
+ curp->man->filesec = '\0';
if (read_whole_file(curp, fd, &blk, &with_mmap) == -1)
return;
@@ -623,11 +728,13 @@
int
mparse_open(struct mparse *curp, const char *file)
{
+ const char *ep;
char *cp;
int fd, save_errno;
- cp = strrchr(file, '.');
- curp->gzip = (cp != NULL && ! strcmp(cp + 1, "gz"));
+ ep = strrchr(file, '.');
+ curp->gzip = (ep != NULL && ! strcmp(ep + 1, "gz"));
+ curp->zstd = (ep != NULL && ! strcmp(ep + 1, "zst"));
/* First try to use the filename as it is. */
@@ -635,20 +742,27 @@
return fd;
/*
- * If that doesn't work and the filename doesn't
- * already end in .gz, try appending .gz.
+ * If that doesn't work and the filename doesn't already
+ * end in .gz or .zst, try appending these suffixes.
*/
- if ( ! curp->gzip) {
+ if ( ! curp->gzip && ! curp->zstd) {
save_errno = errno;
mandoc_asprintf(&cp, "%s.gz", file);
fd = open(cp, O_RDONLY);
free(cp);
- errno = save_errno;
if (fd != -1) {
curp->gzip = 1;
return fd;
}
+ mandoc_asprintf(&cp, "%s.zst", file);
+ fd = open(cp, O_RDONLY);
+ free(cp);
+ errno = save_errno;
+ if (fd != -1) {
+ curp->zstd = 1;
+ return fd;
+ }
}
/* Neither worked, give up. */
@@ -693,6 +807,7 @@
free_buf_list(curp->secondary);
curp->secondary = NULL;
curp->gzip = 0;
+ curp->zstd = 0;
tag_alloc();
}
diff -ruN a/test-zstd.c b/test-zstd.c
--- a/test-zstd.c 1969-12-31 18:00:00.000000000 -0600
+++ b/test-zstd.c 2026-05-29 18:06:59.682203510 -0500
@@ -0,0 +1,7 @@
+#include <zstd.h>
+
+int
+main(void)
+{
+ return ZSTD_versionNumber() == 0;
+}