darwin.libsbuf: init at 14.1

libsbuf is required by some of the source release updates that will
be done. Unfortunately, it is only available on macOS 14 and newer, and
there is no source release available currently.

This is a port of libsbuf from FreeBSD, which appears to be the origin
of the header provided in the 14.x SDK. It provides the same ABI as the
system dylib and same API as the the SDK header while being available on
all supported deployment targets in nixpkgs.

Note: This package is not based on libsbuf from the FreeBSD package set
in nixpkgs because: it doesn’t build on Darwin, and using it would pull
many FreeBSD packages into the Darwin bootstrap, which is undesirable.
This commit is contained in:
Randy Eckenrode 2024-09-21 09:34:47 -04:00
parent 6a54c7f6c9
commit 639108ea70
No known key found for this signature in database
GPG Key ID: 64C1CD4EC2A600D9
4 changed files with 241 additions and 0 deletions

View File

@ -341,4 +341,6 @@ developerToolsPackages_11_3_1 // macosPackages_11_0_1 // {
# TODO(matthewbauer):
# To be removed, once I figure out how to build a newer Security version.
Security = applePackage "Security/boot.nix" "osx-10.9.5" "sha256-7qr0IamjCXCobIJ6V9KtvbMBkJDfRCy4C5eqpHJlQLI=" {};
libsbuf = callPackage ./libsbuf/package.nix { };
}

View File

@ -0,0 +1,17 @@
# Project settings
project('libsbuf', 'c', version : '@version@')
# Libraries
library(
'sbuf',
darwin_versions : '1',
install : true,
sources : [
'subr_prf.c',
'subr_sbuf.c',
],
soversion : '6',
)
install_headers('usbuf.h')
install_man('sbuf.9')

View File

@ -0,0 +1,85 @@
{
lib,
bootstrapStdenv,
fetchurl,
meson,
ninja,
stdenv,
}:
# Apple ships libsbuf with macOS 14 but does not provide any source releases.
# Fortunately, its a single file library that can be made to build on Darwin using the source from FreeBSD.
bootstrapStdenv.mkDerivation (finalAttrs: {
pname = "libsbuf";
version = "14.1.0";
outputs = [
"out"
"dev"
"man"
];
srcs = [
(fetchurl {
name = "subr_sbuf.c";
url = "https://cgit.freebsd.org/src/plain/sys/kern/subr_sbuf.c?h=release/${finalAttrs.version}";
hash = "sha256-+wIcXz2wuYzOXmbxjDYBh7lIpoVtw+SW/l7oMXFJUcc=";
})
(fetchurl {
name = "subr_prf.c";
url = "https://cgit.freebsd.org/src/plain/sys/kern/subr_prf.c?h=release/${finalAttrs.version}";
hash = "sha256-Sd+kJ7/RwwndK1N6YvqQqPTQRA0ajPAT0yk0rOPRpW8=";
})
(fetchurl {
name = "usbuf.h";
url = "https://cgit.freebsd.org/src/plain/sys/sys/sbuf.h?h=release/${finalAttrs.version}";
hash = "sha256-CCwh9kI/X1u16hHWiiBipvBzDKvo2S2OFtI4Jo6HF0E=";
})
(fetchurl {
name = "sbuf.9";
url = "https://cgit.freebsd.org/src/plain/share/man/man9/sbuf.9?h=release/${finalAttrs.version}";
hash = "sha256-43uUIGvYX0NvikcGTTJHrokHvubQ89ztLv/BK3MP0YY=";
})
];
sourceRoot = "source";
unpackPhase = ''
runHook preUnpack
mkdir "$sourceRoot"
for src in "''${srcs[@]}"; do
destFilename=$(basename "$src")
cp "$src" "$sourceRoot/''${src#*-}"
done
runHook postUnpack
'';
patches = [
# Fix up sources to build on Darwin and follow the same ABI used by Apple.
./patches/0001-darwin-compatibility.patch
];
postPatch = lib.optionalString stdenv.hostPlatform.isDarwin ''
substitute '${./meson.build.in}' "meson.build" --subst-var version
'';
strictDeps = true;
nativeBuildInputs = [
meson
ninja
];
__structuredAttrs = true;
meta = {
description = "Safely compose and manipulate strings in C";
homepage = "https://www.freebsd.org";
license = [
lib.licenses.bsd2
lib.licenses.bsd3
];
};
})

View File

@ -0,0 +1,137 @@
diff '--color=auto' -ur a/subr_prf.c b/subr_prf.c
--- a/subr_prf.c 2024-09-04 20:07:10.149623000 -0400
+++ b/subr_prf.c 2024-09-04 20:14:10.265336775 -0400
@@ -64,8 +64,8 @@
#else /* !_KERNEL */
#include <errno.h>
#endif
-#include <sys/ctype.h>
-#include <sys/sbuf.h>
+#include <ctype.h>
+#include <usbuf.h>
#ifdef DDB
#include <ddb/ddb.h>
diff '--color=auto' -ur a/subr_sbuf.c b/subr_sbuf.c
--- a/subr_sbuf.c 2024-09-04 20:07:10.149810000 -0400
+++ b/subr_sbuf.c 2024-09-04 20:22:20.289037135 -0400
@@ -50,7 +50,7 @@
#include <string.h>
#endif /* _KERNEL */
-#include <sys/sbuf.h>
+#include <usbuf.h>
#ifdef _KERNEL
static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
@@ -96,6 +96,18 @@
#define SBUF_MAXEXTENDINCR 4096
#endif
+/* Per https://cgit.freebsd.org/src/commit/?id=8fa6abb6f4f64f4f23e2920e2aea7996566851a4 */
+#define roundup2 __builtin_align_up
+/* From https://cgit.freebsd.org/src/tree/sys/sys/cdefs.h?id=8fa6abb6f4f64f4f23e2920e2aea7996566851a4 */
+#define __predict_false(exp) __builtin_expect((exp),0)
+
+/* These symbols are exported even though the functions arent defined in the public header.
+ Redefine them for consistency. */
+#define sbuf_count_drain usbuf_count_drain
+#define sbuf_drain usbuf_drain
+#define sbuf_nl_terminate usbuf_nl_terminate
+#define sbuf_put_bytes usbuf_put_bytes
+
/*
* Debugging support
*/
diff '--color=auto' -ur a/usbuf.h b/usbuf.h
--- a/usbuf.h 2024-09-04 20:07:10.150177000 -0400
+++ b/usbuf.h 2024-09-04 20:13:26.469610458 -0400
@@ -33,6 +33,50 @@
#include <sys/_types.h>
+#include <stdarg.h>
+
+#define sbuf_new usbuf_new
+#define sbuf_clear usbuf_clear
+#define sbuf_setpos usbuf_setpos
+#define sbuf_bcat usbuf_bcat
+#define sbuf_bcpy usbuf_bcpy
+#define sbuf_cat usbuf_cat
+#define sbuf_cpy usbuf_cpy
+#define sbuf_printf usbuf_printf
+#define sbuf_vprintf usbuf_vprintf
+#define sbuf_putc usbuf_putc
+#define sbuf_set_drain usbuf_set_drain
+#define sbuf_trim usbuf_trim
+#define sbuf_error usbuf_error
+#define sbuf_finish usbuf_finish
+#define sbuf_data usbuf_data
+#define sbuf_len usbuf_len
+#define sbuf_done usbuf_done
+#define sbuf_delete usbuf_delete
+#define sbuf_clear_flags usbuf_clear_flags
+#define sbuf_get_flags usbuf_get_flags
+#define sbuf_set_flags usbuf_set_flags
+#define sbuf_start_section usbuf_start_section
+#define sbuf_end_section usbuf_end_section
+#define sbuf_hexdump usbuf_hexdump
+#define sbuf_putbuf usbuf_putbuf
+#define sbuf_printf_drain usbuf_printf_drain
+
+#define SBUF_FIXEDLEN USBUF_FIXEDLEN
+#define SBUF_AUTOEXTEND USBUF_AUTOEXTEND
+#define SBUF_INCLUDENUL USBUF_INCLUDENUL
+#define SBUF_DRAINTOEOR USBUF_DRAINTOEOR
+#define SBUF_NOWAIT USBUF_NOWAIT
+#define SBUF_USRFLAGMSK USBUF_USRFLAGMSK
+#define SBUF_DYNAMIC USBUF_DYNAMIC
+#define SBUF_FINISHED USBUF_FINISHED
+#define SBUF_DYNSTRUCT USBUF_DYNSTRUCT
+#define SBUF_INSECTION USBUF_INSECTION
+#define SBUF_DRAINATEOL USBUF_DRAINATEOL
+
+#define sbuf usbuf
+#define sbuf_drain_func usbuf_drain_func
+
struct sbuf;
typedef int (sbuf_drain_func)(void *, const char *, int);
@@ -46,17 +90,17 @@
int s_error; /* current error code */
ssize_t s_size; /* size of storage buffer */
ssize_t s_len; /* current length of string */
-#define SBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */
-#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
-#define SBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */
-#define SBUF_DRAINTOEOR 0x00000004 /* use section 0 as drain EOR marker */
-#define SBUF_NOWAIT 0x00000008 /* Extend with non-blocking malloc */
-#define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
-#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
-#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
-#define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */
-#define SBUF_INSECTION 0x00100000 /* set by sbuf_start_section() */
-#define SBUF_DRAINATEOL 0x00200000 /* drained contents ended in \n */
+#define USBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */
+#define USBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
+#define USBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */
+#define USBUF_DRAINTOEOR 0x00000004 /* use section 0 as drain EOR marker */
+#define USBUF_NOWAIT 0x00000008 /* Extend with non-blocking malloc */
+#define USBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */
+#define USBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
+#define USBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
+#define USBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */
+#define USBUF_INSECTION 0x00100000 /* set by sbuf_start_section() */
+#define USBUF_DRAINATEOL 0x00200000 /* drained contents ended in \n */
int s_flags; /* flags */
ssize_t s_sect_len; /* current length of section */
ssize_t s_rec_off; /* current record start offset */
@@ -88,7 +132,7 @@
int sbuf_cpy(struct sbuf *, const char *);
int sbuf_printf(struct sbuf *, const char *, ...)
__printflike(2, 3);
-int sbuf_vprintf(struct sbuf *, const char *, __va_list)
+int sbuf_vprintf(struct sbuf *, const char *, va_list)
__printflike(2, 0);
int sbuf_nl_terminate(struct sbuf *);
int sbuf_putc(struct sbuf *, int);