diff options
Diffstat (limited to 'lib/libc')
127 files changed, 1637 insertions, 2344 deletions
diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 34474cfa9fe4..fd546dfcef61 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -142,9 +142,6 @@ CFLAGS+= -DYP .if ${MK_HESIOD} != "no" CFLAGS+= -DHESIOD .endif -.if ${MK_FP_LIBC} == "no" -CFLAGS+= -DNO_FLOATING_POINT -.endif .if ${MK_NS_CACHING} != "no" CFLAGS+= -DNS_CACHING .endif @@ -193,12 +190,6 @@ SUBDIR.${MK_TESTS}+= tests .include <bsd.lib.mk> -.if (${LIBC_ARCH} == amd64 || ${LIBC_ARCH} == i386) && \ - ${.TARGETS:Mall} == all && \ - defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" -.error ${LIBC_ARCH} libc requires linker ifunc support -.endif - .if !defined(_SKIP_BUILD) # We need libutil.h, get it directly to avoid # recording a build dependency diff --git a/lib/libc/aarch64/gen/makecontext.c b/lib/libc/aarch64/gen/makecontext.c index 8c9b4edd7a15..2d0ee1043a9b 100644 --- a/lib/libc/aarch64/gen/makecontext.c +++ b/lib/libc/aarch64/gen/makecontext.c @@ -74,7 +74,8 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) va_end(ap); /* Set the stack */ - gp->gp_sp = STACKALIGN(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + gp->gp_sp = STACKALIGN((uintptr_t)ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size); /* Arrange for return via the trampoline code. */ gp->gp_elr = (__register_t)_ctx_start; gp->gp_x[19] = (__register_t)func; diff --git a/lib/libc/aarch64/string/Makefile.inc b/lib/libc/aarch64/string/Makefile.inc index 35523fb954be..bc05e849aa20 100644 --- a/lib/libc/aarch64/string/Makefile.inc +++ b/lib/libc/aarch64/string/Makefile.inc @@ -5,10 +5,8 @@ AARCH64_STRING_FUNCS= \ memcmp \ - memcpy \ memmove \ memrchr \ - memset \ stpcpy \ strchr \ strchrnul \ @@ -16,6 +14,11 @@ AARCH64_STRING_FUNCS= \ strnlen \ strrchr +AARCH64_STRING_IFUNC_FILES= \ + memcpy-mops.S \ + memmove-mops.S \ + memset-mops.S + # SIMD-enhanced routines not derived from Arm's code MDSRCS+= \ memchr.S \ @@ -34,7 +37,13 @@ MDSRCS+= \ timingsafe_bcmp.S \ timingsafe_memcmp.S \ bcopy.c \ - bzero.c + bzero.c \ + memcpy.S \ + memcpy_resolver.c \ + memmove_resolver.c \ + memset.S \ + memset_resolver.c \ + memset_zva64.S # # Add the above functions. Generate an asm file that includes the needed @@ -43,8 +52,8 @@ MDSRCS+= \ # override the generated file in these cases. # .for FUNC in ${AARCH64_STRING_FUNCS} -.if !exists(${FUNC}.S) -${FUNC}.S: +.if !exists(${LIBC_SRCTOP}/aarch64/string/${FUNC}.S) +${FUNC}.S: ${LIBC_SRCTOP}/aarch64/string/Makefile.inc printf '/* %sgenerated by libc/aarch64/string/Makefile.inc */\n' @ > ${.TARGET} printf '#define __%s_aarch64 %s\n' ${FUNC} ${FUNC} >> ${.TARGET} printf '#include "aarch64/%s.S"\n' ${FUNC} >> ${.TARGET} @@ -55,6 +64,18 @@ MDSRCS+= ${FUNC}.S CFLAGS.${FUNC}.S+=-I${SRCTOP}/contrib/arm-optimized-routines/string .endfor -# memchr.S is a wrapper in the src tree for the implementation from +.for FILE in ${AARCH64_STRING_IFUNC_FILES} +${FILE}: ${LIBC_SRCTOP}/aarch64/string/Makefile.inc + printf '/* %sgenerated by libc/aarch64/string/Makefile.inc */\n' @ > ${.TARGET} + printf '#include "aarch64/%s"\n' ${FILE} >> ${.TARGET} +CLEANFILES+= ${FILE} +MDSRCS+= ${FILE} +CFLAGS.${FILE}+=-I${SRCTOP}/contrib/arm-optimized-routines/string +.endfor + +# Several files are wrappers in the src tree for the implementation from # arm-optimized-routines CFLAGS.memchr.S+=-I${SRCTOP}/contrib/arm-optimized-routines/string +CFLAGS.memcpy.S+=-I${SRCTOP}/contrib/arm-optimized-routines/string +CFLAGS.memset.S+=-I${SRCTOP}/contrib/arm-optimized-routines/string +CFLAGS.memset_zva64.S+=-I${SRCTOP}/contrib/arm-optimized-routines/string diff --git a/lib/libc/aarch64/string/memcpy.S b/lib/libc/aarch64/string/memcpy.S index 53e860750eb2..c4601d158d6b 100644 --- a/lib/libc/aarch64/string/memcpy.S +++ b/lib/libc/aarch64/string/memcpy.S @@ -1,3 +1 @@ -#define __memcpy_aarch64_simd memcpy -#define __memmove_aarch64_simd memmove #include "aarch64/memcpy-advsimd.S" diff --git a/lib/libc/powerpcspe/gen/fabs.S b/lib/libc/aarch64/string/memcpy_resolver.c index df9196c3273d..c2a7477a939e 100644 --- a/lib/libc/powerpcspe/gen/fabs.S +++ b/lib/libc/aarch64/string/memcpy_resolver.c @@ -1,6 +1,7 @@ -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Arm Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,15 +24,19 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include <sys/types.h> +#include <machine/ifunc.h> -#include <machine/asm.h> -/* - * double fabs(double) - */ -ENTRY(fabs) - /* arg is split in two words, clear sign bit only, in r3. */ - clrlwi %r3,%r3,1 - blr -END(fabs) +#include <elf.h> + +void *__memcpy_aarch64_simd(void *, const void *, size_t); +void *__memcpy_aarch64_mops(void *, const void *, size_t); + +DEFINE_UIFUNC(, void *, memcpy, (void *, const void *, size_t)) +{ + if (ifunc_arg->_hwcap2 & HWCAP2_MOPS) + return (__memcpy_aarch64_mops); + + return (__memcpy_aarch64_simd); +} - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/_fpmath.h b/lib/libc/aarch64/string/memmove_resolver.c index 9bc7450aacaf..95cf3deca966 100644 --- a/lib/libc/powerpcspe/_fpmath.h +++ b/lib/libc/aarch64/string/memmove_resolver.c @@ -1,8 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> - * All rights reserved. + * Copyright (c) 2026 Arm Ltd * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,32 +24,19 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include <sys/types.h> +#include <machine/ifunc.h> -union IEEEl2bits { - long double e; - struct { -#if _BYTE_ORDER == _LITTLE_ENDIAN - unsigned int manl :32; - unsigned int manh :20; - unsigned int exp :11; - unsigned int sign :1; -#else /* _BYTE_ORDER == _LITTLE_ENDIAN */ - unsigned int sign :1; - unsigned int exp :11; - unsigned int manh :20; - unsigned int manl :32; -#endif - } bits; -}; +#include <elf.h> -#define mask_nbit_l(u) ((void)0) -#define LDBL_IMPLICIT_NBIT -#define LDBL_NBIT 0 +void *__memmove_aarch64_simd(void *, const void *, size_t); +void *__memmove_aarch64_mops(void *, const void *, size_t); -#define LDBL_MANH_SIZE 20 -#define LDBL_MANL_SIZE 32 +DEFINE_UIFUNC(, void *, memmove, (void *, const void *, size_t)) +{ + if (ifunc_arg->_hwcap2 & HWCAP2_MOPS) + return (__memmove_aarch64_mops); + + return (__memmove_aarch64_simd); +} -#define LDBL_TO_ARRAY32(u, a) do { \ - (a)[0] = (uint32_t)(u).bits.manl; \ - (a)[1] = (uint32_t)(u).bits.manh; \ -} while(0) diff --git a/lib/libc/aarch64/string/memset.S b/lib/libc/aarch64/string/memset.S new file mode 100644 index 000000000000..acf707cdb7ec --- /dev/null +++ b/lib/libc/aarch64/string/memset.S @@ -0,0 +1 @@ +#include "aarch64/memset.S" diff --git a/lib/libc/aarch64/string/memset_resolver.c b/lib/libc/aarch64/string/memset_resolver.c new file mode 100644 index 000000000000..277e8c177de9 --- /dev/null +++ b/lib/libc/aarch64/string/memset_resolver.c @@ -0,0 +1,55 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Arm Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/types.h> + +#include <machine/armreg.h> +#include <machine/ifunc.h> + +#include <elf.h> + +void *__memset_aarch64(void *, int, size_t); +void *__memset_aarch64_zva64(void *, int, size_t); +void *__memset_aarch64_mops(void *, int, size_t); + +DEFINE_UIFUNC(, void *, memset, (void *, int, size_t)) +{ + uint64_t dczid; + + if (ifunc_arg->_hwcap2 & HWCAP2_MOPS) + return (__memset_aarch64_mops); + + /* + * Check for the DC ZVA instruction, and it will + * zero 64 bytes (4 * 4byte words). + */ + dczid = READ_SPECIALREG(dczid_el0); + if ((dczid & DCZID_DZP) == 0 && DCZID_BS_SIZE(dczid) == 4) + return (__memset_aarch64_zva64); + + return (__memset_aarch64); +} + diff --git a/lib/libc/aarch64/string/memset_zva64.S b/lib/libc/aarch64/string/memset_zva64.S new file mode 100644 index 000000000000..7f1cf6ba577a --- /dev/null +++ b/lib/libc/aarch64/string/memset_zva64.S @@ -0,0 +1,4 @@ +/* Used when we know we have a 64-byte dc zva instruction */ +#define __memset_aarch64 __memset_aarch64_zva64 +#define SKIP_ZVA_CHECK +#include "aarch64/memset.S" diff --git a/lib/libc/amd64/string/strrchr.S b/lib/libc/amd64/string/strrchr.S index e397bbcd3478..a22a821a1d4d 100644 --- a/lib/libc/amd64/string/strrchr.S +++ b/lib/libc/amd64/string/strrchr.S @@ -1,5 +1,6 @@ /*- * Copyright (c) 2023 The FreeBSD Foundation + * Copyright (c) 2026 Robert Clausecker <fuz@FreeBSD.org> * * This software was developed by Robert Clausecker <fuz@FreeBSD.org> * under sponsorship from the FreeBSD Foundation. @@ -65,77 +66,50 @@ ARCHENTRY(strrchr, scalar) xor %rax, %rcx # str ^ c or %r10, %rax # ensure str != 0 before string or %r10, %rcx # ensure str^c != 0 before string - bswap %rcx # in reverse order, to find last match - mov %rdi, %r10 # location of initial mismatch (if any) - xor %r11, %r11 # initial mismatch (none) + xor %r11, %r11 # vector of last match (0 -> no match) add $8, %rdi # advance to next iteration lea (%rax, %r8, 1), %rdx # str - 0x01..01 not %rax # ~str and %rdx, %rax # (str - 0x01..01) & ~str - and %r9, %rax # not including junk bits - jnz 1f # end of string? - - lea (%rcx, %r8, 1), %rdx # (str ^ c) - 0x01..01 - not %rcx # ~(str ^ c) - and %rdx, %rcx # ((str ^ c - 0x01..01) & ~(str ^ c) - and %r9, %rcx # not including junk bits - mov %rcx, %r11 # remember mismatch in head - jmp 0f - - /* main loop unrolled twice */ - ALIGN_TEXT -3: lea (%rcx, %r8, 1), %rdx # (str ^ c) - 0x01..01 - not %rcx # ~(str ^ c) - and %rdx, %rcx # ((str ^ c - 0x01..01) & ~(str ^ c) - and %r9, %rcx # not including junk bits - lea -8(%rdi), %rdx - cmovnz %rdx, %r10 # remember location of current mismatch - cmovnz %rcx, %r11 - -0: mov (%rdi), %rax # str - mov %rsi, %rcx - xor %rax, %rcx # str ^ c - bswap %rcx # in reverse order, to find last match - lea (%rax, %r8, 1), %rdx # str - 0x01..01 - not %rax # ~str - and %rdx, %rax # (str - 0x01..01) & ~str - and %r9, %rax # not including junk bits + and %r9, %rax # NUL bytes in str, not including junk bits jnz 2f # end of string? + /* main loop */ + ALIGN_TEXT +3: mov (%rdi), %rax # str + bswap %rcx # (str ^ c) in reverse order, to find last match lea (%rcx, %r8, 1), %rdx # (str ^ c) - 0x01..01 not %rcx # ~(str ^ c) and %rdx, %rcx # ((str ^ c - 0x01..01) & ~(str ^ c) - and %r9, %rcx # not including junk bits - cmovnz %rdi, %r10 # remember location of current mismatch - cmovnz %rcx, %r11 + and %r9, %rcx # matches in str, not including junk bits + cmovnz %rdi, %r10 # if match found, update match vector + cmovnz %rcx, %r11 # ... and match pointer - mov 8(%rdi), %rax # str - add $16, %rdi + add $8, %rdi # advance to next iteration mov %rsi, %rcx xor %rax, %rcx # str ^ c - bswap %rcx lea (%rax, %r8, 1), %rdx # str - 0x01..01 not %rax # ~str and %rdx, %rax # (str - 0x01..01) & ~str - and %r9, %rax # not including junk bits + and %r9, %rax # NUL bytes in str, not including junk bits jz 3b # end of string? - /* NUL found */ -1: sub $8, %rdi # undo advance past buffer -2: lea (%rcx, %r8, 1), %rdx # (str ^ c) - 0x01..01 + /* NUL found, check for match in tail */ +2: mov %rax, %rdx + neg %rax + xor %rdx, %rax # all bytes behind the NUL byte + or %rax, %rcx # (str ^ c) without matches behind NUL byte + bswap %rcx # (src ^ c) in reverse order, to find last match + lea (%rcx, %r8, 1), %rdx # (str ^ c) - 0x01..01 not %rcx # ~(str ^ c) and %rdx, %rcx # ((str ^ c - 0x01..01) & ~(str ^ c) - and %r9, %rcx # not including junk bits - lea -1(%rax), %rdx - xor %rdx, %rax # mask of bytes in the string - bswap %rdx # in reverse order - and %rdx, %rcx # c found in the tail? - cmovnz %rdi, %r10 - cmovnz %rcx, %r11 - bswap %r11 # unreverse byte order - bsr %r11, %rcx # last location of c in (R10) - shr $3, %rcx # as byte offset - lea (%r10, %rcx, 1), %rax # pointer to match + and %r9, %rcx # matches in str, not including junk bits + cmovnz %rdi, %r10 # if match found, update match vector + cmovnz %rcx, %r11 # ... and match pointer + tzcnt %r11, %rcx # location of last match + lea -1(%r10), %rax # address of last character in vector + shr $3, %ecx # as byte offset + sub %rcx, %rax # subtract character offset test %r11, %r11 # was there actually a match? cmovz %r11, %rax # if not, return null pointer ret diff --git a/lib/libc/arm/Symbol.map b/lib/libc/arm/Symbol.map index 49476d2e176a..0be97d4ea693 100644 --- a/lib/libc/arm/Symbol.map +++ b/lib/libc/arm/Symbol.map @@ -5,7 +5,6 @@ */ FBSD_1.0 { __mcount; - alloca; brk; sbrk; }; diff --git a/lib/libc/arm/aeabi/aeabi_unwind_cpp.c b/lib/libc/arm/aeabi/aeabi_unwind_cpp.c index efcace2c0675..3667b7d7e673 100644 --- a/lib/libc/arm/aeabi/aeabi_unwind_cpp.c +++ b/lib/libc/arm/aeabi/aeabi_unwind_cpp.c @@ -27,15 +27,15 @@ * */ +#include <sys/param.h> + /* * Provide an implementation of __aeabi_unwind_cpp_pr{0,1,2}. These are * required by libc but are implemented in libgcc_eh.a which we don't link - * against. The libgcc_eh.a version will be called so we call abort to + * against. The libgcc_eh.a version will be called so we trap to * check this. */ -#include <stdlib.h> - void __aeabi_unwind_cpp_pr0(void) __hidden; void __aeabi_unwind_cpp_pr1(void) __hidden; void __aeabi_unwind_cpp_pr2(void) __hidden; @@ -43,18 +43,18 @@ void __aeabi_unwind_cpp_pr2(void) __hidden; void __aeabi_unwind_cpp_pr0(void) { - abort(); + __builtin_trap(); } void __aeabi_unwind_cpp_pr1(void) { - abort(); + __builtin_trap(); } void __aeabi_unwind_cpp_pr2(void) { - abort(); + __builtin_trap(); } diff --git a/lib/libc/arm/gen/alloca.S b/lib/libc/arm/gen/alloca.S index 3545cc642aad..88db0cab749b 100644 --- a/lib/libc/arm/gen/alloca.S +++ b/lib/libc/arm/gen/alloca.S @@ -35,6 +35,7 @@ /* like alloc, but automatic automatic free in return */ #include <machine/asm.h> + ENTRY(alloca) add r0, r0, #0x00000007 /* round up to next 8 byte alignment */ bic r0, r0, #0x00000007 @@ -43,4 +44,6 @@ ENTRY(alloca) RET END(alloca) + .symver alloca, alloca@FBSD_1.0 + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c index 4ba7920bcb07..77e8a38176ce 100644 --- a/lib/libc/csu/aarch64/reloc.c +++ b/lib/libc/csu/aarch64/reloc.c @@ -25,17 +25,42 @@ */ #include <sys/cdefs.h> +#include <machine/ifunc.h> + +static __ifunc_arg_t ifunc_arg; static void -ifunc_init(const Elf_Auxinfo *aux __unused) +ifunc_init(const Elf_Auxinfo *aux) { + ifunc_arg._size = sizeof(ifunc_arg); + ifunc_arg._hwcap = 0; + ifunc_arg._hwcap2 = 0; + ifunc_arg._hwcap3 = 0; + ifunc_arg._hwcap4 = 0; + + for (; aux->a_type != AT_NULL; aux++) { + switch (aux->a_type) { + case AT_HWCAP: + ifunc_arg._hwcap = aux->a_un.a_val | _IFUNC_ARG_HWCAP; + break; + case AT_HWCAP2: + ifunc_arg._hwcap2 = aux->a_un.a_val; + break; + case AT_HWCAP3: + ifunc_arg._hwcap3 = aux->a_un.a_val; + break; + case AT_HWCAP4: + ifunc_arg._hwcap4 = aux->a_un.a_val; + break; + } + } } static void crt1_handle_rela(const Elf_Rela *r) { typedef Elf_Addr (*ifunc_resolver_t)( - uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, const __ifunc_arg_t *, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); Elf_Addr *ptr, *where, target; @@ -43,7 +68,7 @@ crt1_handle_rela(const Elf_Rela *r) case R_AARCH64_IRELATIVE: ptr = (Elf_Addr *)r->r_addend; where = (Elf_Addr *)r->r_offset; - target = ((ifunc_resolver_t)ptr)(0, 0, 0, 0, 0, 0, 0, 0); + target = ((ifunc_resolver_t)ptr)(ifunc_arg._hwcap, &ifunc_arg, 0, 0, 0, 0, 0, 0); *where = target; break; } diff --git a/lib/libc/csu/powerpcspe/Makefile.inc b/lib/libc/csu/powerpcspe/Makefile.inc deleted file mode 100644 index ddead75f874d..000000000000 --- a/lib/libc/csu/powerpcspe/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# - -CFLAGS+= -DCRT_IRELOC_SUPPRESS diff --git a/lib/libc/db/btree/bt_seq.c b/lib/libc/db/btree/bt_seq.c index 2562724faf33..fc7fa693b747 100644 --- a/lib/libc/db/btree/bt_seq.c +++ b/lib/libc/db/btree/bt_seq.c @@ -325,7 +325,7 @@ usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE); static int __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) { - PAGE *h; + PAGE *h, *hprev; EPG *ep, save; pgno_t pg; @@ -338,7 +338,7 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) * page) and return it. */ if ((ep = __bt_search(t, key, exactp)) == NULL) - return (0); + return (RET_SPECIAL); if (*exactp) { if (F_ISSET(t, B_NODUPS)) { *erval = *ep; @@ -369,14 +369,14 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) break; if (h->pgno != save.page->pgno) mpool_put(t->bt_mp, h, 0); - if ((h = mpool_get(t->bt_mp, + if ((hprev = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL) { if (h->pgno == save.page->pgno) mpool_put(t->bt_mp, save.page, 0); return (RET_ERROR); } - ep->page = h; + ep->page = h = hprev; ep->index = NEXTINDEX(h); } --ep->index; diff --git a/lib/libc/db/btree/bt_split.c b/lib/libc/db/btree/bt_split.c index 5fbf8c3ac0f3..865543928c35 100644 --- a/lib/libc/db/btree/bt_split.c +++ b/lib/libc/db/btree/bt_split.c @@ -542,7 +542,7 @@ bt_broot(BTREE *t, PAGE *h, PAGE *l, PAGE *r) * If the key is on an overflow page, mark the overflow chain * so it isn't deleted when the leaf copy of the key is deleted. */ - if (bl->flags & P_BIGKEY) { + if (bl->flags & P_BIGKEY) { pgno_t pgno; memcpy(&pgno, bl->bytes, sizeof(pgno)); if (bt_preserve(t, pgno) == RET_ERROR) diff --git a/lib/libc/db/hash/extern.h b/lib/libc/db/hash/extern.h index d3850752ad3a..690219d30606 100644 --- a/lib/libc/db/hash/extern.h +++ b/lib/libc/db/hash/extern.h @@ -54,7 +54,7 @@ void __reclaim_buf(HTAB *, BUFHEAD *); int __split_page(HTAB *, u_int32_t, u_int32_t); /* Default hash routine. */ -extern u_int32_t (*__default_hash)(const void *, size_t); +u_int32_t __default_hash(const void *, size_t); #ifdef HASH_STATISTICS extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows; diff --git a/lib/libc/db/hash/hash_func.c b/lib/libc/db/hash/hash_func.c index 529180b7698d..29597a04d3c0 100644 --- a/lib/libc/db/hash/hash_func.c +++ b/lib/libc/db/hash/hash_func.c @@ -39,114 +39,9 @@ #include "page.h" #include "extern.h" -#ifdef notdef -static u_int32_t hash1(const void *, size_t) __unused; -static u_int32_t hash2(const void *, size_t) __unused; -static u_int32_t hash3(const void *, size_t) __unused; -#endif -static u_int32_t hash4(const void *, size_t); - -/* Default hash function. */ -u_int32_t (*__default_hash)(const void *, size_t) = hash4; - -#ifdef notdef -/* - * Assume that we've already split the bucket to which this key hashes, - * calculate that bucket, and check that in fact we did already split it. - * - * EJB's original hsearch hash. - */ -#define PRIME1 37 -#define PRIME2 1048583 - -u_int32_t -hash1(const void *key, size_t len) -{ - u_int32_t h; - u_int8_t *k; - - h = 0; - k = (u_int8_t *)key; - /* Convert string to integer */ - while (len--) - h = h * PRIME1 ^ (*k++ - ' '); - h %= PRIME2; - return (h); -} - -/* - * Phong Vo's linear congruential hash - */ -#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) - -u_int32_t -hash2(const void *key, size_t len) -{ - u_int32_t h; - u_int8_t *e, c, *k; - - k = (u_int8_t *)key; - e = k + len; - for (h = 0; k != e;) { - c = *k++; - if (!c && k > e) - break; - dcharhash(h, c); - } - return (h); -} - -/* - * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the "leftover bytes" - * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If - * this routine is heavily used enough, it's worth the ugly coding. - * - * Ozan Yigit's original sdbm hash. - */ -u_int32_t -hash3(const void *key, size_t len) -{ - u_int32_t n, loop; - u_int8_t *k; - -#define HASHC n = *k++ + 65599 * n - - n = 0; - k = (u_int8_t *)key; - if (len > 0) { - loop = (len + 8 - 1) >> 3; - - switch (len & (8 - 1)) { - case 0: - do { /* All fall throughs */ - HASHC; - case 7: - HASHC; - case 6: - HASHC; - case 5: - HASHC; - case 4: - HASHC; - case 3: - HASHC; - case 2: - HASHC; - case 1: - HASHC; - } while (--loop); - } - - } - return (n); -} -#endif /* notdef */ - /* Chris Torek's hash function. */ u_int32_t -hash4(const void *key, size_t len) +__default_hash(const void *key, size_t len) { u_int32_t h, loop; const u_int8_t *k; diff --git a/lib/libc/db/mpool/mpool.c b/lib/libc/db/mpool/mpool.c index 1bab66d73baf..0df19dc09e4d 100644 --- a/lib/libc/db/mpool/mpool.c +++ b/lib/libc/db/mpool/mpool.c @@ -214,10 +214,14 @@ mpool_get(MPOOL *mp, pgno_t pgno, /* Read in the contents. */ off = mp->pagesize * pgno; if ((nr = pread(mp->fd, bp->page, mp->pagesize, off)) != (ssize_t)mp->pagesize) { + int serrno; + switch (nr) { case -1: /* errno is set for us by pread(). */ + serrno = errno; free(bp); + errno = serrno; mp->curcache--; return (NULL); case 0: diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 4d064d18d36e..c31f789fd1d1 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -274,8 +274,10 @@ MAN+= alarm.3 \ posix_spawn.3 \ posix_spawn_file_actions_addopen.3 \ posix_spawn_file_actions_init.3 \ + posix_spawnattr_getexecfd_np.3 \ posix_spawnattr_getflags.3 \ posix_spawnattr_getpgroup.3 \ + posix_spawnattr_getprocdescp_np.3 \ posix_spawnattr_getschedparam.3 \ posix_spawnattr_getschedpolicy.3 \ posix_spawnattr_init.3 \ @@ -321,6 +323,7 @@ MAN+= alarm.3 \ ttyname.3 \ ualarm.3 \ ucontext.3 \ + uexterr_gettext.3 \ ulimit.3 \ uname.3 \ unvis.3 \ @@ -465,11 +468,13 @@ MLINKS+=posix_spawn.3 posix_spawnp.3 \ posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addclose.3 \ posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addclosefrom_np.3 \ posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_adddup2.3 \ - posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addchdir_np.3 \ - posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addfchdir_np.3 \ + posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addchdir.3 \ + posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addfchdir.3 \ posix_spawn_file_actions_init.3 posix_spawn_file_actions_destroy.3 \ posix_spawnattr_getflags.3 posix_spawnattr_setflags.3 \ + posix_spawnattr_getexecfd_np.3 posix_spawnattr_setexecfd_np.3 \ posix_spawnattr_getpgroup.3 posix_spawnattr_setpgroup.3 \ + posix_spawnattr_getprocdescp_np.3 posix_spawnattr_setprocdescp_np.3 \ posix_spawnattr_getschedparam.3 posix_spawnattr_setschedparam.3 \ posix_spawnattr_getschedpolicy.3 posix_spawnattr_setschedpolicy.3 \ posix_spawnattr_getsigdefault.3 posix_spawnattr_setsigdefault.3 \ @@ -557,6 +562,7 @@ MLINKS+=unvis.3 strunvis.3 \ unvis.3 strunvisx.3 MLINKS+=vis.3 nvis.3 \ vis.3 snvis.3 \ + vis.3 stravis.3 \ vis.3 strenvisx.3 \ vis.3 strnunvis.3 \ vis.3 strnunvisx.3 \ @@ -583,8 +589,8 @@ install-passwd: .PHONY ${PWD_MKDB_CMD} -i -p -d ${DESTDIR}/etc ${DESTDIR}/etc/master.passwd .if defined(NO_ROOT) && defined(METALOG) ( \ - echo ".${DISTBASE}/etc/pwd.db type=file mode=0644 uname=root gname=wheel"; \ - echo ".${DISTBASE}/etc/spwd.db type=file mode=0600 uname=root gname=wheel"; \ - echo ".${DISTBASE}/etc/passwd type=file mode=0644 uname=root gname=wheel"; \ + echo ".${DISTBASE}/etc/pwd.db type=file uname=root gname=wheel mode=0644"; \ + echo ".${DISTBASE}/etc/spwd.db type=file uname=root gname=wheel mode=0600"; \ + echo ".${DISTBASE}/etc/passwd type=file uname=root gname=wheel mode=0644"; \ ) | cat -l >> ${METALOG} .endif diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 494b65bc5cc1..60f34b3a1923 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -474,6 +474,15 @@ FBSD_1.8 { str2sig; }; +FBSD_1.9 { + posix_spawn_file_actions_addchdir; + posix_spawn_file_actions_addfchdir; + posix_spawnattr_getexecfd_np; + posix_spawnattr_getprocdescp_np; + posix_spawnattr_setexecfd_np; + posix_spawnattr_setprocdescp_np; +}; + FBSDprivate_1.0 { /* needed by thread libraries */ __thr_jtable; diff --git a/lib/libc/gen/closedir.c b/lib/libc/gen/closedir.c index 6015114d6c47..73070d171cd1 100644 --- a/lib/libc/gen/closedir.c +++ b/lib/libc/gen/closedir.c @@ -68,6 +68,5 @@ fdclosedir(DIR *dirp) int closedir(DIR *dirp) { - return (_close(fdclosedir(dirp))); } diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3 index 263dfdd6eb95..270abb2d2371 100644 --- a/lib/libc/gen/directory.3 +++ b/lib/libc/gen/directory.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 1, 2020 +.Dd January 31, 2026 .Dt DIRECTORY 3 .Os .Sh NAME @@ -86,13 +86,6 @@ and returns a pointer to be used to identify the .Em directory stream in subsequent operations. -The pointer -.Dv NULL -is returned if -.Fa filename -cannot be accessed, or if it cannot -.Xr malloc 3 -enough memory to hold the whole thing. .Pp The .Fn fdopendir @@ -134,14 +127,6 @@ or .Fn closedir on the same .Em directory stream . -The function returns -.Dv NULL -upon reaching the end of the directory or on error. -In the event of an error, -.Va errno -may be set to any of the values documented for the -.Xr getdirentries 2 -system call. .Pp The .Fn readdir_r @@ -166,10 +151,6 @@ upon reaching the end of the directory .Fa result is set to .Dv NULL . -The -.Fn readdir_r -function -returns 0 on success or an error number to indicate failure. .Pp The .Fn telldir @@ -179,12 +160,9 @@ returns a token representing the current location associated with the named Values returned by .Fn telldir are good only for the lifetime of the -.Dv DIR -pointer, -.Fa dirp , +.Em directory stream from which they are derived. -If the directory is closed and then -reopened, prior values returned by +If the directory is closed and then reopened, prior values returned by .Fn telldir will no longer be valid. Values returned by @@ -217,28 +195,22 @@ The function closes the named .Em directory stream -and frees the structure associated with the -.Fa dirp -pointer, -returning 0 on success. -On failure, \-1 is returned and the global variable -.Va errno -is set to indicate the error. +and frees the structure associated with +.Fa dirp . .Pp The .Fn fdclosedir function is equivalent to the .Fn closedir -function except that this function returns directory file descriptor instead of -closing it. +function except that it returns the file descriptor associated with +.Fa dirp +instead of closing it. .Pp The .Fn dirfd function -returns the integer file descriptor associated with the named -.Em directory stream , -see -.Xr open 2 . +returns the file descriptor associated with +.Fa dirp . .Sh EXAMPLES Sample code which searches a directory for entry ``name'' is: .Bd -literal -offset indent @@ -255,6 +227,38 @@ while ((dp = readdir(dirp)) != NULL) { (void)closedir(dirp); return (NOT_FOUND); .Ed +.Sh RETURN VALUES +The +.Fn opendir +and +.Fn fdopendir +functions return a pointer to the new +.Em directory stream +on success and +.Dv NULL +on failure. +.Pp +The +.Fn readdir +function returns a pointer to a directory entry on success and +.Dv NULL +on failure. +The +.Fn readdir_r +function returns 0 on success and an error number on failure. +.Pp +The +.Fn telldir +function returns a nonnegative value on success and -1 on failure. +.Pp +The +.Fn closedir +function returns 0 on success and -1 on failure. +The +.Fn fdclosedir +and +.Fn dirfd +functions return an open file descriptor on success and -1 on failure. .Sh ERRORS The .Fn opendir @@ -325,6 +329,16 @@ function may also fail and set .Va errno for any of the errors specified for the routine .Xr close 2 . +.Pp +The +.Fn dirfd +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa dirp +argument does not refer to a valid directory stream. +.El .Sh SEE ALSO .Xr close 2 , .Xr lseek 2 , diff --git a/lib/libc/gen/dirfd.c b/lib/libc/gen/dirfd.c index 85090bd4da6c..984e69b9ae9a 100644 --- a/lib/libc/gen/dirfd.c +++ b/lib/libc/gen/dirfd.c @@ -27,9 +27,9 @@ */ #include "namespace.h" -#include <sys/param.h> - #include <dirent.h> +#include <errno.h> +#include <stddef.h> #include "un-namespace.h" #include "gen-private.h" @@ -37,6 +37,9 @@ int dirfd(DIR *dirp) { - + if (dirp == NULL || _dirfd(dirp) < 0) { + errno = EINVAL; + return (-1); + } return (_dirfd(dirp)); } diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index 340545114114..2f10c17a4f53 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -164,6 +164,20 @@ Symbols from the loaded library are put before global symbols when resolving symbolic references originated from the library. .El .Pp +A special syntax for the +.Fa path +is supported, in the form of +.Dl #number/name . +The +.Ql number +should be a decimal number, which references an open file descriptor, +and which must be also listed in the environment variable +.Ev LD_LIBRARY_PATH_FDS . +In this case, the linker tries to load an object that can be opened by +.Ql openat(number, path, O_RDONLY) . +This feature is only available to trusted processes, i.e., +the activated image must be not set-uid or set-gid. +.Pp If .Fn dlopen fails, it returns a null pointer, and sets an error condition which may diff --git a/lib/libc/gen/dup3.3 b/lib/libc/gen/dup3.3 index 338a9ae74c64..ec89ef77cf17 100644 --- a/lib/libc/gen/dup3.3 +++ b/lib/libc/gen/dup3.3 @@ -52,6 +52,8 @@ The close-on-fork flag on the new file descriptor is determined by the bit in .Fa flags . .Pp +The resolve-beneath flag on the new file descriptor is preserved. +.Pp If .Fa oldd \*(Ne diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3 index 70a214152a19..2df03c2dcdde 100644 --- a/lib/libc/gen/err.3 +++ b/lib/libc/gen/err.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 29, 2012 +.Dd February 23, 2026 .Dt ERR 3 .Os .Sh NAME @@ -128,6 +128,12 @@ environment variable is present, an additional report is printed. The report includes at least the category of the error, the name of the source file (if known by the used version of libc), the source line number, and parameters. +If the +.Ev EXTERROR_VERBOSE +environment variable is present and set to "brief", +the report adds only the name of +the source file (if known by the used version of libc) +and the source line number. The format of the printed string is not contractual and might be changed. .Pp In the case of the diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c index 793bf7522e42..2628eb8186cc 100644 --- a/lib/libc/gen/err.c +++ b/lib/libc/gen/err.c @@ -163,14 +163,14 @@ _warn(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - vwarnc(errno, fmt, ap); + vwarnci(true, errno, fmt, ap); va_end(ap); } void vwarn(const char *fmt, va_list ap) { - vwarnc(errno, fmt, ap); + vwarnci(true, errno, fmt, ap); } void diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h index 883dd98289cd..e45d05e384bd 100644 --- a/lib/libc/gen/exterr_cat_filenames.h +++ b/lib/libc/gen/exterr_cat_filenames.h @@ -2,15 +2,18 @@ * Automatically @generated, use * tools/build/make_libc_exterr_cat_filenames.sh */ + [EXTERR_CAT_VMM] = "dev/vmm/vmm_dev.c", [EXTERR_CAT_FUSE_DEVICE] = "fs/fuse/fuse_device.c", [EXTERR_CAT_FUSE_VFS] = "fs/fuse/fuse_vfsops.c", [EXTERR_CAT_FUSE_VNOPS] = "fs/fuse/fuse_vnops.c", [EXTERR_CAT_GEOM] = "geom/geom_subr.c", [EXTERR_CAT_GEOMVFS] = "geom/geom_vfs.c", [EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c", - [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c", + [EXTERR_CAT_PROCEXIT] = "kern/kern_exit.c", + [EXTERR_CAT_FORK] = "kern/kern_fork.c", [EXTERR_CAT_GENIO] = "kern/sys_generic.c", [EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c", + [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c", [EXTERR_CAT_VFSSYSCALL] = "kern/vfs_syscalls.c", [EXTERR_CAT_BRIDGE] = "net/if_bridge.c", [EXTERR_CAT_SWAP] = "vm/swap_pager.c", diff --git a/lib/libc/gen/fdopendir.c b/lib/libc/gen/fdopendir.c index 9393cbe28f85..05e1a09fd00c 100644 --- a/lib/libc/gen/fdopendir.c +++ b/lib/libc/gen/fdopendir.c @@ -37,6 +37,7 @@ #include <errno.h> #include <fcntl.h> #include <stdbool.h> +#include <stddef.h> #include "un-namespace.h" #include "gen-private.h" diff --git a/lib/libc/gen/fmtcheck.c b/lib/libc/gen/fmtcheck.c index de889ad3421c..6d85e3889a4d 100644 --- a/lib/libc/gen/fmtcheck.c +++ b/lib/libc/gen/fmtcheck.c @@ -55,10 +55,8 @@ enum __e_fmtcheck_types { FMTCHECK_INTMAXTPOINTER, FMTCHECK_PTRDIFFTPOINTER, FMTCHECK_SIZETPOINTER, -#ifndef NO_FLOATING_POINT FMTCHECK_DOUBLE, FMTCHECK_LONGDOUBLE, -#endif FMTCHECK_STRING, FMTCHECK_WSTRING, FMTCHECK_WIDTH, @@ -185,7 +183,6 @@ get_next_format_from_precision(const char **pf) RETURN(pf,f,FMTCHECK_UNKNOWN); RETURN(pf,f,FMTCHECK_LONG); } -#ifndef NO_FLOATING_POINT if (strchr("aAeEfFgG", *f)) { switch (modifier) { case MOD_LONGDOUBLE: @@ -197,7 +194,6 @@ get_next_format_from_precision(const char **pf) RETURN(pf,f,FMTCHECK_UNKNOWN); } } -#endif if (*f == 'c') { switch (modifier) { case MOD_LONG: diff --git a/lib/libc/gen/memfd_create.c b/lib/libc/gen/memfd_create.c index 78131f46d7b1..8e6c93be4337 100644 --- a/lib/libc/gen/memfd_create.c +++ b/lib/libc/gen/memfd_create.c @@ -95,16 +95,25 @@ memfd_create(const char *name, unsigned int flags) npgs = getpagesizes(pgs, nitems(pgs)); if (npgs == -1) goto clean; - pgsize = (size_t)1 << ((flags & MFD_HUGE_MASK) >> MFD_HUGE_SHIFT); - for (pgidx = 0; pgidx < npgs; pgidx++) { - if (pgsize == pgs[pgidx]) - break; - } - if (pgidx == npgs) { - errno = EOPNOTSUPP; + else if (npgs == 1) { + errno = ENOSYS; goto clean; } + if ((flags & MFD_HUGE_MASK) == 0) { + pgidx = 1; + } else { + pgsize = 1UL << ((flags & MFD_HUGE_MASK) >> MFD_HUGE_SHIFT); + for (pgidx = 1; pgidx < npgs; pgidx++) { + if (pgsize == pgs[pgidx]) + break; + } + if (pgidx == npgs) { + errno = EOPNOTSUPP; + goto clean; + } + } + memset(&slc, 0, sizeof(slc)); slc.psind = pgidx; slc.alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT; diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c index 08d9eb10eaa2..4c08b7156055 100644 --- a/lib/libc/gen/opendir.c +++ b/lib/libc/gen/opendir.c @@ -42,6 +42,5 @@ DIR * opendir(const char *name) { - return (__opendir2(name, DTF_HIDEW | DTF_NODUP)); } diff --git a/lib/libc/gen/opendir2.c b/lib/libc/gen/opendir2.c index c5c2e662efd8..321cb2261b8c 100644 --- a/lib/libc/gen/opendir2.c +++ b/lib/libc/gen/opendir2.c @@ -68,7 +68,6 @@ __opendir2(const char *name, int flags) static int opendir_compar(const void *p1, const void *p2) { - return (strcmp((*(const struct dirent * const *)p1)->d_name, (*(const struct dirent * const *)p2)->d_name)); } diff --git a/lib/libc/gen/pause.3 b/lib/libc/gen/pause.3 index 6b17ae10777d..85257071ce2f 100644 --- a/lib/libc/gen/pause.3 +++ b/lib/libc/gen/pause.3 @@ -77,7 +77,7 @@ A system call first appeared in the Programmer's Workbench (PWB/UNIX) and was then ported to .At v7 . -It was reimplemeted as a wrapper around the +It was reimplemented as a wrapper around the .Fn sigpause and .Fn sigblock diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3 index 278fee88463a..ad66d1a426c4 100644 --- a/lib/libc/gen/posix_spawn.3 +++ b/lib/libc/gen/posix_spawn.3 @@ -446,24 +446,28 @@ action. .Xr sched_setscheduler 2 , .Xr setpgid 2 , .Xr vfork 2 , -.Xr posix_spawn_file_actions_addchdir_np 3 , +.Xr posix_spawn_file_actions_addchdir 3 , .Xr posix_spawn_file_actions_addclose 3 , .Xr posix_spawn_file_actions_addclosefrom_np 3 , .Xr posix_spawn_file_actions_adddup2 3 , -.Xr posix_spawn_file_actions_addfchdir_np 3 , +.Xr posix_spawn_file_actions_addfchdir 3 , .Xr posix_spawn_file_actions_addopen 3 , .Xr posix_spawn_file_actions_destroy 3 , .Xr posix_spawn_file_actions_init 3 , .Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getexecfd_np 3 , .Xr posix_spawnattr_getflags 3 , .Xr posix_spawnattr_getpgroup 3 , +.Xr posix_spawnattr_getprocdescp_np 3 , .Xr posix_spawnattr_getschedparam 3 , .Xr posix_spawnattr_getschedpolicy 3 , .Xr posix_spawnattr_getsigdefault 3 , .Xr posix_spawnattr_getsigmask 3 , .Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setexecfd_np 3 , .Xr posix_spawnattr_setflags 3 , .Xr posix_spawnattr_setpgroup 3 , +.Xr posix_spawnattr_setprocdescp_np 3 , .Xr posix_spawnattr_setschedparam 3 , .Xr posix_spawnattr_setschedpolicy 3 , .Xr posix_spawnattr_setsigdefault 3 , @@ -477,8 +481,10 @@ functions conform to .St -p1003.1-2001 , except that they ignore all errors from .Fn close . -A future update of the Standard is expected to require that these functions -not fail because a file descriptor to be closed (via +The +.St -p1003.1-2024 , +version of the Standard no longer requires that these functions +fail because a file descriptor to be closed (via .Fn posix_spawn_file_actions_addclose ) is not open. .Sh HISTORY diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c index a5b732696b8c..11cdb5a29d03 100644 --- a/lib/libc/gen/posix_spawn.c +++ b/lib/libc/gen/posix_spawn.c @@ -29,6 +29,7 @@ #include "namespace.h" #include <sys/param.h> #include <sys/procctl.h> +#include <sys/procdesc.h> #include <sys/queue.h> #include <sys/wait.h> @@ -37,6 +38,7 @@ #include <sched.h> #include <spawn.h> #include <signal.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -50,6 +52,9 @@ struct __posix_spawnattr { int sa_schedpolicy; sigset_t sa_sigdefault; sigset_t sa_sigmask; + int sa_execfd; + int *sa_pdrfork_fdp; + int sa_pdflags; }; struct __posix_spawn_file_actions { @@ -231,7 +236,6 @@ struct posix_spawn_args { #define PSPAWN_STACK_ALIGN(sz) \ (((sz) + PSPAWN_STACK_ALIGNBYTES) & ~PSPAWN_STACK_ALIGNBYTES) -#if defined(__i386__) || defined(__amd64__) /* * Below we'll assume that _RFORK_THREAD_STACK_SIZE is appropriately aligned for * the posix_spawn() case where we do not end up calling execvpe and won't ever @@ -240,7 +244,6 @@ struct posix_spawn_args { #define _RFORK_THREAD_STACK_SIZE 4096 _Static_assert((_RFORK_THREAD_STACK_SIZE % PSPAWN_STACK_ALIGNMENT) == 0, "Inappropriate stack size alignment"); -#endif static int _posix_spawn_thr(void *data) @@ -260,7 +263,9 @@ _posix_spawn_thr(void *data) _exit(127); } envp = psa->envp != NULL ? psa->envp : environ; - if (psa->use_env_path) + if (psa->sa != NULL && (*(psa->sa))->sa_execfd != -1) + fexecve((*(psa->sa))->sa_execfd, psa->argv, envp); + else if (psa->use_env_path) __libc_execvpe(psa->path, psa->argv, envp); else _execve(psa->path, psa->argv, envp); @@ -278,12 +283,16 @@ do_posix_spawn(pid_t *pid, const char *path, { struct posix_spawn_args psa; pid_t p; -#ifdef _RFORK_THREAD_STACK_SIZE + int pfd; + bool do_pfd; char *stack; - size_t cnt, stacksz; + size_t stacksz; +#if defined(__i386__) || defined(__amd64__) stacksz = _RFORK_THREAD_STACK_SIZE; if (use_env_path) { + size_t cnt; + /* * We need to make sure we have enough room on the stack for the * potential alloca() in execvPe if it gets kicked back an @@ -310,6 +319,9 @@ do_posix_spawn(pid_t *pid, const char *path, return (ENOMEM); stacksz = (((uintptr_t)stack + stacksz) & ~PSPAWN_STACK_ALIGNBYTES) - (uintptr_t)stack; +#else + stack = NULL; + stacksz = 0; #endif psa.path = path; psa.fa = fa; @@ -319,6 +331,8 @@ do_posix_spawn(pid_t *pid, const char *path, psa.use_env_path = use_env_path; psa.error = 0; + do_pfd = sa != NULL && (*sa)->sa_pdrfork_fdp != NULL; + /* * Passing RFSPAWN to rfork(2) gives us effectively a vfork that drops * non-ignored signal handlers. We'll fall back to the slightly less @@ -330,22 +344,26 @@ do_posix_spawn(pid_t *pid, const char *path, * a special property of the libthr rtld locks ensure that * rtld is operational in the child. In particular, libthr * rtld locks do not store owner' tid into the lock word. + * + * x86 stores the return address on the stack, so rfork(2) + * cannot work as-is because the child would clobber the + * return address of the parent. Because of this, we must use + * rfork_thread instead. + * + * Every other architecture stores the return address in a + * register, the trivial rfork_thread() wrapper is provided + * for them. The only minor drawback is that the stack is + * temporarily allocated. */ -#ifdef _RFORK_THREAD_STACK_SIZE - /* - * x86 stores the return address on the stack, so rfork(2) cannot work - * as-is because the child would clobber the return address of the - * parent. Because of this, we must use rfork_thread instead while - * almost every other arch stores the return address in a register. - */ - p = rfork_thread(RFSPAWN, stack + stacksz, _posix_spawn_thr, &psa); + if (do_pfd) { + p = pdrfork_thread(&pfd, PD_CLOEXEC | (*sa)->sa_pdflags, + RFSPAWN, stack + stacksz, _posix_spawn_thr, &psa); + } else { + p = rfork_thread(RFSPAWN, stack + stacksz, _posix_spawn_thr, + &psa); + } free(stack); -#else - p = rfork(RFSPAWN); - if (p == 0) - /* _posix_spawn_thr does not return */ - _posix_spawn_thr(&psa); -#endif + /* * The above block should leave us in a state where we've either * succeeded and we're ready to process the results, or we need to @@ -353,6 +371,8 @@ do_posix_spawn(pid_t *pid, const char *path, */ if (p == -1 && errno == EINVAL) { + if (do_pfd) + return (EOPNOTSUPP); p = vfork(); if (p == 0) /* _posix_spawn_thr does not return */ @@ -360,12 +380,18 @@ do_posix_spawn(pid_t *pid, const char *path, } if (p == -1) return (errno); - if (psa.error != 0) + if (psa.error != 0) { /* Failed; ready to reap */ - _waitpid(p, NULL, WNOHANG); - else if (pid != NULL) + if (do_pfd) + (void)_close(pfd); + else + _waitpid(p, NULL, WNOHANG); + } else if (pid != NULL) { /* exec succeeded */ *pid = p; + if (do_pfd) + *((*sa)->sa_pdrfork_fdp) = pfd; + } return (psa.error); } @@ -523,6 +549,8 @@ posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t * STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); return (0); } +__weak_reference(posix_spawn_file_actions_addchdir_np, + posix_spawn_file_actions_addchdir); int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *__restrict fa, @@ -545,6 +573,9 @@ posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *__restrict fa, return (0); } +__weak_reference(posix_spawn_file_actions_addfchdir_np, + posix_spawn_file_actions_addfchdir); + int posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t * __restrict fa, int from) @@ -578,6 +609,7 @@ posix_spawnattr_init(posix_spawnattr_t *ret) sa = calloc(1, sizeof(struct __posix_spawnattr)); if (sa == NULL) return (errno); + sa->sa_execfd = -1; /* Set defaults as specified by POSIX, cleared above */ *ret = sa; @@ -640,6 +672,23 @@ posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa, } int +posix_spawnattr_getexecfd_np(const posix_spawnattr_t * __restrict sa, + int * __restrict fdp) +{ + *fdp = (*sa)->sa_execfd; + return (0); +} + +int +posix_spawnattr_getprocdescp_np(const posix_spawnattr_t * __restrict sa, + int ** __restrict fdpp, int * __restrict pdrflagsp) +{ + *fdpp = (*sa)->sa_pdrfork_fdp; + *pdrflagsp = (*sa)->sa_pdflags; + return (0); +} + +int posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags) { if ((flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | @@ -688,3 +737,20 @@ posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa, (*sa)->sa_sigmask = *sigmask; return (0); } + +int +posix_spawnattr_setexecfd_np(posix_spawnattr_t * __restrict sa, + int execfd) +{ + (*sa)->sa_execfd = execfd; + return (0); +} + +int +posix_spawnattr_setprocdescp_np(const posix_spawnattr_t * __restrict sa, + int * __restrict fdp, int pdrflags) +{ + (*sa)->sa_pdrfork_fdp = fdp; + (*sa)->sa_pdflags = pdrflags; + return (0); +} diff --git a/lib/libc/gen/posix_spawn_file_actions_addopen.3 b/lib/libc/gen/posix_spawn_file_actions_addopen.3 index 80bc91454471..1d0eac45f872 100644 --- a/lib/libc/gen/posix_spawn_file_actions_addopen.3 +++ b/lib/libc/gen/posix_spawn_file_actions_addopen.3 @@ -40,8 +40,8 @@ .Nm posix_spawn_file_actions_adddup2 , .Nm posix_spawn_file_actions_addclose , .Nm posix_spawn_file_actions_addclosefrom_np , -.Nm posix_spawn_file_actions_addchdir_np , -.Nm posix_spawn_file_actions_addfchdir_np +.Nm posix_spawn_file_actions_addchdir , +.Nm posix_spawn_file_actions_addfchdir .Nd "add open, dup2, close, closefrom, or chdir/fchdir actions to spawn file actions object" .Sh LIBRARY .Lb libc @@ -72,12 +72,12 @@ .Fa "int from" .Fc .Ft int -.Fo posix_spawn_file_actions_addchdir_np +.Fo posix_spawn_file_actions_addchdir .Fa "posix_spawn_file_actions_t *restrict file_actions" .Fa "const char *restrict path" .Fc .Ft int -.Fo posix_spawn_file_actions_addfchdir_np +.Fo posix_spawn_file_actions_addfchdir .Fa "posix_spawn_file_actions_t * file_actions" .Fa "int fildes" .Fc @@ -189,9 +189,9 @@ For each open file descriptor, logically the close action is performed, and any possible errors encountered are ignored. .Pp The -.Fn posix_spawn_file_actions_addchdir_np +.Fn posix_spawn_file_actions_addchdir and -.Fn posix_spawn_file_actions_addfchdir_np +.Fn posix_spawn_file_actions_addfchdir functions add a change current directory action to the object referenced by .Fa file_actions @@ -201,11 +201,11 @@ in the order of insertion into the object. It also sets the working directory for the spawned program. The -.Fn posix_spawn_file_actions_addchdir_np +.Fn posix_spawn_file_actions_addchdir function takes the .Fa path to set as the working directory, while -.Fn posix_spawn_file_actions_addfchdir_np +.Fn posix_spawn_file_actions_addfchdir takes the directory file descriptor. .Sh RETURN VALUES Upon successful completion, these functions return zero; @@ -250,11 +250,8 @@ is equal to A future update of the Standard is expected to require this behavior. .Pp The -.Fn posix_spawn_file_actions_addchdir_np , -.Fn posix_spawn_file_actions_addfchdir_np , -and .Fn posix_spawn_file_actions_addclosefrom_np -functions are non-standard functions implemented after the similar +function is non-standard and implemented after the similar functionality provided by glibc. .Sh HISTORY The @@ -271,5 +268,13 @@ and .Fn posix_spawn_file_actions_addclosefrom_np functions first appeared in .Fx 13.1 . +In +.Fx 16.0 , +the +.Fn posix_spawn_file_actions_addchdir , +.Fn posix_spawn_file_actions_addfchdir +aliases where added to the corresponding functions with the +.Ql _np +suffix. .Sh AUTHORS .An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getexecfd_np.3 b/lib/libc/gen/posix_spawnattr_getexecfd_np.3 new file mode 100644 index 000000000000..6edcfcdfb42f --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getexecfd_np.3 @@ -0,0 +1,87 @@ +.\" Copyright 2026 The FreeBSD Foundation +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" This documentation was written by +.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship +.\" from the FreeBSD Foundation. +.\" +.Dd January 25, 2026 +.Dt POSIX_SPAWNATTR_GETEXECFD_NP 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getexecfd_np , +.Nm posix_spawnattr_setexecfd_np +.Nd "get and set the spawn-execfd attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fo posix_spawnattr_getexecfd_np +.Fa "const posix_spawnattr_t *restrict attr" +.Fa "int *restrict fdp" +.Fc +.Ft int +.Fo posix_spawnattr_setexecfd_np +.Fa "posix_spawnattr_t *attr" +.Fa "int fd" +.Fc +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getexecfd_np +function obtains the value of the spawn-execfd attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setexecfd_np +function sets the spawn-execfd attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-execfd attribute provides the file descriptor that is used +to execute new image in the spawned process by the +.Xr posix_spawn 3 +family of functions. +If the attribute is set to a value other then \-1, it must be a valid +file descriptor which does not have the +.Va O_CLOFORK +flag set. +Then, +.Fn posix_spawn +executes the executable image referenced by the file descriptor in the +newly created process, using the +.Xr fexecve 2 +system call. +In this case, the +.Fa path +argument to +.Fn posix_spawn +is ignored. +.Pp +The default value for the spawn-execfd attribute is \-1, which +means that the executed image is specified by the +.Fa path +argument to +.Fn posix_spawn . +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getexecfd_np +and +.Fn posix_spawnattr_setexecfd_np +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getexecfd_np +and +.Fn posix_spawnattr_setexecfd_np +are +.Fx +extensions that first appeared in +.Fx 16.0 . diff --git a/lib/libc/gen/posix_spawnattr_getprocdescp_np.3 b/lib/libc/gen/posix_spawnattr_getprocdescp_np.3 new file mode 100644 index 000000000000..fab529d91313 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getprocdescp_np.3 @@ -0,0 +1,94 @@ +.\" Copyright 2026 The FreeBSD Foundation +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" This documentation was written by +.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship +.\" from the FreeBSD Foundation. +.\" +.Dd January 26, 2026 +.Dt POSIX_SPAWNATTR_GETPROCDESCP_NP 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getprocdesp_np , +.Nm posix_spawnattr_setprocdescp_np +.Nd "get and set the spawn-procdescp attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fo posix_spawnattr_getprocdescp_np +.Fa "const posix_spawnattr_t *restrict attr" +.Fa "int **restrict fdpp" +.Fa "int *restrict pdrflagsp" +.Fc +.Ft int +.Fo posix_spawnattr_setprocdescp_np +.Fa "posix_spawnattr_t *attr" +.Fa "int *restrict fdp" +.Fa "int pdrflags" +.Fc +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getprocdescp_np +function obtains the value of the spawn-procdescp attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_procdescp_np +function sets the spawn-procdescp attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-procdescp attribute provides the location where the child process's +file descriptor will be stored after a successful spawn. +Setting the attribute to a non-NULL value implicitly request the creation of +the file descriptor that references the child process. +It wiil be created by the +.Xr pdrfork 2 +system call. which will be used instead of +.Xr fork/vfork/rfork 2 +when the attribute is set to +.Va NULL. +.Pp +If the attribute is set to a value other then +.Dv NULL , +it must be a valid pointer to a variable of +.Vt int +type, where the resulting descriptor will be stored. +The +.Fa pdrflags +argument specifies additional flags that are accepted by the +.Xr pdfork 2 +system call. +See its description for the list of the valid flags. +Note that the +.Va PD_CLOEXEC +flag is always set, preventing leakage of the process descriptor +into the newly created child. +.Pp +The default value for the spawn-procdescp attribute is +.Dv NULL , +which means that no process descriptor will be created. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getprocdescp_np +and +.Fn posix_spawnattr_setprocdescp_np +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getprocdescp_np +and +.Fn posix_spawnattr_setprocdescp_np +are +.Fx +extensions that first appeared in +.Fx 16.0 . diff --git a/lib/libc/gen/rewinddir.c b/lib/libc/gen/rewinddir.c index df829e98d138..5cead2adc6d4 100644 --- a/lib/libc/gen/rewinddir.c +++ b/lib/libc/gen/rewinddir.c @@ -43,7 +43,6 @@ void rewinddir(DIR *dirp) { - if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */ diff --git a/lib/libc/gen/rtld_get_var.3 b/lib/libc/gen/rtld_get_var.3 index 092114e86d78..93aab133793b 100644 --- a/lib/libc/gen/rtld_get_var.3 +++ b/lib/libc/gen/rtld_get_var.3 @@ -73,6 +73,23 @@ but without the (or .Ev LD_32_ or any other ABI-specific) prefix. +.Pp +The list of variables that can be modified with the +.Fn rtld_set_var +function is: +.Bl -tag +.It Dv LD_BIND_NOT +.It Dv LD_BIND_NOW +.It Dv LD_DEBUG +.It Dv LD_DUMP_REL_PRE +.It Dv LD_DUMP_REL_POST +.It Dv LD_DYNAMIC_WEAK +.It Dv LD_LIBMAP_DISABLE +.It Dv LD_LIBRARY_PATH +.It Dv LD_LIBRARY_PATH_FDS +.It Dv LD_LIBRARY_PATH_RPATH +.It Dv LD_LOADFLTR +.El .Sh RETURN VALUES The .Fn rtld_get_var diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c index fb589f4b36b6..84b20fbafa03 100644 --- a/lib/libc/gen/scandir.c +++ b/lib/libc/gen/scandir.c @@ -232,14 +232,12 @@ scandirat(int dirfd, const char *dirname, struct dirent ***namelist, int alphasort(const struct dirent **d1, const struct dirent **d2) { - return (strcoll((*d1)->d_name, (*d2)->d_name)); } int versionsort(const struct dirent **d1, const struct dirent **d2) { - return (strverscmp((*d1)->d_name, (*d2)->d_name)); } diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index ef897c653728..75fd6307bd30 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 31, 2025 +.Dd April 15, 2026 .Dt SYSCTL 3 .Os .Sh NAME @@ -325,7 +325,7 @@ information. .Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent .It Sy Second Level Name Ta Sy Type Ta Sy Changeable .It Dv KERN_ARGMAX Ta integer Ta no -.It Dv KERN_ARND Ta integer Ta no +.It Dv KERN_ARND Ta byte buffer Ta no .It Dv KERN_BOOTFILE Ta string Ta yes .It Dv KERN_BOOTTIME Ta struct timeval Ta no .It Dv KERN_CLOCKRATE Ta struct clockinfo Ta no @@ -333,7 +333,7 @@ information. .It Dv KERN_HOSTID Ta integer Ta yes .It Dv KERN_HOSTUUID Ta string Ta yes .It Dv KERN_HOSTNAME Ta string Ta yes -.It Dv KERN_IOV_MAX Ta integer Ta yes +.It Dv KERN_IOV_MAX Ta integer Ta no .It Dv KERN_JOB_CONTROL Ta integer Ta no .It Dv KERN_LOCKF Ta struct kinfo_lockf Ta no .It Dv KERN_LOGSIGEXIT Ta integer Ta yes @@ -457,7 +457,7 @@ the currently installed userland. .It Li KERN_OSRELEASE The system release string. .It Li KERN_OSREV -The system revision string. +The system revision number. .It Li KERN_OSTYPE The system type string. .It Li KERN_POSIX1 @@ -501,14 +501,14 @@ specifies the current process. .It Dv KERN_PROC_GROUPS Ta "gid_t []" .It Dv KERN_PROC_ENV Ta "Set of strings" .It Dv KERN_PROC_AUXV Ta "Elf_Auxinfo []" -.It Dv KERN_PROC_RLIMIT Ta "Integer" -.It Dv KERN_PROC_PS_STRINGS Ta "Integer" +.It Dv KERN_PROC_RLIMIT Ta "struct rlimit" +.It Dv KERN_PROC_PS_STRINGS Ta "Pointer to struct ps_strings" .It Dv KERN_PROC_UMASK Ta "Integer/short" .It Dv KERN_PROC_OSREL Ta "Integer" -.It Dv KERN_PROC_SIGTRAMP Ta "Integer" -.It Dv KERN_PROC_CWD Ta "String" +.It Dv KERN_PROC_SIGTRAMP Ta "struct kinfo_sigtramp" +.It Dv KERN_PROC_CWD Ta "struct kinfo_file" .It Dv KERN_PROC_NFDS Ta "Integer" -.It Dv KERN_PROC_SIGFASTBLK Ta "Integer" +.It Dv KERN_PROC_SIGFASTBLK Ta "Address" .It Dv KERN_PROC_VM_LAYOUT Ta "struct kinfo_vm_layout" .It Dv KERN_PROC_RLIMIT_USAGE Ta "rlim_t []" .It Dv KERN_PROC_KQUEUE Ta "struct kinfo_knote []" @@ -570,7 +570,8 @@ Read from the note of the elf executable at time. Might be modified by the process. .It Dv KERN_PROC_SIGTRAMP -Address of the signal trampoline in the process address space, +Structure describing the address range of the signal trampoline in the +process address space, where, simplifying, the kernel passes control for signal delivery. .It Dv KERN_PROC_CWD Returns the current working directory for the process. @@ -586,6 +587,12 @@ Fills a structure describing process virtual address space layout. Like .Dv KERN_PROC_RLIMIT , but instead of the limit, returns the accounted resource usage. +If the MIB is of the form +.Li kern.proc.rlimit_usage\&. Ns Va pid , +usage values for all resources are returned. +If the MIB is of the form +.Li kern.proc.rlimit_usage\&. Ns Va pid Ns \&. Ns Va resource , +the usage value for the specified resource is returned. For resources which do not have a meaningful current value, .Li \-1 is returned. diff --git a/lib/libc/gen/syslog.3 b/lib/libc/gen/syslog.3 index 62140554f4f5..1e316c20d8d8 100644 --- a/lib/libc/gen/syslog.3 +++ b/lib/libc/gen/syslog.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 3, 2023 +.Dd March 8, 2026 .Dt SYSLOG 3 .Os .Sh NAME @@ -34,7 +34,7 @@ .Nm openlog , .Nm closelog , .Nm setlogmask -.Nd control system log +.Nd control system message log .Sh LIBRARY .Lb libc .Sh SYNOPSIS diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c index 1731cc4d7a2c..d71b7bed158c 100644 --- a/lib/libc/gen/telldir.c +++ b/lib/libc/gen/telldir.c @@ -53,7 +53,7 @@ telldir(DIR *dirp) if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); - /* + /* * Outline: * 1) If the directory position fits in a packed structure, return that. * 2) Otherwise, see if it's already been recorded in the linked list @@ -95,7 +95,7 @@ telldir(DIR *dirp) LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); } ddloc.i.is_packed = 0; - /* + /* * Technically this assignment could overflow on 32-bit architectures, * but we would get ENOMEM long before that happens. */ diff --git a/lib/libc/gen/uexterr_format.c b/lib/libc/gen/uexterr_format.c index 8d3b458ca9f2..308220adea1f 100644 --- a/lib/libc/gen/uexterr_format.c +++ b/lib/libc/gen/uexterr_format.c @@ -9,6 +9,7 @@ */ #include <sys/param.h> +#include <sys/exterr_cat.h> #include <sys/exterrvar.h> #include <exterr.h> #include <stdbool.h> @@ -34,13 +35,16 @@ static const char exterror_verbose_name[] = "EXTERROR_VERBOSE"; enum exterr_verbose_state { EXTERR_VERBOSE_UNKNOWN = 100, EXTERR_VERBOSE_DEFAULT, - EXTERR_VERBOSE_ALLOW, + EXTERR_VERBOSE_ALLOW_BRIEF, + EXTERR_VERBOSE_ALLOW_FULL, }; static enum exterr_verbose_state exterror_verbose = EXTERR_VERBOSE_UNKNOWN; static void exterr_verbose_init(void) { + const char *v; + /* * No need to care about thread-safety, the result is * idempotent. @@ -49,8 +53,9 @@ exterr_verbose_init(void) return; if (issetugid()) { exterror_verbose = EXTERR_VERBOSE_DEFAULT; - } else if (getenv(exterror_verbose_name) != NULL) { - exterror_verbose = EXTERR_VERBOSE_ALLOW; + } else if ((v = getenv(exterror_verbose_name)) != NULL) { + exterror_verbose = strcmp(v, "brief") == 0 ? + EXTERR_VERBOSE_ALLOW_BRIEF : EXTERR_VERBOSE_ALLOW_FULL; } else { exterror_verbose = EXTERR_VERBOSE_DEFAULT; } @@ -77,13 +82,21 @@ __uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz) strlcpy(buf, "", bufsz); } - if (exterror_verbose == EXTERR_VERBOSE_ALLOW || !has_msg) { + if (exterror_verbose > EXTERR_VERBOSE_DEFAULT || !has_msg) { char lbuf[128]; - snprintf(lbuf, sizeof(lbuf), - "errno %d category %u (src sys/%s:%u) p1 %#jx p2 %#jx", - ue->error, ue->cat, cat_to_filename(ue->cat), - ue->src_line, (uintmax_t)ue->p1, (uintmax_t)ue->p2); +#define SRC_FMT "(src sys/%s:%u)" + if (exterror_verbose == EXTERR_VERBOSE_ALLOW_BRIEF) { + snprintf(lbuf, sizeof(lbuf), SRC_FMT, + cat_to_filename(ue->cat), ue->src_line); + } else if (!has_msg || + exterror_verbose == EXTERR_VERBOSE_ALLOW_FULL) { + snprintf(lbuf, sizeof(lbuf), + "errno %d category %u " SRC_FMT " p1 %#jx p2 %#jx", + ue->error, ue->cat, cat_to_filename(ue->cat), + ue->src_line, (uintmax_t)ue->p1, (uintmax_t)ue->p2); + } +#undef SRC_FMT if (has_msg) strlcat(buf, " ", bufsz); strlcat(buf, lbuf, bufsz); diff --git a/lib/libc/gen/uexterr_gettext.3 b/lib/libc/gen/uexterr_gettext.3 new file mode 100644 index 000000000000..576fe49d0c37 --- /dev/null +++ b/lib/libc/gen/uexterr_gettext.3 @@ -0,0 +1,71 @@ +.\" Copyright 2026 The FreeBSD Foundation +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" This documentation was written by +.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship +.\" from the FreeBSD Foundation. +.\" +.Dd Feburary 17, 2026 +.Dt UEXTERR_GETTEXT +.Os +.Sh NAME +.Nm uexterr_gettext +.Nd "get string representation of the current extended error" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In exterr.h +.Ft int +.Fo uexterr_gettext +.Fa "char *buffer" +.Fa "size_t buffer_size" +.Fc +.Sh DESCRIPTION +The +.Nm +function fills the buffer pointed to by the +.Fa buffer +pointer with the formatted extended null-terminated +error string, as reported by the +last error from a system call, which returned an extended error. +The capacity of the passed buffer is +.Va buffer_size +bytes. +.Pp +Normally, applications should use the +.Xr err 3 +family of functions to display errors from system calls. +If this is not convenient or even not possible, +for instance for applications with an advanced user interface, the +.Nm +function can be used to fetch the string with the extended error. +.Pp +Note that most parts of the extended errors are directly provided by +the kernel, and as such cannot be localized. +.Pp +See +.Xr exterror 9 +for the description of the extended error facilities. +.Sh RETURN VALUES +The +.Fn +function returns zero. +There are currently no errors defined for the function, +which might change in future. +.Pp +If any error condition is added, it will be reported by returning \-1 +and setting +.Va errno +to the corresponding value. +.Sh SEE ALSO +.Xr errno 3 , +.Xr err 3 , +.Xr exterror 9 +.Sh STANDARDS +The +.Nm +is a +.Fx +extension that first appeared in +.Fx 15.0 . diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index db4cbc32be35..299629fce2ad 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -252,6 +252,7 @@ enum { INTERPOS__reserved0, /* was distribute_static_tls */ INTERPOS_pdfork, INTERPOS_uexterr_gettext, + INTERPOS_pdwait, INTERPOS_MAX }; diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index deca8c58fca5..b9cc29d5bfdb 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -304,6 +304,9 @@ _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap) for (nn = 4, net2 = net; net2; net2 >>= 8) netbr[--nn] = net2 & 0xff; switch (nn) { + case 4: /* net was all-zero i.e. 0.0.0.0 */ + sprintf(qbuf, "0.0.0.0.in-addr.arpa"); + break; case 3: /* Class A */ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); break; diff --git a/lib/libc/net/sockatmark.3 b/lib/libc/net/sockatmark.3 index f499eb0b902d..2b6fe2a8907b 100644 --- a/lib/libc/net/sockatmark.3 +++ b/lib/libc/net/sockatmark.3 @@ -108,8 +108,8 @@ is a descriptor for a file, not a socket. .Rs .%T "An Introductory 4.4BSD Interprocess Communication Tutorial" .%A Stuart Sechrest -.Re .%U https://docs.freebsd.org/44doc/psd/20.ipctut/paper.pdf +.Re .Rs .%T "An Advanced 4.4BSD Interprocess Communication Tutorial" .%A Samuel J. Leffler diff --git a/lib/libc/posix1e/mac.conf b/lib/libc/posix1e/mac.conf index 011143abf073..7da9bb8a9638 100644 --- a/lib/libc/posix1e/mac.conf +++ b/lib/libc/posix1e/mac.conf @@ -12,6 +12,7 @@ default_labels file ?biba,?lomac,?mls,?sebsd default_labels ifnet ?biba,?lomac,?mls,?sebsd +default_labels jail ? default_labels process ?biba,?lomac,?mls,?partition,?sebsd default_labels socket ?biba,?lomac,?mls diff --git a/lib/libc/posix1e/mac.conf.5 b/lib/libc/posix1e/mac.conf.5 index 98aa62dd83a7..99d75584a0d7 100644 --- a/lib/libc/posix1e/mac.conf.5 +++ b/lib/libc/posix1e/mac.conf.5 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 25, 2015 +.Dd January 19. 2026 .Dt MAC.CONF 5 .Os .Sh NAME @@ -79,6 +79,7 @@ and # Default label set to be used by simple MAC applications default_labels file ?biba,?lomac,?mls,?sebsd +default_labels jail ? default_labels ifnet ?biba,?lomac,?mls,?sebsd default_labels process ?biba,?lomac,?mls,?partition,?sebsd default_labels socket ?biba,?lomac,?mls diff --git a/lib/libc/powerpcspe/Makefile.inc b/lib/libc/powerpcspe/Makefile.inc deleted file mode 100644 index 0b5879574480..000000000000 --- a/lib/libc/powerpcspe/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -CFLAGS+= -I${LIBC_SRCTOP}/powerpc - -# Long double is 64-bits -SRCS+=machdep_ldisd.c -SYM_MAPS+=${LIBC_SRCTOP}/powerpc/Symbol.map diff --git a/lib/libc/powerpcspe/gen/Makefile.inc b/lib/libc/powerpcspe/gen/Makefile.inc deleted file mode 100644 index 502f3dc231bf..000000000000 --- a/lib/libc/powerpcspe/gen/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -.include "${LIBC_SRCTOP}/powerpc/gen/Makefile.common" - -SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ - fpgetsticky.c fpsetmask.c fpsetround.c \ - _setjmp.S setjmp.S sigsetjmp.S diff --git a/lib/libc/powerpcspe/gen/_setjmp.S b/lib/libc/powerpcspe/gen/_setjmp.S deleted file mode 100644 index f282e0013f97..000000000000 --- a/lib/libc/powerpcspe/gen/_setjmp.S +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */ - -#include <machine/asm.h> -/* - * C library -- _setjmp, _longjmp - * - * _longjmp(a,v) - * will generate a "return(v?v:1)" from the last call to - * _setjmp(a) - * by restoring registers from the stack. - * The previous signal state is NOT restored. - * - * jmpbuf layout: - * +------------+ - * | unused | - * +------------+ - * | unused | - * | | - * | (4 words) | - * | | - * +------------+ - * | saved regs | - * | ... | - */ - -ENTRY(_setjmp) - mflr %r11 - mfcr %r12 - evstdd %r1,24+0*8(%r3) - evstdd %r2,24+1*8(%r3) - evstdd %r11,24+2*8(%r3) - evstdd %r12,24+3*8(%r3) - evstdd %r13,24+4*8(%r3) - evstdd %r14,24+5*8(%r3) - evstdd %r15,24+6*8(%r3) - evstdd %r16,24+7*8(%r3) - evstdd %r17,24+8*8(%r3) - evstdd %r18,24+9*8(%r3) - evstdd %r19,24+10*8(%r3) - evstdd %r20,24+11*8(%r3) - evstdd %r21,24+12*8(%r3) - evstdd %r22,24+13*8(%r3) - evstdd %r23,24+14*8(%r3) - evstdd %r24,24+15*8(%r3) - evstdd %r25,24+16*8(%r3) - evstdd %r26,24+17*8(%r3) - evstdd %r27,24+18*8(%r3) - evstdd %r28,24+19*8(%r3) - evstdd %r29,24+20*8(%r3) - evstdd %r30,24+21*8(%r3) - evstdd %r31,24+22*8(%r3) - - li %r3,0 - blr -END(_setjmp) - -ENTRY(_longjmp) - evldd %r1,24+0*8(%r3) - evldd %r2,24+1*8(%r3) - evldd %r11,24+2*8(%r3) - evldd %r12,24+3*8(%r3) - evldd %r13,24+4*8(%r3) - evldd %r14,24+5*8(%r3) - evldd %r15,24+6*8(%r3) - evldd %r16,24+7*8(%r3) - evldd %r17,24+8*8(%r3) - evldd %r18,24+9*8(%r3) - evldd %r19,24+10*8(%r3) - evldd %r20,24+11*8(%r3) - evldd %r21,24+12*8(%r3) - evldd %r22,24+13*8(%r3) - evldd %r23,24+14*8(%r3) - evldd %r24,24+15*8(%r3) - evldd %r25,24+16*8(%r3) - evldd %r26,24+17*8(%r3) - evldd %r27,24+18*8(%r3) - evldd %r28,24+19*8(%r3) - evldd %r29,24+20*8(%r3) - evldd %r30,24+21*8(%r3) - evldd %r31,24+22*8(%r3) - - mtlr %r11 - mtcr %r12 - or. %r3,%r4,%r4 - bnelr - li %r3,1 - blr -END(_longjmp) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/flt_rounds.c b/lib/libc/powerpcspe/gen/flt_rounds.c deleted file mode 100644 index 26dfca0e0e3a..000000000000 --- a/lib/libc/powerpcspe/gen/flt_rounds.c +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: flt_rounds.c,v 1.4.10.3 2002/03/22 20:41:53 nathanw Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <machine/float.h> -#include <machine/spr.h> - -#ifndef _SOFT_FLOAT -static const int map[] = { - 1, /* round to nearest */ - 0, /* round to zero */ - 2, /* round to positive infinity */ - 3 /* round to negative infinity */ -}; - -int -__flt_rounds() -{ - uint32_t fpscr; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); - return map[(fpscr & 0x03)]; -} -#endif diff --git a/lib/libc/powerpcspe/gen/fpgetmask.c b/lib/libc/powerpcspe/gen/fpgetmask.c deleted file mode 100644 index f7679be4ca54..000000000000 --- a/lib/libc/powerpcspe/gen/fpgetmask.c +++ /dev/null @@ -1,46 +0,0 @@ -/* $NetBSD: fpgetmask.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dan Winship. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <machine/spr.h> -#include <ieeefp.h> - -#ifndef _SOFT_FLOAT -fp_except_t -fpgetmask() -{ - uint32_t fpscr; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); - return ((fp_except_t)((fpscr >> 2) & 0x1f)); -} -#endif diff --git a/lib/libc/powerpcspe/gen/fpgetround.c b/lib/libc/powerpcspe/gen/fpgetround.c deleted file mode 100644 index 9c01bcbaf327..000000000000 --- a/lib/libc/powerpcspe/gen/fpgetround.c +++ /dev/null @@ -1,46 +0,0 @@ -/* $NetBSD: fpgetround.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dan Winship. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <machine/spr.h> -#include <ieeefp.h> - -#ifndef _SOFT_FLOAT -fp_rnd_t -fpgetround() -{ - uint32_t fpscr; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); - return ((fp_rnd_t)(fpscr & 0x3)); -} -#endif diff --git a/lib/libc/powerpcspe/gen/fpgetsticky.c b/lib/libc/powerpcspe/gen/fpgetsticky.c deleted file mode 100644 index a97c27296cab..000000000000 --- a/lib/libc/powerpcspe/gen/fpgetsticky.c +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: fpgetsticky.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dan Winship. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "namespace.h" - -#include <sys/types.h> -#include <machine/spr.h> -#include <ieeefp.h> - -#ifndef _SOFT_FLOAT -fp_except_t -fpgetsticky() -{ - uint32_t fpscr; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); - return ((fp_except_t)((fpscr >> 25) & 0x1f)); -} -#endif diff --git a/lib/libc/powerpcspe/gen/fpsetmask.c b/lib/libc/powerpcspe/gen/fpsetmask.c deleted file mode 100644 index a7a2569df905..000000000000 --- a/lib/libc/powerpcspe/gen/fpsetmask.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: fpsetmask.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dan Winship. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <machine/spr.h> -#include <ieeefp.h> - -#ifndef _SOFT_FLOAT -fp_except_t -fpsetmask(fp_except_t mask) -{ - uint32_t fpscr; - fp_except_t old; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); - old = (fp_except_t)((fpscr >> 2) & 0x1f); - fpscr = (fpscr & 0xffffff83) | ((mask & 0x1f) << 2); - __asm__ __volatile("mtspr %1,%0;isync" :: "r"(fpscr), "K"(SPR_SPEFSCR)); - return (old); -} -#endif diff --git a/lib/libc/powerpcspe/gen/fpsetround.c b/lib/libc/powerpcspe/gen/fpsetround.c deleted file mode 100644 index 2280e190b2f9..000000000000 --- a/lib/libc/powerpcspe/gen/fpsetround.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: fpsetround.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ - -/* - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dan Winship. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <machine/spr.h> -#include <ieeefp.h> - -#ifndef _SOFT_FLOAT -fp_rnd_t -fpsetround(fp_rnd_t rnd_dir) -{ - uint32_t fpscr; - fp_rnd_t old; - - __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR) ); - old = (fp_rnd_t)(fpscr & 0x3); - fpscr = (fpscr & 0xfffffffc) | rnd_dir; - __asm__ __volatile("mtspr %1, %0;isync" :: "r"(fpscr), "K"(SPR_SPEFSCR)); - return (old); -} -#endif diff --git a/lib/libc/powerpcspe/gen/setjmp.S b/lib/libc/powerpcspe/gen/setjmp.S deleted file mode 100644 index 1bd3edcf5239..000000000000 --- a/lib/libc/powerpcspe/gen/setjmp.S +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* $NetBSD: setjmp.S,v 1.3 1998/10/03 12:30:38 tsubai Exp $ */ - -#include <machine/asm.h> -#include <sys/syscall.h> - -/* - * C library -- setjmp, longjmp - * - * longjmp(a,v) - * will generate a "return(v?v:1)" from the last call to - * setjmp(a) - * by restoring registers from the stack. - * The previous signal state is restored. - * - * jmpbuf layout: - * +------------+ - * | unused | - * +------------+ - * | sig state | - * | | - * | (4 words) | - * | | - * +------------+ - * | saved regs | - * | ... | - */ - -ENTRY(setjmp) - mr %r6,%r3 - li %r3,1 /* SIG_BLOCK, but doesn't matter */ - /* since set == NULL */ - li %r4,0 /* set = NULL */ - mr %r5,%r6 /* &oset */ - addi %r5,%r5,4 - li %r0, SYS_sigprocmask /*sigprocmask(SIG_BLOCK, NULL, &oset)*/ - sc /*assume no error XXX */ - mflr %r11 /* r11 <- link reg */ - mfcr %r12 /* r12 <- condition reg */ - mr %r10,%r1 /* r10 <- stackptr */ - mr %r9,%r2 /* r9 <- global ptr */ - evstdd %r9,24+0*8(%r6) - evstdd %r10,24+1*8(%r6) - evstdd %r11,24+2*8(%r6) - evstdd %r12,24+3*8(%r6) - evstdd %r13,24+4*8(%r6) - evstdd %r14,24+5*8(%r6) - evstdd %r15,24+6*8(%r6) - evstdd %r16,24+7*8(%r6) - evstdd %r17,24+8*8(%r6) - evstdd %r18,24+9*8(%r6) - evstdd %r19,24+10*8(%r6) - evstdd %r20,24+11*8(%r6) - evstdd %r21,24+12*8(%r6) - evstdd %r22,24+13*8(%r6) - evstdd %r23,24+14*8(%r6) - evstdd %r24,24+15*8(%r6) - evstdd %r25,24+16*8(%r6) - evstdd %r26,24+17*8(%r6) - evstdd %r27,24+18*8(%r6) - evstdd %r28,24+19*8(%r6) - evstdd %r29,24+20*8(%r6) - evstdd %r30,24+21*8(%r6) - evstdd %r31,24+22*8(%r6) - - li %r3,0 /* return (0) */ - blr -END(setjmp) - - WEAK_REFERENCE(CNAME(__longjmp), longjmp) -ENTRY(__longjmp) - evldd %r9,24+0*8(%r3) - evldd %r10,24+1*8(%r3) - evldd %r11,24+2*8(%r3) - evldd %r12,24+3*8(%r3) - evldd %r13,24+4*8(%r3) - evldd %r14,24+5*8(%r3) - evldd %r15,24+6*8(%r3) - evldd %r16,24+7*8(%r3) - evldd %r17,24+8*8(%r3) - evldd %r18,24+9*8(%r3) - evldd %r19,24+10*8(%r3) - evldd %r20,24+11*8(%r3) - evldd %r21,24+12*8(%r3) - evldd %r22,24+13*8(%r3) - evldd %r23,24+14*8(%r3) - evldd %r24,24+15*8(%r3) - evldd %r25,24+16*8(%r3) - evldd %r26,24+17*8(%r3) - evldd %r27,24+18*8(%r3) - evldd %r28,24+19*8(%r3) - evldd %r29,24+20*8(%r3) - evldd %r30,24+21*8(%r3) - evldd %r31,24+22*8(%r3) - - mr %r6,%r4 /* save val param */ - mtlr %r11 /* r11 -> link reg */ - mtcr %r12 /* r12 -> condition reg */ - mr %r1,%r10 /* r10 -> stackptr */ - mr %r4,%r3 - li %r3,3 /* SIG_SETMASK */ - addi %r4,%r4,4 /* &set */ - li %r5,0 /* oset = NULL */ - li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ - sc /* assume no error XXX */ - or. %r3,%r6,%r6 - bnelr - li %r3,1 - blr -END(__longjmp) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/sigsetjmp.S b/lib/libc/powerpcspe/gen/sigsetjmp.S deleted file mode 100644 index 45c85c3fce23..000000000000 --- a/lib/libc/powerpcspe/gen/sigsetjmp.S +++ /dev/null @@ -1,148 +0,0 @@ -/*- - * Copyright (c) 2016 Justin Hibbits - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* $NetBSD: sigsetjmp.S,v 1.4 1998/10/03 12:30:38 tsubai Exp $ */ - -#include <machine/asm.h> -/* - * C library -- sigsetjmp, siglongjmp - * - * siglongjmp(a,v) - * will generate a "return(v?v:1)" from the last call to - * sigsetjmp(a, savemask) - * by restoring registers from the stack. - * The previous signal state is restored if savemask is non-zero - * - * jmpbuf layout: - * +------------+ - * | savemask | - * +------------+ - * | sig state | - * | | - * | (4 words) | - * | | - * +------------+ - * | saved regs | - * | ... | - */ - - -#include <sys/syscall.h> - -ENTRY(sigsetjmp) - mr %r6,%r3 - stw %r4,0(%r3) - or. %r7,%r4,%r4 - beq 1f - li %r3,1 /* SIG_BLOCK, but doesn't matter */ - /* since set == NULL */ - li %r4,0 /* set = NULL */ - mr %r5,%r6 /* &oset */ - addi %r5,%r5,4 - li %r0, SYS_sigprocmask /* sigprocmask(SIG_BLOCK, NULL, &oset)*/ - sc /* assume no error XXX */ -1: - mflr %r11 - mfcr %r12 - mr %r10,%r1 - mr %r9,%r2 - - /* FPRs */ - evstdd %r9,24+0*8(%r6) - evstdd %r10,24+1*8(%r6) - evstdd %r11,24+2*8(%r6) - evstdd %r12,24+3*8(%r6) - evstdd %r13,24+4*8(%r6) - evstdd %r14,24+5*8(%r6) - evstdd %r15,24+6*8(%r6) - evstdd %r16,24+7*8(%r6) - evstdd %r17,24+8*8(%r6) - evstdd %r18,24+9*8(%r6) - evstdd %r19,24+10*8(%r6) - evstdd %r20,24+11*8(%r6) - evstdd %r21,24+12*8(%r6) - evstdd %r22,24+13*8(%r6) - evstdd %r23,24+14*8(%r6) - evstdd %r24,24+15*8(%r6) - evstdd %r25,24+16*8(%r6) - evstdd %r26,24+17*8(%r6) - evstdd %r27,24+18*8(%r6) - evstdd %r28,24+19*8(%r6) - evstdd %r29,24+20*8(%r6) - evstdd %r30,24+21*8(%r6) - evstdd %r31,24+22*8(%r6) - - li %r3,0 - blr -END(sigsetjmp) - -ENTRY(siglongjmp) - - /* FPRs */ - evldd %r9,24+0*8(%r3) - evldd %r10,24+1*8(%r3) - evldd %r11,24+2*8(%r3) - evldd %r12,24+3*8(%r3) - evldd %r13,24+4*8(%r3) - evldd %r14,24+5*8(%r3) - evldd %r15,24+6*8(%r3) - evldd %r16,24+7*8(%r3) - evldd %r17,24+8*8(%r3) - evldd %r18,24+9*8(%r3) - evldd %r19,24+10*8(%r3) - evldd %r20,24+11*8(%r3) - evldd %r21,24+12*8(%r3) - evldd %r22,24+13*8(%r3) - evldd %r23,24+14*8(%r3) - evldd %r24,24+15*8(%r3) - evldd %r25,24+16*8(%r3) - evldd %r26,24+17*8(%r3) - evldd %r27,24+18*8(%r3) - evldd %r28,24+19*8(%r3) - evldd %r29,24+20*8(%r3) - evldd %r30,24+21*8(%r3) - evldd %r31,24+22*8(%r3) - - lwz %r7,0(%r3) - mr %r6,%r4 - mtlr %r11 - mtcr %r12 - mr %r1,%r10 - or. %r7,%r7,%r7 - beq 1f - mr %r4,%r3 - li %r3,3 /* SIG_SETMASK */ - addi %r4,%r4,4 /* &set */ - li %r5,0 /* oset = NULL */ - li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ - sc /* assume no error XXX */ -1: - or. %r3,%r6,%r6 - bnelr - li %r3,1 - blr -END(siglongjmp) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/softfloat/milieu.h b/lib/libc/powerpcspe/softfloat/milieu.h deleted file mode 100644 index 6139aa58b982..000000000000 --- a/lib/libc/powerpcspe/softfloat/milieu.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */ - -/* -=============================================================================== - -This C header file is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2a. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort -has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT -TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO -PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY -AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) they include prominent notice that the work is derivative, and (2) they -include prominent notice akin to these four paragraphs for those parts of -this code that are retained. - -=============================================================================== -*/ - -/* -------------------------------------------------------------------------------- -Include common integer types and flags. -------------------------------------------------------------------------------- -*/ -#include "powerpc-gcc.h" - -/* -------------------------------------------------------------------------------- -Symbolic Boolean literals. -------------------------------------------------------------------------------- -*/ -enum { - FALSE = 0, - TRUE = 1 -}; diff --git a/lib/libc/powerpcspe/softfloat/powerpc-gcc.h b/lib/libc/powerpcspe/softfloat/powerpc-gcc.h deleted file mode 100644 index d11198866e39..000000000000 --- a/lib/libc/powerpcspe/softfloat/powerpc-gcc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ - -/* -------------------------------------------------------------------------------- -One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. -------------------------------------------------------------------------------- -*/ -#define BIGENDIAN - -/* -------------------------------------------------------------------------------- -The macro `BITS64' can be defined to indicate that 64-bit integer types are -supported by the compiler. -------------------------------------------------------------------------------- -*/ -#define BITS64 - -/* -------------------------------------------------------------------------------- -Each of the following `typedef's defines the most convenient type that holds -integers of at least as many bits as specified. For example, `uint8' should -be the most convenient type that can hold unsigned integers of as many as -8 bits. The `flag' type must be able to hold either a 0 or 1. For most -implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed -to the same as `int'. -------------------------------------------------------------------------------- -*/ -typedef int flag; -typedef unsigned int uint8; -typedef int int8; -typedef unsigned int uint16; -typedef int int16; -typedef unsigned int uint32; -typedef signed int int32; -#ifdef BITS64 -typedef unsigned long long int uint64; -typedef signed long long int int64; -#endif - -/* -------------------------------------------------------------------------------- -Each of the following `typedef's defines a type that holds integers -of _exactly_ the number of bits specified. For instance, for most -implementation of C, `bits16' and `sbits16' should be `typedef'ed to -`unsigned short int' and `signed short int' (or `short int'), respectively. -------------------------------------------------------------------------------- -*/ -typedef unsigned char bits8; -typedef signed char sbits8; -typedef unsigned short int bits16; -typedef signed short int sbits16; -typedef unsigned int bits32; -typedef signed int sbits32; -#ifdef BITS64 -typedef unsigned long long int bits64; -typedef signed long long int sbits64; -#endif - -#ifdef BITS64 -/* -------------------------------------------------------------------------------- -The `LIT64' macro takes as its argument a textual integer literal and -if necessary ``marks'' the literal as having a 64-bit integer type. -For example, the GNU C Compiler (`gcc') requires that 64-bit literals be -appended with the letters `LL' standing for `long long', which is `gcc's -name for the 64-bit integer type. Some compilers may allow `LIT64' to be -defined as the identity macro: `#define LIT64( a ) a'. -------------------------------------------------------------------------------- -*/ -#define LIT64( a ) a##LL -#endif - -/* -------------------------------------------------------------------------------- -The macro `INLINE' can be used before functions that should be inlined. If -a compiler does not support explicit inlining, this macro should be defined -to be `static'. -------------------------------------------------------------------------------- -*/ -#define INLINE static __inline - -/* -------------------------------------------------------------------------------- -The ARM FPA is odd in that it stores doubles high-order word first, no matter -what the endianness of the CPU. VFP is sane. -------------------------------------------------------------------------------- -*/ -#if defined(SOFTFLOAT_FOR_GCC) -#define FLOAT64_DEMANGLE(a) (a) -#define FLOAT64_MANGLE(a) (a) -#endif diff --git a/lib/libc/powerpcspe/softfloat/softfloat.h b/lib/libc/powerpcspe/softfloat/softfloat.h deleted file mode 100644 index b20cb3e7aa00..000000000000 --- a/lib/libc/powerpcspe/softfloat/softfloat.h +++ /dev/null @@ -1,306 +0,0 @@ -/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ - -/* This is a derivative work. */ - -/* -=============================================================================== - -This C header file is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2a. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort -has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT -TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO -PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY -AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) they include prominent notice that the work is derivative, and (2) they -include prominent notice akin to these four paragraphs for those parts of -this code that are retained. - -=============================================================================== -*/ - -/* -------------------------------------------------------------------------------- -The macro `FLOATX80' must be defined to enable the extended double-precision -floating-point format `floatx80'. If this macro is not defined, the -`floatx80' type will not be defined, and none of the functions that either -input or output the `floatx80' type will be defined. The same applies to -the `FLOAT128' macro and the quadruple-precision format `float128'. -------------------------------------------------------------------------------- -*/ -/* #define FLOATX80 */ -/* #define FLOAT128 */ - -#include <machine/ieeefp.h> - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE floating-point types. -------------------------------------------------------------------------------- -*/ -typedef unsigned int float32; -typedef unsigned long long float64; -#ifdef FLOATX80 -typedef struct { - unsigned short high; - unsigned long long low; -} floatx80; -#endif -#ifdef FLOAT128 -typedef struct { - unsigned long long high, low; -} float128; -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE floating-point underflow tininess-detection mode. -------------------------------------------------------------------------------- -*/ -#ifndef SOFTFLOAT_FOR_GCC -extern int8 float_detect_tininess; -#endif -enum { - float_tininess_after_rounding = 0, - float_tininess_before_rounding = 1 -}; - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE floating-point rounding mode. -------------------------------------------------------------------------------- -*/ -extern fp_rnd_t float_rounding_mode; -enum { - float_round_nearest_even = FP_RN, - float_round_to_zero = FP_RZ, - float_round_down = FP_RM, - float_round_up = FP_RP -}; - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE floating-point exception flags. -------------------------------------------------------------------------------- -*/ -typedef fp_except_t fp_except; - -extern fp_except float_exception_flags; -extern fp_except float_exception_mask; -enum { - float_flag_inexact = FP_X_IMP, - float_flag_underflow = FP_X_UFL, - float_flag_overflow = FP_X_OFL, - float_flag_divbyzero = FP_X_DZ, - float_flag_invalid = FP_X_INV -}; - -/* -------------------------------------------------------------------------------- -Routine to raise any or all of the software IEC/IEEE floating-point -exception flags. -------------------------------------------------------------------------------- -*/ -void float_raise( fp_except ); - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE integer-to-floating-point conversion routines. -------------------------------------------------------------------------------- -*/ -float32 int32_to_float32( int ); -float64 int32_to_float64( int ); -#ifdef FLOATX80 -floatx80 int32_to_floatx80( int ); -#endif -#ifdef FLOAT128 -float128 int32_to_float128( int ); -#endif -float32 int64_to_float32( long long ); -float64 int64_to_float64( long long ); -#ifdef FLOATX80 -floatx80 int64_to_floatx80( long long ); -#endif -#ifdef FLOAT128 -float128 int64_to_float128( long long ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE single-precision conversion routines. -------------------------------------------------------------------------------- -*/ -int float32_to_int32( float32 ); -int float32_to_int32_round_to_zero( float32 ); -unsigned int float32_to_uint32_round_to_zero( float32 ); -long long float32_to_int64( float32 ); -long long float32_to_int64_round_to_zero( float32 ); -float64 float32_to_float64( float32 ); -#ifdef FLOATX80 -floatx80 float32_to_floatx80( float32 ); -#endif -#ifdef FLOAT128 -float128 float32_to_float128( float32 ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE single-precision operations. -------------------------------------------------------------------------------- -*/ -float32 float32_round_to_int( float32 ); -float32 float32_add( float32, float32 ); -float32 float32_sub( float32, float32 ); -float32 float32_mul( float32, float32 ); -float32 float32_div( float32, float32 ); -float32 float32_rem( float32, float32 ); -float32 float32_sqrt( float32 ); -int float32_eq( float32, float32 ); -int float32_le( float32, float32 ); -int float32_lt( float32, float32 ); -int float32_eq_signaling( float32, float32 ); -int float32_le_quiet( float32, float32 ); -int float32_lt_quiet( float32, float32 ); -#ifndef SOFTFLOAT_FOR_GCC -int float32_is_signaling_nan( float32 ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE double-precision conversion routines. -------------------------------------------------------------------------------- -*/ -int float64_to_int32( float64 ); -int float64_to_int32_round_to_zero( float64 ); -unsigned int float64_to_uint32_round_to_zero( float64 ); -long long float64_to_int64( float64 ); -long long float64_to_int64_round_to_zero( float64 ); -float32 float64_to_float32( float64 ); -#ifdef FLOATX80 -floatx80 float64_to_floatx80( float64 ); -#endif -#ifdef FLOAT128 -float128 float64_to_float128( float64 ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE double-precision operations. -------------------------------------------------------------------------------- -*/ -float64 float64_round_to_int( float64 ); -float64 float64_add( float64, float64 ); -float64 float64_sub( float64, float64 ); -float64 float64_mul( float64, float64 ); -float64 float64_div( float64, float64 ); -float64 float64_rem( float64, float64 ); -float64 float64_sqrt( float64 ); -int float64_eq( float64, float64 ); -int float64_le( float64, float64 ); -int float64_lt( float64, float64 ); -int float64_eq_signaling( float64, float64 ); -int float64_le_quiet( float64, float64 ); -int float64_lt_quiet( float64, float64 ); -#ifndef SOFTFLOAT_FOR_GCC -int float64_is_signaling_nan( float64 ); -#endif - -#ifdef FLOATX80 - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE extended double-precision conversion routines. -------------------------------------------------------------------------------- -*/ -int floatx80_to_int32( floatx80 ); -int floatx80_to_int32_round_to_zero( floatx80 ); -long long floatx80_to_int64( floatx80 ); -long long floatx80_to_int64_round_to_zero( floatx80 ); -float32 floatx80_to_float32( floatx80 ); -float64 floatx80_to_float64( floatx80 ); -#ifdef FLOAT128 -float128 floatx80_to_float128( floatx80 ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE extended double-precision rounding precision. Valid -values are 32, 64, and 80. -------------------------------------------------------------------------------- -*/ -extern int floatx80_rounding_precision; - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE extended double-precision operations. -------------------------------------------------------------------------------- -*/ -floatx80 floatx80_round_to_int( floatx80 ); -floatx80 floatx80_add( floatx80, floatx80 ); -floatx80 floatx80_sub( floatx80, floatx80 ); -floatx80 floatx80_mul( floatx80, floatx80 ); -floatx80 floatx80_div( floatx80, floatx80 ); -floatx80 floatx80_rem( floatx80, floatx80 ); -floatx80 floatx80_sqrt( floatx80 ); -int floatx80_eq( floatx80, floatx80 ); -int floatx80_le( floatx80, floatx80 ); -int floatx80_lt( floatx80, floatx80 ); -int floatx80_eq_signaling( floatx80, floatx80 ); -int floatx80_le_quiet( floatx80, floatx80 ); -int floatx80_lt_quiet( floatx80, floatx80 ); -int floatx80_is_signaling_nan( floatx80 ); - -#endif - -#ifdef FLOAT128 - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE quadruple-precision conversion routines. -------------------------------------------------------------------------------- -*/ -int float128_to_int32( float128 ); -int float128_to_int32_round_to_zero( float128 ); -long long float128_to_int64( float128 ); -long long float128_to_int64_round_to_zero( float128 ); -float32 float128_to_float32( float128 ); -float64 float128_to_float64( float128 ); -#ifdef FLOATX80 -floatx80 float128_to_floatx80( float128 ); -#endif - -/* -------------------------------------------------------------------------------- -Software IEC/IEEE quadruple-precision operations. -------------------------------------------------------------------------------- -*/ -float128 float128_round_to_int( float128 ); -float128 float128_add( float128, float128 ); -float128 float128_sub( float128, float128 ); -float128 float128_mul( float128, float128 ); -float128 float128_div( float128, float128 ); -float128 float128_rem( float128, float128 ); -float128 float128_sqrt( float128 ); -int float128_eq( float128, float128 ); -int float128_le( float128, float128 ); -int float128_lt( float128, float128 ); -int float128_eq_signaling( float128, float128 ); -int float128_le_quiet( float128, float128 ); -int float128_lt_quiet( float128, float128 ); -int float128_is_signaling_nan( float128 ); - -#endif - diff --git a/lib/libc/quad/Symbol.map b/lib/libc/quad/Symbol.map index f7dcdebfc7ae..251814cb238f 100644 --- a/lib/libc/quad/Symbol.map +++ b/lib/libc/quad/Symbol.map @@ -5,15 +5,31 @@ FBSD_1.0 { * broken and they expect to see them in libc. glibc exports * them, but they do not appear to be exported in Solaris. */ -#ifndef __i386__ +#ifdef __i386__ + __cmpdi2; + __divdi3; + __moddi3; + __qdivrem; + __ucmpdi2; + __udivdi3; + __umoddi3; +#elif defined(__arm__) + __adddi3; + __anddi3; + __floatunsdidf; + __iordi3; + __lshldi3; + __one_cmpldi2; + __qdivrem; + __subdi3; + __xordi3; +#else __adddi3; __anddi3; __ashldi3; __ashrdi3; -#endif __cmpdi2; __divdi3; -#ifndef __i386__ __fixdfdi; __fixsfdi; __fixunsdfdi; @@ -24,21 +40,15 @@ FBSD_1.0 { __iordi3; __lshldi3; __lshrdi3; -#endif __moddi3; -#ifndef __i386__ __muldi3; __negdi2; __one_cmpldi2; -#endif __qdivrem; -#ifndef __i386__ __subdi3; -#endif __ucmpdi2; __udivdi3; __umoddi3; -#ifndef __i386__ __xordi3; #endif }; diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index 5a2fce013c8c..b21a3fa1670f 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -118,21 +118,12 @@ static u_int32_t net_mask(struct in_addr); /*% * Set up default settings. If the configuration file exist, the values * there will have precedence. Otherwise, the server address is set to - * INADDR_ANY and the default domain name comes from the gethostname(). - * - * An interim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 - * rather than INADDR_ANY ("0.0.0.0") as the default name server address - * since it was noted that INADDR_ANY actually meant ``the first interface - * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, - * it had to be "up" in order for you to reach your own name server. It - * was later decided that since the recommended practice is to always - * install local static routes through 127.0.0.1 for all your network - * interfaces, that we could solve this problem without a code change. + * the loopback address the default domain name comes from gethostname(). * * The configuration file should always be used, since it is the only way - * to specify a default domain. If you are running a server on your local - * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" - * in the configuration file. + * to specify options and a default domain. If you are running a server + * on your local machine, you should say "nameserver 127.0.0.1" or + * "nameserver ::1" in the configuration file. * * Return 0 if completes successfully, -1 on error */ @@ -146,6 +137,26 @@ res_ninit(res_state statp) { /*% This function has to be reachable by res_data.c but not publicly. */ int __res_vinit(res_state statp, int preinit) { + union res_sockaddr_union u[] = { + { .sin = { + .sin_family = AF_INET, +#ifdef HAVE_SA_LEN + .sin_len = sizeof(struct sockaddr_in), +#endif + .sin_port = htons(NAMESERVER_PORT), + .sin_addr = { htonl(INADDR_LOOPBACK) }, + } }, +#ifdef HAS_INET6_STRUCTS + { .sin6 = { + .sin6_family = AF_INET6, +#ifdef HAVE_SA_LEN + .sin6_len = sizeof(struct sockaddr_in6), +#endif + .sin6_port = htons(NAMESERVER_PORT), + .sin6_addr = IN6ADDR_LOOPBACK_INIT, + } }, +#endif + }; FILE *fp; char *cp, **pp; int n; @@ -158,7 +169,6 @@ __res_vinit(res_state statp, int preinit) { char *net; #endif int dots; - union res_sockaddr_union u[2]; int maxns = MAXNS; RES_SET_H_ERRNO(statp, 0); @@ -173,23 +183,6 @@ __res_vinit(res_state statp, int preinit) { statp->id = res_nrandomid(statp); - memset(u, 0, sizeof(u)); - u[nserv].sin.sin_addr.s_addr = INADDR_ANY; - u[nserv].sin.sin_family = AF_INET; - u[nserv].sin.sin_port = htons(NAMESERVER_PORT); -#ifdef HAVE_SA_LEN - u[nserv].sin.sin_len = sizeof(struct sockaddr_in); -#endif - nserv++; -#ifdef HAS_INET6_STRUCTS - u[nserv].sin6.sin6_addr = in6addr_any; - u[nserv].sin6.sin6_family = AF_INET6; - u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT); -#ifdef HAVE_SA_LEN - u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6); -#endif - nserv++; -#endif statp->nscount = 0; statp->ndots = 1; statp->pfcode = 0; @@ -224,7 +217,7 @@ __res_vinit(res_state statp, int preinit) { #ifdef RESOLVSORT statp->nsort = 0; #endif - res_setservers(statp, u, nserv); + res_setservers(statp, u, nitems(u)); #ifdef SOLARIS2 /* @@ -288,7 +281,6 @@ __res_vinit(res_state statp, int preinit) { (line[sizeof(name) - 1] == ' ' || \ line[sizeof(name) - 1] == '\t')) - nserv = 0; if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) { struct stat sb; struct timespec now; @@ -507,15 +499,8 @@ __res_vinit(res_state statp, int preinit) { #endif (void) fclose(fp); } -/* - * Last chance to get a nameserver. This should not normally - * be necessary - */ -#ifdef NO_RESOLV_CONF - if(nserv == 0) - nserv = get_nameservers(statp); -#endif + /* guess default domain if not set */ if (statp->defdname[0] == 0 && gethostname(buf, sizeof(statp->defdname) - 1) == 0 && (cp = strchr(buf, '.')) != NULL) diff --git a/lib/libc/riscv/gen/makecontext.c b/lib/libc/riscv/gen/makecontext.c index e5371d082b2c..8a6498167f13 100644 --- a/lib/libc/riscv/gen/makecontext.c +++ b/lib/libc/riscv/gen/makecontext.c @@ -80,7 +80,8 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) va_end(ap); /* Set the stack */ - gp->gp_sp = STACKALIGN(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + gp->gp_sp = STACKALIGN((uintptr_t)ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size); /* Arrange for return via the trampoline code. */ gp->gp_sepc = (__register_t)_ctx_start; gp->gp_s[0] = (__register_t)func; diff --git a/lib/libc/riscv/string/Makefile.inc b/lib/libc/riscv/string/Makefile.inc index 6dae6b2cb62d..ce965833cb27 100644 --- a/lib/libc/riscv/string/Makefile.inc +++ b/lib/libc/riscv/string/Makefile.inc @@ -5,6 +5,5 @@ MDSRCS+= \ memcpy.S \ memset.S \ strlen.S \ - strnlen.S \ strchrnul.S \ strrchr.S diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c index 03a4497b21ec..5e78cd19ebf1 100644 --- a/lib/libc/rpc/getnetconfig.c +++ b/lib/libc/rpc/getnetconfig.c @@ -118,7 +118,6 @@ struct netconfig_vars { #define NC_INVALID 0 -static int *__nc_error(void); static int parse_ncp(char *, struct netconfig *); static struct netconfig *dup_ncp(struct netconfig *); @@ -129,46 +128,10 @@ static mutex_t nc_file_lock = MUTEX_INITIALIZER; static struct netconfig_info ni = { 0, 0, NULL, NULL}; static mutex_t ni_lock = MUTEX_INITIALIZER; -static thread_key_t nc_key; -static once_t nc_once = ONCE_INITIALIZER; -static int nc_key_error; - -static void -nc_key_init(void) -{ - - nc_key_error = thr_keycreate(&nc_key, free); -} +static _Thread_local int nc_error = 0; #define MAXNETCONFIGLINE 1000 -static int * -__nc_error(void) -{ - static int nc_error = 0; - int *nc_addr; - - /* - * Use the static `nc_error' if we are the main thread - * (including non-threaded programs), or if an allocation - * fails. - */ - if (thr_main()) - return (&nc_error); - if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0) - return (&nc_error); - if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) { - nc_addr = (int *)malloc(sizeof (int)); - if (thr_setspecific(nc_key, (void *) nc_addr) != 0) { - free(nc_addr); - return (&nc_error); - } - *nc_addr = 0; - } - return (nc_addr); -} - -#define nc_error (*(__nc_error())) /* * A call to setnetconfig() establishes a /etc/netconfig "session". A session * "handle" is returned on a successful call. At the start of a session (after diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3 index 12d19df117ad..7ae3ec5c5aeb 100644 --- a/lib/libc/rpc/rpc.3 +++ b/lib/libc/rpc/rpc.3 @@ -254,9 +254,9 @@ enum xdr_op { * structure of the data type to be decoded. If this points to 0, * then the type routines should allocate dynamic storage of the * appropriate size and return it. - * bool_t (*xdrproc_t)(XDR *, caddr_t *); + * bool_t (*xdrproc_t)(XDR *, void *); */ -typedef bool_t (*xdrproc_t)(); +typedef bool_t (*xdrproc_t)(XDR *, void *); /* * The XDR handle. diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index c63b89594ce6..24a19624d366 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -72,7 +72,8 @@ static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, int *, u_int, u_int, char *); static SVCXPRT *svc_com_create(int, u_int, u_int, char *); -static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *); +static bool_t rpc_wrap_bcast(char *, const struct netbuf *, + const struct netconfig *); /* XXX */ #define IN4_LOCALHOST_STRING "127.0.0.1" @@ -307,19 +308,10 @@ registerrpc(int prognum, int versnum, int procnum, } /* - * All the following clnt_broadcast stuff is convulated; it supports - * the earlier calling style of the callback function + * Support the earlier calling style of the callback function with a + * per-thread temporary copy of the real callback. */ -static thread_key_t clnt_broadcast_key; -static resultproc_t clnt_broadcast_result_main; -static once_t clnt_broadcast_once = ONCE_INITIALIZER; - -static void -clnt_broadcast_key_init(void) -{ - - thr_keycreate(&clnt_broadcast_key, free); -} +static _Thread_local clnt_broadcast_resultproc_t clnt_broadcast_result; /* * Need to translate the netbuf address into sockaddr_in address. @@ -327,21 +319,16 @@ clnt_broadcast_key_init(void) */ /* ARGSUSED */ static bool_t -rpc_wrap_bcast(char *resultp, struct netbuf *addr, struct netconfig *nconf) +rpc_wrap_bcast(char *resultp, const struct netbuf *addr, + const struct netconfig *nconf) /* * char *resultp; // results of the call * struct netbuf *addr; // address of the guy who responded * struct netconfig *nconf; // Netconf of the transport */ { - resultproc_t clnt_broadcast_result; - if (strcmp(nconf->nc_netid, "udp")) return (FALSE); - if (thr_main()) - clnt_broadcast_result = clnt_broadcast_result_main; - else - clnt_broadcast_result = (resultproc_t)thr_getspecific(clnt_broadcast_key); return (*clnt_broadcast_result)(resultp, (struct sockaddr_in *)addr->buf); } @@ -351,7 +338,8 @@ rpc_wrap_bcast(char *resultp, struct netbuf *addr, struct netconfig *nconf) */ enum clnt_stat clnt_broadcast(u_long prog, u_long vers, u_long proc, xdrproc_t xargs, - void *argsp, xdrproc_t xresults, void *resultsp, resultproc_t eachresult) + void *argsp, xdrproc_t xresults, void *resultsp, + clnt_broadcast_resultproc_t eachresult) /* * u_long prog; // program number * u_long vers; // version number @@ -363,16 +351,16 @@ clnt_broadcast(u_long prog, u_long vers, u_long proc, xdrproc_t xargs, * resultproc_t eachresult; // call with each result obtained */ { + enum clnt_stat ret; - if (thr_main()) - clnt_broadcast_result_main = eachresult; - else { - thr_once(&clnt_broadcast_once, clnt_broadcast_key_init); - thr_setspecific(clnt_broadcast_key, (void *) eachresult); - } - return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, + clnt_broadcast_result = eachresult; + + ret = rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers, (rpcproc_t)proc, xargs, argsp, xresults, resultsp, - (resultproc_t) rpc_wrap_bcast, "udp"); + rpc_wrap_bcast, "udp"); + + clnt_broadcast_result = NULL; + return (ret); } /* diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c index edbd4e379699..4fa99316321c 100644 --- a/lib/libc/stdio/printf-pos.c +++ b/lib/libc/stdio/printf-pos.c @@ -311,11 +311,9 @@ reswitch: switch (ch) { goto rflag; } goto reswitch; -#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; -#endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; @@ -359,7 +357,6 @@ reswitch: switch (ch) { if ((error = addsarg(&types, flags))) goto error; break; -#ifndef NO_FLOATING_POINT case 'a': case 'A': case 'e': @@ -372,7 +369,6 @@ reswitch: switch (ch) { if (error) goto error; break; -#endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) error = addtype(&types, TP_INTMAXT); @@ -504,11 +500,9 @@ reswitch: switch (ch) { goto rflag; } goto reswitch; -#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; -#endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; @@ -552,7 +546,6 @@ reswitch: switch (ch) { if ((error = addsarg(&types, flags))) goto error; break; -#ifndef NO_FLOATING_POINT case 'a': case 'A': case 'e': @@ -565,7 +558,6 @@ reswitch: switch (ch) { if (error) goto error; break; -#endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) error = addtype(&types, TP_INTMAXT); @@ -744,14 +736,10 @@ build_arg_table(struct typetable *types, va_list ap, union arg **argtable) (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *); break; case T_DOUBLE: -#ifndef NO_FLOATING_POINT (*argtable) [n].doublearg = va_arg (ap, double); -#endif break; case T_LONG_DOUBLE: -#ifndef NO_FLOATING_POINT (*argtable) [n].longdoublearg = va_arg (ap, long double); -#endif break; case TP_CHAR: (*argtable) [n].pchararg = va_arg (ap, char *); diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h index 411b778dc234..9de2783c4804 100644 --- a/lib/libc/stdio/printfcommon.h +++ b/lib/libc/stdio/printfcommon.h @@ -43,7 +43,6 @@ */ -#ifndef NO_FLOATING_POINT #define dtoa __dtoa #define freedtoa __freedtoa @@ -57,7 +56,6 @@ static int exponent(CHAR *, int, CHAR); -#endif /* !NO_FLOATING_POINT */ static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *); static CHAR *__ultoa(u_long, CHAR *, int, int, const char *); @@ -280,7 +278,6 @@ __ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs) return (cp); } -#ifndef NO_FLOATING_POINT static int exponent(CHAR *p0, int exp, CHAR fmtch) @@ -318,4 +315,3 @@ exponent(CHAR *p0, int exp, CHAR fmtch) return (p - p0); } -#endif /* !NO_FLOATING_POINT */ diff --git a/lib/libc/stdio/printflocal.h b/lib/libc/stdio/printflocal.h index f3d0d3e9e216..f3bedcda6678 100644 --- a/lib/libc/stdio/printflocal.h +++ b/lib/libc/stdio/printflocal.h @@ -82,10 +82,8 @@ union arg { ptrdiff_t *pptrdiffarg; ssize_t *pssizearg; intmax_t *pintmaxarg; -#ifndef NO_FLOATING_POINT double doublearg; long double longdoublearg; -#endif wint_t wintarg; wchar_t *pwchararg; }; diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 2dc8d9022179..a4633ce7837f 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -314,7 +314,6 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap) char sign; /* sign prefix (' ', '+', '-', or \0) */ struct grouping_state gs; /* thousands' grouping info */ -#ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating * point numbers into several parts, some of which may be empty: @@ -343,7 +342,6 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap) int ndig; /* actual number of digits returned by dtoa */ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ -#endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ @@ -465,12 +463,10 @@ __vfprintf(FILE *fp, locale_t locale, int serrno, const char *fmt0, va_list ap) va_copy(orgap, ap); io_init(&io, fp); ret = 0; -#ifndef NO_FLOATING_POINT dtoaresult = NULL; decimal_point = localeconv_l(locale)->decimal_point; /* The overwhelmingly common case is decpt_len == 1. */ decpt_len = (decimal_point[1] == '\0' ? 1 : strlen(decimal_point)); -#endif /* * Scan the format for conversions (`%' character). @@ -574,11 +570,9 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; -#endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; @@ -704,7 +698,6 @@ reswitch: switch (ch) { } base = 10; goto number; -#ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { @@ -823,7 +816,6 @@ fp_common: size += grouping_init(&gs, expt, locale); } break; -#endif /* !NO_FLOATING_POINT */ case 'm': error = __strerror_rl(serrno, errnomsg, sizeof(errnomsg), locale); @@ -1023,9 +1015,7 @@ invalid: PAD(width - realsz, zeroes); /* the string or number proper */ -#ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { -#endif /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); if (gs.grouping) { @@ -1034,7 +1024,6 @@ invalid: } else { PRINT(cp, size); } -#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { @@ -1071,7 +1060,6 @@ invalid: PRINT(expstr, expsize); } } -#endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); @@ -1085,10 +1073,8 @@ done: FLUSH(); error: va_end(orgap); -#ifndef NO_FLOATING_POINT if (dtoaresult != NULL) freedtoa(dtoaresult); -#endif if (convbuf != NULL) free(convbuf); if (__sferror(fp)) diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c index 89e9e843969f..576fe7d80485 100644 --- a/lib/libc/stdio/vfscanf.c +++ b/lib/libc/stdio/vfscanf.c @@ -56,9 +56,7 @@ #include "local.h" #include "xlocale_private.h" -#ifndef NO_FLOATING_POINT #include <locale.h> -#endif #define BUF 513 /* Maximum length of numeric string. */ @@ -89,9 +87,7 @@ #define CT_FLOAT 4 /* %[efgEFG] conversion */ static const u_char *__sccl(char *, const u_char *); -#ifndef NO_FLOATING_POINT static int parsefloat(FILE *, char *, char *, locale_t); -#endif __weak_reference(__vfscanf, vfscanf); @@ -648,12 +644,10 @@ literal: base = 16; break; -#ifndef NO_FLOATING_POINT case 'A': case 'E': case 'F': case 'G': case 'a': case 'e': case 'f': case 'g': c = CT_FLOAT; break; -#endif case 'S': flags |= LONG; @@ -835,7 +829,6 @@ literal: } break; -#ifndef NO_FLOATING_POINT case CT_FLOAT: /* scan a floating point number as if by strtod */ if (width == 0 || width > sizeof(buf) - 1) @@ -858,7 +851,6 @@ literal: } } break; -#endif /* !NO_FLOATING_POINT */ } if (!(flags & SUPPRESS)) nassigned++; @@ -984,7 +976,6 @@ doswitch: /* NOTREACHED */ } -#ifndef NO_FLOATING_POINT static int parsefloat(FILE *fp, char *buf, char *end, locale_t locale) { @@ -1153,4 +1144,3 @@ parsedone: *++commit = '\0'; return (commit - buf); } -#endif diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index 0d77bd74567e..f5324915ec3e 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -389,7 +389,6 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) int prec; /* precision from format; <0 for N/A */ wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */ struct grouping_state gs; /* thousands' grouping info */ -#ifndef NO_FLOATING_POINT /* * We can decompose the printed representation of floating * point numbers into several parts, some of which may be empty: @@ -417,7 +416,6 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) int ndig; /* actual number of digits returned by dtoa */ wchar_t expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult; /* buffer allocated by dtoa */ -#endif u_long ulval; /* integer arguments %[diouxX] */ uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */ int base; /* base for [diouxX] conversion */ @@ -537,9 +535,7 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) va_copy(orgap, ap); io_init(&io, fp); ret = 0; -#ifndef NO_FLOATING_POINT decimal_point = get_decpt(locale); -#endif /* * Scan the format for conversions (`%' character). @@ -643,11 +639,9 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; -#endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; @@ -761,7 +755,6 @@ reswitch: switch (ch) { } base = 10; goto number; -#ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { @@ -885,7 +878,6 @@ fp_common: size += grouping_init(&gs, expt, locale); } break; -#endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the @@ -1080,9 +1072,7 @@ invalid: PAD(width - realsz, zeroes); /* the string or number proper */ -#ifndef NO_FLOATING_POINT if ((flags & FPT) == 0) { -#endif /* leading zeroes from decimal precision */ PAD(dprec - size, zeroes); if (gs.grouping) { @@ -1091,7 +1081,6 @@ invalid: } else { PRINT(cp, size); } -#ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { @@ -1129,7 +1118,6 @@ invalid: PRINT(expstr, expsize); } } -#endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c index 7ca64eb37811..dbe7c6c48c98 100644 --- a/lib/libc/stdio/vfwscanf.c +++ b/lib/libc/stdio/vfwscanf.c @@ -84,9 +84,7 @@ #define CT_INT 3 /* %[dioupxX] conversion */ #define CT_FLOAT 4 /* %[efgEFG] conversion */ -#ifndef NO_FLOATING_POINT static int parsefloat(FILE *, wchar_t *, wchar_t *, locale_t); -#endif struct ccl { const wchar_t *start; /* character class start */ @@ -630,12 +628,10 @@ literal: base = 16; break; -#ifndef NO_FLOATING_POINT case 'A': case 'E': case 'F': case 'G': case 'a': case 'e': case 'f': case 'g': c = CT_FLOAT; break; -#endif case 'S': flags |= LONG; @@ -813,7 +809,6 @@ literal: } break; -#ifndef NO_FLOATING_POINT case CT_FLOAT: /* scan a floating point number as if by strtod */ if (width == 0 || width > sizeof(buf) / @@ -835,7 +830,6 @@ literal: } } break; -#endif /* !NO_FLOATING_POINT */ } if (!(flags & SUPPRESS)) nassigned++; @@ -848,7 +842,6 @@ match_failure: return (nassigned); } -#ifndef NO_FLOATING_POINT static int parsefloat(FILE *fp, wchar_t *buf, wchar_t *end, locale_t locale) { @@ -1007,4 +1000,3 @@ parsedone: *++commit = '\0'; return (commit - buf); } -#endif diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c index a5671db67f58..4af0425792b0 100644 --- a/lib/libc/stdio/xprintf.c +++ b/lib/libc/stdio/xprintf.c @@ -60,10 +60,8 @@ union arg { int intarg; long longarg; intmax_t intmaxarg; -#ifndef NO_FLOATING_POINT double doublearg; long double longdoublearg; -#endif wint_t wintarg; char *pchararg; wchar_t *pwchararg; @@ -497,14 +495,10 @@ __v2printf(FILE *fp, const char *fmt0, unsigned pct, va_list ap) args[ch].pwchararg = va_arg (ap, wchar_t *); break; case PA_DOUBLE: -#ifndef NO_FLOATING_POINT args[ch].doublearg = va_arg (ap, double); -#endif break; case PA_DOUBLE | PA_FLAG_LONG_DOUBLE: -#ifndef NO_FLOATING_POINT args[ch].longdoublearg = va_arg (ap, long double); -#endif break; default: errx(1, "argtype = %x (fmt = \"%s\")\n", diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index c311ba3d2bcc..2cdff5b934cb 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -91,7 +91,7 @@ SYM_MAPS+= ${LIBC_SRCTOP}/stdlib/Symbol.map MAN+= a64l.3 abort.3 abs.3 atexit.3 atof.3 \ atoi.3 atol.3 at_quick_exit.3 bsearch.3 \ div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \ - hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \ + hcreate.3 insque.3 \ lsearch.3 memalignment.3 memory.3 ptsname.3 qsort.3 \ quick_exit.3 \ radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 realpath.3 \ @@ -101,7 +101,13 @@ MAN+= a64l.3 abort.3 abs.3 atexit.3 atof.3 \ MLINKS+=a64l.3 l64a.3 \ a64l.3 l64a_r.3 +MLINKS+=abs.3 labs.3 \ + abs.3 llabs.3 \ + abs.3 imaxabs.3 MLINKS+=atol.3 atoll.3 +MLINKS+=div.3 ldiv.3 \ + div.3 lldiv.3 \ + div.3 imaxdiv.3 MLINKS+=exit.3 _Exit.3 MLINKS+=getenv.3 clearenv.3 \ getenv.3 putenv.3 \ @@ -142,6 +148,7 @@ MLINKS+=strtod.3 strtof.3 \ MLINKS+=strtol.3 strtoll.3 \ strtol.3 strtoq.3 \ strtol.3 strtoimax.3 +MLINKS+=strtonum.3 strtonumx.3 MLINKS+=strtoul.3 strtoull.3 \ strtoul.3 strtouq.3 \ strtoul.3 strtoumax.3 diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 03a6d0b543ac..373006b4a388 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -134,6 +134,7 @@ FBSD_1.8 { FBSD_1.9 { memalignment; recallocarray; + strtonumx; tdestroy; }; diff --git a/lib/libc/stdlib/abs.3 b/lib/libc/stdlib/abs.3 index d47f83ea0f73..b5844761ef48 100644 --- a/lib/libc/stdlib/abs.3 +++ b/lib/libc/stdlib/abs.3 @@ -1,5 +1,6 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2026 Aymeric Wibo <obiwac@freebsd.org> .\" .\" This code is derived from software contributed to Berkeley by .\" the American National Standards Committee X3, on Information @@ -29,49 +30,74 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 3, 2022 +.Dd February 19, 2026 .Dt ABS 3 .Os .Sh NAME -.Nm abs -.Nd integer absolute value function -.Sh LIBRARY -.Lb libc +.Nm abs , +.Nm labs , +.Nm llabs , +.Nm imaxabs +.Nd return absolute value for integer types .Sh SYNOPSIS +.Lb libc .In stdlib.h .Ft int -.Fn abs "int j" +.Fn abs "int i" +.Ft long +.Fn labs "long i" +.Ft long long +.Fn llabs "long long i" +.In inttypes.h +.Ft intmax_t +.Fn imaxabs "intmax_t i" .Sh DESCRIPTION The -.Fn abs -function -computes -the absolute value of the integer -.Fa j . +.Fn abs , +.Fn labs , +.Fn llabs , +and +.Fn imaxabs +functions compute the absolute value of +.Fa i . .Sh RETURN VALUES The -.Fn abs -function -returns -the absolute value. +.Fn abs , +.Fn labs , +.Fn llabs , +and +.Fn imaxabs +functions return the absolute value. .Sh SEE ALSO .Xr cabs 3 , .Xr fabs 3 , .Xr floor 3 , -.Xr hypot 3 , -.Xr imaxabs 3 , -.Xr labs 3 , -.Xr llabs 3 , -.Xr math 3 +.Xr hypot 3 .Sh STANDARDS The -.Fn abs -function conforms to -.St -isoC-99 . +.Fn abs , +.Fn labs , +.Fn llabs , +and +.Fn imaxabs +functions conform to +.St -isoC-2023 +and +.St -p1003.1-2024 . .Sh HISTORY The .Fn abs function first appeared in .At v6 . +The +.Fn labs +function first appeared in +.Bx 4.3 . +The +.Fn llabs +and +.Fn imaxabs +functions first appeared in +.Fx 5.0 . .Sh BUGS The absolute value of the most negative integer remains negative. diff --git a/lib/libc/stdlib/abs.c b/lib/libc/stdlib/abs.c index baed3795bf5e..3ebbff748897 100644 --- a/lib/libc/stdlib/abs.c +++ b/lib/libc/stdlib/abs.c @@ -32,7 +32,7 @@ #include <stdlib.h> int -abs(int j) +abs(int i) { - return(j < 0 ? -j : j); + return(i < 0 ? -i : i); } diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3 index 4ff384813550..4082c887497c 100644 --- a/lib/libc/stdlib/atexit.3 +++ b/lib/libc/stdlib/atexit.3 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 6, 2002 +.Dd March 31, 2026 .Dt ATEXIT 3 .Os .Sh NAME @@ -90,6 +90,7 @@ function was called by a program that did not supply a implementation. .El .Sh SEE ALSO +.Xr _exit 2 , .Xr at_quick_exit 3 , .Xr exit 3 .Sh STANDARDS diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c index 3123bd12dca8..3d742d90fb44 100644 --- a/lib/libc/stdlib/cxa_thread_atexit_impl.c +++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c @@ -119,9 +119,9 @@ walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) static void cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) { - struct cxa_thread_dtor *dtor, *tdtor; + struct cxa_thread_dtor *dtor; - LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { + while ((dtor = LIST_FIRST(&dtors)) != NULL) { LIST_REMOVE(dtor, entry); cb(dtor); free(dtor); diff --git a/lib/libc/stdlib/div.3 b/lib/libc/stdlib/div.3 index 55c1bd107cb7..6565a4159562 100644 --- a/lib/libc/stdlib/div.3 +++ b/lib/libc/stdlib/div.3 @@ -1,8 +1,12 @@ .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> +.\" Copyright (c) 2026 Aymeric Wibo <obiwac@freebsd.org> .\" .\" This code is derived from software contributed to Berkeley by -.\" Chris Torek. +.\" Chris Torek and the American National Standards Committee X3, +.\" on Information Processing Systems. +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: @@ -27,39 +31,77 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 14, 2001 +.Dd February 18, 2026 .Dt DIV 3 .Os .Sh NAME -.Nm div +.Nm div , +.Nm ldiv , +.Nm lldiv , +.Nm imaxdiv .Nd return quotient and remainder from division -.Sh LIBRARY -.Lb libc .Sh SYNOPSIS +.Lb libc .In stdlib.h .Ft div_t -.Fn div "int num" "int denom" +.Fn div "int numer" "int denom" +.Ft ldiv_t +.Fn ldiv "long numer" "long denom" +.Ft lldiv_t +.Fn lldiv "long long numer" "long long denom" +.In inttypes.h +.Ft imaxdiv_t +.Fn imaxdiv "intmax_t numer" "intmax_t denom" .Sh DESCRIPTION The -.Fn div -function -computes the value -.Fa num/denom -and returns the quotient and remainder in a structure named -.Fa div_t -that contains two -.Vt int +.Fn div , +.Fn ldiv , +.Fn lldiv , +and +.Fn imaxdiv +functions compute the value of +.Fa numer +(the numerator) divided by +.Fa denom +(the denominator) and return the stored result in the form of the +.Fa div_t , +.Fa ldiv_t , +.Fa lldiv_t , +or +.Fa imaxdiv_t +types, respectively. +These types are structs which contain two +.Vt int , +.Vt long , +.Vt long long , +or +.Vt intmax_t members named .Va quot -and -.Va rem . -.Sh SEE ALSO -.Xr imaxdiv 3 , -.Xr ldiv 3 , -.Xr lldiv 3 +(the quotient) and +.Va rem +(the remainder). .Sh STANDARDS The +.Fn div , +.Fn ldiv , +.Fn lldiv , +and +.Fn imaxdiv +functions conform to +.St -isoC-2023 +and +.St -p1003.1-2024 . +.Sh HISTORY +The .Fn div -function -conforms to -.St -isoC-99 . +and +.Fn ldiv +functions first appeared in +.Bx 4.3 . +The +.Fn lldiv +and +.Fn imaxdiv +functions first appeared in +.Fx 5.0 . diff --git a/lib/libc/stdlib/div.c b/lib/libc/stdlib/div.c index 351dca870553..cdc6e1922060 100644 --- a/lib/libc/stdlib/div.c +++ b/lib/libc/stdlib/div.c @@ -35,12 +35,12 @@ #include <stdlib.h> /* div_t */ div_t -div(int num, int denom) +div(int numer, int denom) { div_t r; - r.quot = num / denom; - r.rem = num % denom; + r.quot = numer / denom; + r.rem = numer % denom; return (r); } diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3 index a5b5bff9d1a7..1b40f6dfea7e 100644 --- a/lib/libc/stdlib/getopt.3 +++ b/lib/libc/stdlib/getopt.3 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 5, 2014 +.Dd December 14, 2025 .Dt GETOPT 3 .Os .Sh NAME @@ -60,30 +60,49 @@ if it has been specified in the string of accepted option characters, The option string .Fa optstring may contain the following elements: individual characters, and -characters followed by a colon to indicate an option argument -is to follow. -If an individual character is followed by two colons, then the -option argument is optional; +characters followed by a colon +.Pq Ql \&: +to indicate an option argument is to follow. +If an individual character is followed by two colons +.Pq Ql \&:\&: , +then the option argument is optional; .Va optarg is set to the rest of the current -.Va argv +.Fa argv word, or .Dv NULL if there were no more characters in the current word. -This is a -.Tn GNU -extension. +This is an extension not covered by POSIX. +.Pp For example, an option string .Li \&"x" recognizes an option -.Dq Fl x , -and an option string +.Dq Fl x . +.Pp +An option string .Li \&"x:" -recognizes an option and argument -.Dq Fl x Ar argument . +recognizes an option with an argument, both +.Dq Fl x Ns Ar arg\^ , +and +.Dq Fl x Ar arg\^ . It does not matter to .Fn getopt -if a following argument has leading white space. +if the option's argument is a separate word or not. +.Pp +An option string +.Li \&"x::" +recognizes the option both without an argument +.Dq Fl x , +and with an argument +.Dq Fl x Ns Ar arg\^ . +In the latter case the argument must be part of the same +.Fa argv +word. +The +.Dq Fl x +and +.Dq Ar arg\^ +must not be separated by a whitespace on the command line. .Pp On return from .Fn getopt , @@ -267,7 +286,7 @@ Care should be taken not to use as the first character in .Fa optstring to avoid a semantic conflict with -.Tn GNU +GNU .Fn getopt , which assigns different meaning to an .Fa optstring diff --git a/lib/libc/stdlib/imaxabs.3 b/lib/libc/stdlib/imaxabs.3 deleted file mode 100644 index fa68216facc1..000000000000 --- a/lib/libc/stdlib/imaxabs.3 +++ /dev/null @@ -1,60 +0,0 @@ -.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd November 14, 2001 -.Dt IMAXABS 3 -.Os -.Sh NAME -.Nm imaxabs -.Nd returns absolute value -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In inttypes.h -.Ft intmax_t -.Fn imaxabs "intmax_t j" -.Sh DESCRIPTION -The -.Fn imaxabs -function returns the absolute value of -.Fa j . -.Sh SEE ALSO -.Xr abs 3 , -.Xr fabs 3 , -.Xr hypot 3 , -.Xr labs 3 , -.Xr llabs 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn imaxabs -function conforms to -.St -isoC-99 . -.Sh HISTORY -The -.Fn imaxabs -function first appeared in -.Fx 5.0 . -.Sh BUGS -The absolute value of the most negative integer remains negative. diff --git a/lib/libc/stdlib/imaxabs.c b/lib/libc/stdlib/imaxabs.c index 08a27ac98da7..e0fd9448f0b2 100644 --- a/lib/libc/stdlib/imaxabs.c +++ b/lib/libc/stdlib/imaxabs.c @@ -29,7 +29,7 @@ #include <inttypes.h> intmax_t -imaxabs(intmax_t j) +imaxabs(intmax_t i) { - return (j < 0 ? -j : j); + return (i < 0 ? -i : i); } diff --git a/lib/libc/stdlib/imaxdiv.3 b/lib/libc/stdlib/imaxdiv.3 deleted file mode 100644 index 1553a81edae2..000000000000 --- a/lib/libc/stdlib/imaxdiv.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd November 14, 2001 -.Dt IMAXDIV 3 -.Os -.Sh NAME -.Nm imaxdiv -.Nd returns quotient and remainder -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In inttypes.h -.Ft imaxdiv_t -.Fn imaxdiv "intmax_t numer" "intmax_t denom" -.Sh DESCRIPTION -The -.Fn imaxdiv -function computes the value of -.Fa numer -divided by -.Fa denom -and returns the stored result in the form of the -.Vt imaxdiv_t -type. -.Pp -The -.Vt imaxdiv_t -type is defined as: -.Bd -literal -offset indent -typedef struct { - intmax_t quot; /* Quotient. */ - intmax_t rem; /* Remainder. */ -} imaxdiv_t; -.Ed -.Sh SEE ALSO -.Xr div 3 , -.Xr ldiv 3 , -.Xr lldiv 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn imaxdiv -function conforms to -.St -isoC-99 . -.Sh HISTORY -The -.Fn imaxdiv -function first appeared in -.Fx 5.0 . diff --git a/lib/libc/stdlib/imaxdiv.c b/lib/libc/stdlib/imaxdiv.c index bf9737a3c47a..a8b4df2f3904 100644 --- a/lib/libc/stdlib/imaxdiv.c +++ b/lib/libc/stdlib/imaxdiv.c @@ -28,7 +28,6 @@ #include <inttypes.h> -/* See comments in div.c for implementation details. */ imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) { diff --git a/lib/libc/stdlib/labs.3 b/lib/libc/stdlib/labs.3 deleted file mode 100644 index 97f527b7d941..000000000000 --- a/lib/libc/stdlib/labs.3 +++ /dev/null @@ -1,64 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd November 14, 2001 -.Dt LABS 3 -.Os -.Sh NAME -.Nm labs -.Nd return the absolute value of a long integer -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft long -.Fn labs "long j" -.Sh DESCRIPTION -The -.Fn labs -function -returns the absolute value of the long integer -.Fa j . -.Sh SEE ALSO -.Xr abs 3 , -.Xr cabs 3 , -.Xr floor 3 , -.Xr imaxabs 3 , -.Xr llabs 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn labs -function -conforms to -.St -isoC . -.Sh BUGS -The absolute value of the most negative integer remains negative. diff --git a/lib/libc/stdlib/labs.c b/lib/libc/stdlib/labs.c index 23696f1c0f0c..93102b3a2b91 100644 --- a/lib/libc/stdlib/labs.c +++ b/lib/libc/stdlib/labs.c @@ -32,7 +32,7 @@ #include <stdlib.h> long -labs(long j) +labs(long i) { - return(j < 0 ? -j : j); + return(i < 0 ? -i : i); } diff --git a/lib/libc/stdlib/ldiv.3 b/lib/libc/stdlib/ldiv.3 deleted file mode 100644 index 66abb00d4d6c..000000000000 --- a/lib/libc/stdlib/ldiv.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd April 3, 2022 -.Dt LDIV 3 -.Os -.Sh NAME -.Nm ldiv -.Nd return quotient and remainder from division -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft ldiv_t -.Fn ldiv "long num" "long denom" -.Sh DESCRIPTION -The -.Fn ldiv -function -computes the value -.Fa num Ns / Ns Fa denom -and returns the quotient and remainder in a structure named -.Vt ldiv_t -that contains two -.Vt long -members named -.Va quot -and -.Va rem . -.Sh SEE ALSO -.Xr div 3 , -.Xr imaxdiv 3 , -.Xr lldiv 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn ldiv -function -conforms to -.St -isoC-99 . -.Sh HISTORY -An -.Fn ldiv -function with similar functionality, but a different calling convention, -first appeared in -.At v4 . diff --git a/lib/libc/stdlib/ldiv.c b/lib/libc/stdlib/ldiv.c index 4c73bcc14af4..4e92c56dd3e2 100644 --- a/lib/libc/stdlib/ldiv.c +++ b/lib/libc/stdlib/ldiv.c @@ -35,14 +35,12 @@ #include <stdlib.h> /* ldiv_t */ ldiv_t -ldiv(long num, long denom) +ldiv(long numer, long denom) { ldiv_t r; - /* see div.c for comments */ - - r.quot = num / denom; - r.rem = num % denom; + r.quot = numer / denom; + r.rem = numer % denom; return (r); } diff --git a/lib/libc/stdlib/llabs.3 b/lib/libc/stdlib/llabs.3 deleted file mode 100644 index 6a12fd539dc6..000000000000 --- a/lib/libc/stdlib/llabs.3 +++ /dev/null @@ -1,60 +0,0 @@ -.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd November 14, 2001 -.Dt LLABS 3 -.Os -.Sh NAME -.Nm llabs -.Nd returns absolute value -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft "long long" -.Fn llabs "long long j" -.Sh DESCRIPTION -The -.Fn llabs -function returns the absolute value of -.Fa j . -.Sh SEE ALSO -.Xr abs 3 , -.Xr fabs 3 , -.Xr hypot 3 , -.Xr imaxabs 3 , -.Xr labs 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn llabs -function conforms to -.St -isoC-99 . -.Sh HISTORY -The -.Fn llabs -function first appeared in -.Fx 5.0 . -.Sh BUGS -The absolute value of the most negative integer remains negative. diff --git a/lib/libc/stdlib/llabs.c b/lib/libc/stdlib/llabs.c index ac151e3a5036..ff56e526b8a9 100644 --- a/lib/libc/stdlib/llabs.c +++ b/lib/libc/stdlib/llabs.c @@ -29,7 +29,7 @@ #include <stdlib.h> long long -llabs(long long j) +llabs(long long i) { - return (j < 0 ? -j : j); + return (i < 0 ? -i : i); } diff --git a/lib/libc/stdlib/lldiv.3 b/lib/libc/stdlib/lldiv.3 deleted file mode 100644 index d1de4e9234e3..000000000000 --- a/lib/libc/stdlib/lldiv.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd November 14, 2001 -.Dt LLDIV 3 -.Os -.Sh NAME -.Nm lldiv -.Nd returns quotient and remainder -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In stdlib.h -.Ft lldiv_t -.Fn lldiv "long long numer" "long long denom" -.Sh DESCRIPTION -The -.Fn lldiv -function computes the value of -.Fa numer -divided by -.Fa denom -and returns the stored result in the form of the -.Vt lldiv_t -type. -.Pp -The -.Vt lldiv_t -type is defined as: -.Bd -literal -offset indent -typedef struct { - long long quot; /* Quotient. */ - long long rem; /* Remainder. */ -} lldiv_t; -.Ed -.Sh SEE ALSO -.Xr div 3 , -.Xr imaxdiv 3 , -.Xr ldiv 3 , -.Xr math 3 -.Sh STANDARDS -The -.Fn lldiv -function conforms to -.St -isoC-99 . -.Sh HISTORY -The -.Fn lldiv -function first appeared in -.Fx 5.0 . diff --git a/lib/libc/stdlib/lldiv.c b/lib/libc/stdlib/lldiv.c index 6feeb74bacd6..cdce0a4f6a27 100644 --- a/lib/libc/stdlib/lldiv.c +++ b/lib/libc/stdlib/lldiv.c @@ -28,7 +28,6 @@ #include <stdlib.h> -/* See comments in div.c for implementation details. */ lldiv_t lldiv(long long numer, long long denom) { diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3 index 9a2ab5c7a840..d72513c2f301 100644 --- a/lib/libc/stdlib/reallocarray.3 +++ b/lib/libc/stdlib/reallocarray.3 @@ -176,4 +176,4 @@ The function first appeared in .Ox 6.1 and -.Fx 16.0 . +.Fx 15.1 . diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3 index 76f40249963b..a17ddee0b2f1 100644 --- a/lib/libc/stdlib/realpath.3 +++ b/lib/libc/stdlib/realpath.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 10, 2025 +.Dd March 18, 2026 .Dt REALPATH 3 .Os .Sh NAME @@ -75,27 +75,24 @@ must exist when is called, and all but the last component must name either directories or symlinks pointing to the directories. .Sh "RETURN VALUES" -The +On success, the .Fn realpath function returns .Fa resolved_path -on success. -If the function was supplied -.Dv NULL -as -.Fa resolved_path , -and operation did not cause errors, the returned value is -a null-terminated string in a buffer allocated by a call to -.Fn malloc 3 . +if it was not +.Dv NULL , +or a pointer to a null-terminated string which must be freed by the +caller if it was. If an error occurs, .Fn realpath returns .Dv NULL , and if .Fa resolved_path -is not +was not .Dv NULL , -the array that it points to contains the pathname which caused the problem. +the array that it points to contains the pathname which caused the +problem. .Sh ERRORS The function .Fn realpath @@ -107,6 +104,9 @@ for any of the errors specified for the library functions and .Xr getcwd 3 . .Sh SEE ALSO +.Xr basename 3 , +.Xr dirname 3 , +.Xr free 3 , .Xr getcwd 3 .Sh STANDARDS The @@ -118,15 +118,3 @@ The .Fn realpath function first appeared in .Bx 4.4 . -.Sh CAVEATS -This implementation of -.Fn realpath -differs slightly from the Solaris implementation. -The -.Bx 4.4 -version always returns absolute pathnames, -whereas the Solaris implementation will, -under certain circumstances, return a relative -.Fa resolved_path -when given a relative -.Fa pathname . diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 18f29e95ee6b..9dc0cc4d3dd4 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -98,7 +98,6 @@ realpath1(const char *path, char *resolved) left_len = 0; } - prev_len = resolved_len; if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; @@ -129,7 +128,9 @@ realpath1(const char *path, char *resolved) /* * Append the next path component and lstat() it. */ - resolved_len = strlcat(resolved, next_token, PATH_MAX); + prev_len = resolved_len; + resolved_len += strlcpy(resolved + prev_len, next_token, + PATH_MAX - prev_len); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; return (NULL); @@ -141,8 +142,11 @@ realpath1(const char *path, char *resolved) * directory is not a directory. Rewind the path * to correctly indicate where the error lies. */ - if (errno == EACCES || errno == ENOTDIR) + if (errno == EACCES || errno == ENOTDIR) { + if (prev_len > 1) + prev_len--; resolved[prev_len] = '\0'; + } return (NULL); } if (S_ISLNK(sb.st_mode)) { diff --git a/lib/libc/stdlib/strtonum.3 b/lib/libc/stdlib/strtonum.3 index 2650d147e7cc..7e6111a6ff71 100644 --- a/lib/libc/stdlib/strtonum.3 +++ b/lib/libc/stdlib/strtonum.3 @@ -1,4 +1,5 @@ .\" Copyright (c) 2004 Ted Unangst +.\" Copyright 2023 Oxide Computer Company .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -14,11 +15,12 @@ .\" .\" $OpenBSD: strtonum.3,v 1.13 2006/04/25 05:15:42 tedu Exp $ .\" -.Dd April 29, 2004 +.Dd January 15, 2026 .Dt STRTONUM 3 .Os .Sh NAME -.Nm strtonum +.Nm strtonum , +.Nm strtonumx .Nd "reliably convert string value to an integer" .Sh SYNOPSIS .In stdlib.h @@ -29,26 +31,33 @@ .Fa "long long maxval" .Fa "const char **errstr" .Fc +.Ft long long +.Fo strtonumx +.Fa "const char *nptr" +.Fa "long long minval" +.Fa "long long maxval" +.Fa "const char **errstr" +.Fa "int base" +.Fc .Sh DESCRIPTION The .Fn strtonum -function converts the string in +and +.Fn strtonumx +functions convert the string in .Fa nptr to a .Vt "long long" value. -The -.Fn strtonum -function was designed to facilitate safe, robust programming -and overcome the shortcomings of the +These functions were designed to facilitate safe, robust programming and +overcome the shortcomings of the .Xr atoi 3 and .Xr strtol 3 family of interfaces. .Pp The string may begin with an arbitrary amount of whitespace -(as determined by -.Xr isspace 3 ) +.Pq as determined by Xr isspace 3 followed by a single optional .Ql + or @@ -57,7 +66,10 @@ sign. .Pp The remainder of the string is converted to a .Vt "long long" -value according to base 10. +value according to base 10 +.Pq for Fn strtonum +or the provided base +.Pq for Fn strtonumx . .Pp The value obtained is then checked against the provided .Fa minval @@ -68,13 +80,30 @@ If .Fa errstr is non-null, .Fn strtonum -stores an error string in +and +.Fn strtonumx +store an error string in .Fa *errstr indicating the failure. +.Pp +For +.Fn strtonumx +the value of +.Ar base +is interpreted in the same way as described in +.Xr strtoll 3 . +In particular, if the value of +.Ar base +is 0, then the expected form of +.Ar nptr +is that of a decimal constant, octal constant or hexadecimal constant, any of +which may be preceded by a + or - sign. .Sh RETURN VALUES The .Fn strtonum -function returns the result of the conversion, +and +.Fn strtonumx +functions return the result of the conversion, unless the value would exceed the provided bounds or is invalid. On error, 0 is returned, .Va errno @@ -90,6 +119,8 @@ a successful return of 0 from an error. .Sh EXAMPLES Using .Fn strtonum +and +.Fn strtonumx correctly is meant to be simpler than the alternative functions. .Bd -literal -offset indent int iterations; @@ -107,7 +138,10 @@ The above example will guarantee that the value of iterations is between .It Bq Er ERANGE The given string was out of range. .It Bq Er EINVAL -The given string did not consist solely of digit characters. +The given string did not consist solely of digit characters +.Pq for Fn strtonum , +or characters which are valid in the given base +.Pq for Fn strtonumx . .It Bq Er EINVAL The supplied .Fa minval @@ -120,12 +154,15 @@ If an error occurs, will be set to one of the following strings: .Pp .Bl -tag -width ".Li too large" -compact -.It Li "too large" +.It Qq too large The result was larger than the provided maximum value. -.It Li "too small" +.It Qq too small The result was smaller than the provided minimum value. -.It Li invalid -The string did not consist solely of digit characters. +.It Qq invalid +The string did not consist solely of characters valid in the specified base +.Pq or base 10 for Fn strtonum . +.It Qq unparsable; invalid base specified +The specified base was outside the permitted range. .El .Sh SEE ALSO .Xr atof 3 , @@ -152,3 +189,6 @@ The .Fn strtonum function first appeared in .Ox 3.6 . +The +.Fn strtonumx +function first appeared in illumos in 2023. diff --git a/lib/libc/stdlib/strtonum.c b/lib/libc/stdlib/strtonum.c index 0d0715bf39c1..44c27d6af3ad 100644 --- a/lib/libc/stdlib/strtonum.c +++ b/lib/libc/stdlib/strtonum.c @@ -2,6 +2,8 @@ * Copyright (c) 2004 Ted Unangst and Todd Miller * All rights reserved. * + * Copyright 2023 Oxide Computer Company + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. @@ -24,10 +26,13 @@ #define INVALID 1 #define TOOSMALL 2 #define TOOLARGE 3 +#define BADBASE 4 + +#define MBASE ('z' - 'a' + 1 + 10) long long -strtonum(const char *numstr, long long minval, long long maxval, - const char **errstrp) +strtonumx(const char *numstr, long long minval, long long maxval, + const char **errstrp, int base) { long long ll = 0; int error = 0; @@ -35,20 +40,23 @@ strtonum(const char *numstr, long long minval, long long maxval, struct errval { const char *errstr; int err; - } ev[4] = { + } ev[5] = { { NULL, 0 }, { "invalid", EINVAL }, { "too small", ERANGE }, { "too large", ERANGE }, + { "unparsable; invalid base specified", EINVAL }, }; ev[0].err = errno; errno = 0; if (minval > maxval) { error = INVALID; + } else if (base < 0 || base > MBASE || base == 1) { + error = BADBASE; } else { - ll = strtoll(numstr, &ep, 10); - if (errno == EINVAL || numstr == ep || *ep != '\0') + ll = strtoll(numstr, &ep, base); + if (numstr == ep || *ep != '\0') error = INVALID; else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) error = TOOSMALL; @@ -58,8 +66,15 @@ strtonum(const char *numstr, long long minval, long long maxval, if (errstrp != NULL) *errstrp = ev[error].errstr; errno = ev[error].err; - if (error) + if (error != 0) ll = 0; return (ll); } + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + return (strtonumx(numstr, minval, maxval, errstrp, 10)); +} diff --git a/lib/libc/stdlib/system.3 b/lib/libc/stdlib/system.3 index 119432342f70..f09577099a5c 100644 --- a/lib/libc/stdlib/system.3 +++ b/lib/libc/stdlib/system.3 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 11, 2024 +.Dd February 24, 2026 .Dt SYSTEM 3 .Os .Sh NAME @@ -77,8 +77,10 @@ or \-1 if an error occurred when invoking .Xr fork 2 or .Xr waitpid 2 . -A return value of 127 means the execution of the shell -failed. +If the child process fails to execute the shell, it will terminate +with an exit code of 127 and +.Nm +will return the corresponding exit status. .Sh SEE ALSO .Xr sh 1 , .Xr execve 2 , diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c index b581a6ec3b14..a2f472502bfd 100644 --- a/lib/libc/stdlib/system.c +++ b/lib/libc/stdlib/system.c @@ -32,21 +32,22 @@ #include "namespace.h" #include <sys/types.h> #include <sys/wait.h> + +#include <errno.h> +#include <paths.h> #include <signal.h> -#include <stdlib.h> #include <stddef.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> -#include <paths.h> -#include <errno.h> #include "un-namespace.h" #include "libc_private.h" +#include "spinlock.h" #pragma weak system int system(const char *command) { - return (((int (*)(const char *)) __libc_interposing[INTERPOS_system])(command)); } @@ -54,54 +55,85 @@ system(const char *command) int __libc_system(const char *command) { - pid_t pid, savedpid; - int pstat; - struct sigaction ign, intact, quitact; - sigset_t newsigblock, oldsigblock; + static spinlock_t lock = _SPINLOCK_INITIALIZER; + static volatile unsigned long concurrent; + static struct sigaction ointact, oquitact; + struct sigaction ign; + sigset_t sigblock, osigblock; + char *argv[] = { "sh", "-c", __DECONST(char *, command), NULL }; + extern char **environ; + int pstat = -1, serrno = 0; + pid_t pid; - if (!command) /* just checking... */ - return(1); + if (command == NULL) /* just checking... */ + return (eaccess(_PATH_BSHELL, X_OK) == 0); - (void)sigemptyset(&newsigblock); - (void)sigaddset(&newsigblock, SIGCHLD); - (void)sigaddset(&newsigblock, SIGINT); - (void)sigaddset(&newsigblock, SIGQUIT); - (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); - switch(pid = vfork()) { /* - * In the child, use unwrapped syscalls. libthr is in - * undefined state after vfork(). + * If we are the first concurrent instance, ignore SIGINT and + * SIGQUIT. Block SIGCHLD regardless of concurrency, since on + * FreeBSD, sigprocmask() is equivalent to pthread_sigmask(). */ - case -1: /* error */ - (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - return (-1); - case 0: /* child */ + if (__isthreaded) + _SPINLOCK(&lock); + if (concurrent++ == 0) { + memset(&ign, 0, sizeof(ign)); + ign.sa_handler = SIG_IGN; + sigemptyset(&ign.sa_mask); + (void)__libc_sigaction(SIGINT, &ign, &ointact); + (void)__libc_sigaction(SIGQUIT, &ign, &oquitact); + } + sigemptyset(&sigblock); + sigaddset(&sigblock, SIGCHLD); + (void)__libc_sigprocmask(SIG_BLOCK, &sigblock, &osigblock); + if (__isthreaded) + _SPINUNLOCK(&lock); + + /* + * Fork the child process. + */ + if ((pid = fork()) < 0) { /* error */ + serrno = errno; + } else if (pid == 0) { /* child */ /* - * Restore original signal dispositions and exec the command. + * Restore original signal dispositions. */ - (void)__sys_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); + (void)__libc_sigaction(SIGINT, &ointact, NULL); + (void)__libc_sigaction(SIGQUIT, &oquitact, NULL); + (void)__sys_sigprocmask(SIG_SETMASK, &osigblock, NULL); + /* + * Exec the command. + */ + _execve(_PATH_BSHELL, argv, environ); _exit(127); + } else { /* parent */ + /* + * Wait for the child to terminate. + */ + while (_wait4(pid, &pstat, 0, NULL) < 0) { + if (errno != EINTR) { + serrno = errno; + break; + } + } } - /* - * If we are running means that the child has either completed - * its execve, or has failed. - * Block SIGINT/QUIT because sh -c handles it and wait for - * it to clean up. + + /* + * If we are the last concurrent instance, restore original signal + * dispositions. Unblock SIGCHLD, unless it was already blocked. */ - memset(&ign, 0, sizeof(ign)); - ign.sa_handler = SIG_IGN; - (void)sigemptyset(&ign.sa_mask); - (void)__libc_sigaction(SIGINT, &ign, &intact); - (void)__libc_sigaction(SIGQUIT, &ign, &quitact); - savedpid = pid; - do { - pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); - } while (pid == -1 && errno == EINTR); - (void)__libc_sigaction(SIGINT, &intact, NULL); - (void)__libc_sigaction(SIGQUIT, &quitact, NULL); - (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - return (pid == -1 ? -1 : pstat); + if (__isthreaded) + _SPINLOCK(&lock); + if (--concurrent == 0) { + (void)__libc_sigaction(SIGINT, &ointact, NULL); + (void)__libc_sigaction(SIGQUIT, &oquitact, NULL); + } + if (!sigismember(&osigblock, SIGCHLD)) + (void)__libc_sigprocmask(SIG_UNBLOCK, &sigblock, NULL); + if (__isthreaded) + _SPINUNLOCK(&lock); + if (serrno != 0) + errno = serrno; + return (pstat); } __weak_reference(__libc_system, __system); diff --git a/lib/libc/stdlib/tdestroy.c b/lib/libc/stdlib/tdestroy.c index c324e151da11..2aeb02228e46 100644 --- a/lib/libc/stdlib/tdestroy.c +++ b/lib/libc/stdlib/tdestroy.c @@ -16,53 +16,51 @@ nul_node_free(void *node __unused) { } -/* Find the leftmost node. */ -static posix_tnode * -tdestroy_find_leftmost(posix_tnode *tn) -{ - while (tn->llink != NULL) - tn = tn->llink; - return (tn); -} - -/* - * This algorithm for non-recursive non-allocating destruction of the tree - * is described in - * https://codegolf.stackexchange.com/questions/478/free-a-binary-tree/489#489P - * and in https://devblogs.microsoft.com/oldnewthing/20251107-00/?p=111774. - */ void tdestroy(void *rootp, void (*node_free)(void *)) { - posix_tnode *tn, *tn_leftmost, *xtn; + posix_tnode *back, *curr, **front; - tn = rootp; - if (tn == NULL) + if (rootp == NULL) return; if (node_free == NULL) node_free = nul_node_free; - tn_leftmost = tn; - while (tn != NULL) { + back = rootp; + front = &back; + + for (;;) { /* - * Make the right subtree the left subtree of the - * leftmost node, and recalculate the leftmost. + * The sequence of nodes from back to just before *front linked + * by llink have been found to have non-NULL rlink. + * + * Extend *front to (*front)->llink, deleting *front from the + * sequence if it has a NULL rlink. */ - tn_leftmost = tdestroy_find_leftmost(tn_leftmost); - if (tn->rlink != NULL) { - tn_leftmost->llink = tn->rlink; - tn_leftmost = tn_leftmost->llink; + curr = *front; + if (curr->rlink != NULL) + front = &curr->llink; + else { + *front = curr->llink; + node_free(curr->key); + free(curr); } + if (*front != NULL) + continue; + if (back == NULL) + break; /* - * At this point, all children of tn have been - * arranged to be reachable via tn->left. We can - * safely delete the current node and advance to its - * left child as the new root. + * The sequence cannot be extended because *front is NULL. Make + * the rlink of the back node the new *front, the llink of the + * back node the new back, and free the old back node. */ - xtn = tn->llink; - node_free(tn->key); - free(tn); - tn = xtn; + curr = back; + back = curr->llink; + if (back == NULL) + front = &back; + *front = curr->rlink; + node_free(curr->key); + free(curr); } } diff --git a/lib/libc/string/bcmp.3 b/lib/libc/string/bcmp.3 index 954e10bfdeab..ec3caa0f1c9f 100644 --- a/lib/libc/string/bcmp.3 +++ b/lib/libc/string/bcmp.3 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 15, 2016 +.Dd October 8, 2025 .Dt BCMP 3 .Os .Sh NAME @@ -73,3 +73,11 @@ before it was moved to for .St -p1003.1-2001 compliance. +.Pp +.St -p1003.1-2008 +removes the specification of +.Fn bcmp +and it is marked as LEGACY in +.St -p1003.1-2004 . +For portability with other systems new programs should use +.Xr memcmp 3 . diff --git a/lib/libc/string/fls.c b/lib/libc/string/fls.c index ac5fb7738722..dfc8397056cb 100644 --- a/lib/libc/string/fls.c +++ b/lib/libc/string/fls.c @@ -42,5 +42,5 @@ int fls(int mask) { - return (mask == 0 ? 0 : CHAR_BIT * sizeof(mask) - __builtin_clz(mask)); + return (mask == 0 ? 0 : INT_WIDTH - __builtin_clz(mask)); } diff --git a/lib/libc/string/flsl.c b/lib/libc/string/flsl.c index d88c8dfcdc63..c6457c1382bb 100644 --- a/lib/libc/string/flsl.c +++ b/lib/libc/string/flsl.c @@ -43,5 +43,5 @@ int flsl(long mask) { - return (mask == 0 ? 0 : CHAR_BIT * sizeof(mask) - __builtin_clzl(mask)); + return (mask == 0 ? 0 : LONG_WIDTH - __builtin_clzl(mask)); } diff --git a/lib/libc/string/flsll.c b/lib/libc/string/flsll.c index 635ebacddf18..bf11f7c338f1 100644 --- a/lib/libc/string/flsll.c +++ b/lib/libc/string/flsll.c @@ -42,5 +42,5 @@ int flsll(long long mask) { - return (mask == 0 ? 0 : CHAR_BIT * sizeof(mask) - __builtin_clzll(mask)); + return (mask == 0 ? 0 : LLONG_WIDTH - __builtin_clzll(mask)); } diff --git a/lib/libc/string/swab.c b/lib/libc/string/swab.c index ed4436a49810..4f4fb26379c6 100644 --- a/lib/libc/string/swab.c +++ b/lib/libc/string/swab.c @@ -3,14 +3,16 @@ * Copyright (c) 2024 rilysh <nightquick@proton.me> */ +#include <string.h> #include <unistd.h> #include <sys/endian.h> void swab(const void * __restrict from, void * __restrict to, ssize_t len) { - const uint16_t *f __aligned(1) = from; - uint16_t *t __aligned(1) = to; + const char *f = from; + char *t = to; + uint16_t tmp; /* * POSIX says overlapping copy behavior is undefined, however many @@ -19,7 +21,12 @@ swab(const void * __restrict from, void * __restrict to, ssize_t len) * and swapping them before writing them back accomplishes this. */ while (len > 1) { - *t++ = bswap16(*f++); + memcpy(&tmp, f, 2); + tmp = bswap16(tmp); + memcpy(t, &tmp, 2); + + f += 2; + t += 2; len -= 2; } } diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 32b1b0ecee05..8acffcfd714e 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -71,3 +71,7 @@ FBSD_1.6 { FBSD_1.7 { _Fork; }; + +FBSD_1.9 { + pdwait; +}; diff --git a/lib/libc/sys/pdwait.c b/lib/libc/sys/pdwait.c new file mode 100644 index 000000000000..89d43b7fca2e --- /dev/null +++ b/lib/libc/sys/pdwait.c @@ -0,0 +1,20 @@ +/* + * Copyright 2026 The FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + */ + +#include <sys/types.h> +#include <sys/procdesc.h> +#include "libc_private.h" + +#pragma weak pdwait +int +pdwait(int fd, int *status, int options, struct __wrusage *ru, + struct __siginfo *infop) +{ + return (INTERPOS_SYS(pdwait, fd, status, options, ru, infop)); +} diff --git a/lib/libc/tests/gen/dir2_test.c b/lib/libc/tests/gen/dir2_test.c index 4ec5a1759d06..dac8ccbe472a 100644 --- a/lib/libc/tests/gen/dir2_test.c +++ b/lib/libc/tests/gen/dir2_test.c @@ -41,7 +41,6 @@ ATF_TC(telldir_after_seekdir); ATF_TC_HEAD(telldir_after_seekdir, tc) { - atf_tc_set_md_var(tc, "descr", "Calling telldir(3) after seekdir(3) " "should return the argument passed to seekdir."); } @@ -50,7 +49,7 @@ ATF_TC_BODY(telldir_after_seekdir, tc) const int NUMFILES = 1000; char template[] = "dXXXXXX"; char *tmpdir; - int i, dirfd; + int i, dd; DIR *dirp; struct dirent *de; long beginning, middle, end, td; @@ -58,8 +57,8 @@ ATF_TC_BODY(telldir_after_seekdir, tc) /* Create a temporary directory */ tmpdir = mkdtemp(template); ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed"); - dirfd = open(tmpdir, O_RDONLY | O_DIRECTORY); - ATF_REQUIRE(dirfd > 0); + dd = open(tmpdir, O_RDONLY | O_DIRECTORY); + ATF_REQUIRE(dd > 0); /* * Fill it with files. Must be > 128 to ensure that the directory @@ -70,14 +69,14 @@ ATF_TC_BODY(telldir_after_seekdir, tc) char filename[16]; snprintf(filename, sizeof(filename), "%d", i); - fd = openat(dirfd, filename, O_WRONLY | O_CREAT, 0600); + fd = openat(dd, filename, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd > 0); close(fd); } /* Get some directory bookmarks in various locations */ - dirp = fdopendir(dirfd); - ATF_REQUIRE_MSG(dirfd >= 0, "fdopendir failed"); + dirp = fdopendir(dd); + ATF_REQUIRE_MSG(dd >= 0, "fdopendir failed"); beginning = telldir(dirp); for (i = 0; i < NUMFILES / 2; i = i+1) { de = readdir(dirp); @@ -126,7 +125,7 @@ ATF_TC_BODY(telldir_at_end_of_block, tc) const int NUMFILES = 129; char template[] = "dXXXXXX"; char *tmpdir; - int i, dirfd; + int i, dd; DIR *dirp; struct dirent *de; long td; @@ -135,8 +134,8 @@ ATF_TC_BODY(telldir_at_end_of_block, tc) /* Create a temporary directory */ tmpdir = mkdtemp(template); ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed"); - dirfd = open(tmpdir, O_RDONLY | O_DIRECTORY); - ATF_REQUIRE(dirfd > 0); + dd = open(tmpdir, O_RDONLY | O_DIRECTORY); + ATF_REQUIRE(dd > 0); /* * Fill it with files. Must be > 128 to ensure that the directory @@ -147,14 +146,14 @@ ATF_TC_BODY(telldir_at_end_of_block, tc) char filename[16]; snprintf(filename, sizeof(filename), "%d", i); - fd = openat(dirfd, filename, O_WRONLY | O_CREAT, 0600); + fd = openat(dd, filename, O_WRONLY | O_CREAT, 0600); ATF_REQUIRE(fd > 0); close(fd); } /* Read all entries within the first page */ - dirp = fdopendir(dirfd); - ATF_REQUIRE_MSG(dirfd >= 0, "fdopendir failed"); + dirp = fdopendir(dd); + ATF_REQUIRE_MSG(dd >= 0, "fdopendir failed"); for (i = 0; i < NUMFILES - 1; i = i + 1) ATF_REQUIRE_MSG(readdir(dirp) != NULL, "readdir failed"); @@ -178,9 +177,8 @@ ATF_TC_BODY(telldir_at_end_of_block, tc) ATF_TP_ADD_TCS(tp) { - ATF_TP_ADD_TC(tp, telldir_after_seekdir); ATF_TP_ADD_TC(tp, telldir_at_end_of_block); - return atf_no_error(); + return (atf_no_error()); } diff --git a/lib/libc/tests/stdlib/Makefile b/lib/libc/tests/stdlib/Makefile index 9d84becfbd1f..a714a8cab774 100644 --- a/lib/libc/tests/stdlib/Makefile +++ b/lib/libc/tests/stdlib/Makefile @@ -17,6 +17,7 @@ ATF_TESTS_C+= qsort_s_test ATF_TESTS_C+= qsort_bench ATF_TESTS_C+= set_constraint_handler_s_test ATF_TESTS_C+= strfmon_test +ATF_TESTS_C+= system_test ATF_TESTS_C+= tsearch_test ATF_TESTS_CXX+= cxa_thread_atexit_test ATF_TESTS_CXX+= cxa_thread_atexit_nothr_test @@ -44,7 +45,6 @@ NETBSD_ATF_TESTS_C+= posix_memalign_test NETBSD_ATF_TESTS_C+= random_test NETBSD_ATF_TESTS_C+= strtod_test NETBSD_ATF_TESTS_C+= strtol_test -NETBSD_ATF_TESTS_C+= system_test # TODO: need to come up with a correct explanation of what the patch pho does # with h_atexit @@ -78,6 +78,7 @@ LIBADD.${t}+= netbsd util LIBADD.libc_exit_test+= pthread LIBADD.strtod_test+= m +LIBADD.system_test+= pthread SUBDIR+= dynthr_mod SUBDIR+= libatexit diff --git a/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc b/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc index 0b3b9497a6bd..d70c6b1b88dc 100644 --- a/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc +++ b/lib/libc/tests/stdlib/cxa_thread_atexit_nothr_test.cc @@ -30,7 +30,10 @@ #include <cstdio> #include <cstdlib> +#define AGAIN_CALL_LIMIT 20 + static FILE *output = NULL; +static int again_counter = 0; struct Foo { Foo() { ATF_REQUIRE(fprintf(output, "Created\n") > 0); } @@ -79,14 +82,16 @@ extern "C" int __cxa_thread_atexit(void (*)(void *), void *, void *); static void again(void *arg) { - - __cxa_thread_atexit(again, arg, &output); + if (again_counter < AGAIN_CALL_LIMIT) { + again_counter++; + __cxa_thread_atexit(again, arg, &output); + } } ATF_TEST_CASE_WITHOUT_HEAD(cxx__thread_inf_dtors); ATF_TEST_CASE_BODY(cxx__thread_inf_dtors) { - + skip("Skip since we only have main thread"); again(NULL); } diff --git a/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc b/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc index 628a70b510d1..6a5587698d37 100644 --- a/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc +++ b/lib/libc/tests/stdlib/cxa_thread_atexit_test.cc @@ -30,7 +30,10 @@ #include <cstdlib> #include <thread> +#define AGAIN_CALL_LIMIT 20 + static FILE *output = NULL; +static int again_counter = 0; struct Foo { Foo() { ATF_REQUIRE(fprintf(output, "Created\n") > 0); } @@ -52,8 +55,10 @@ extern "C" int __cxa_thread_atexit(void (*)(void *), void *, void *); static void again(void *arg) { - - __cxa_thread_atexit(again, arg, &output); + if (again_counter < AGAIN_CALL_LIMIT) { + ++again_counter; + __cxa_thread_atexit(again, arg, &output); + } } struct Baz { @@ -164,6 +169,7 @@ ATF_TEST_CASE_BODY(cxx__thread_inf_dtors) std::thread t([]() { e.use(); }); t.join(); + ATF_REQUIRE_EQ(again_counter, AGAIN_CALL_LIMIT); } ATF_INIT_TEST_CASES(tcs) diff --git a/lib/libc/tests/stdlib/system_test.c b/lib/libc/tests/stdlib/system_test.c new file mode 100644 index 000000000000..9e556f257791 --- /dev/null +++ b/lib/libc/tests/stdlib/system_test.c @@ -0,0 +1,190 @@ +/*- + * Copyright (c) 2026 Klara, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(system_true); +ATF_TC_HEAD(system_true, tc) +{ + atf_tc_set_md_var(tc, "descr", "system(\"true\")"); +} +ATF_TC_BODY(system_true, tc) +{ + ATF_REQUIRE_EQ(W_EXITCODE(0, 0), system("true")); +} + +ATF_TC(system_false); +ATF_TC_HEAD(system_false, tc) +{ + atf_tc_set_md_var(tc, "descr", "system(\"false\")"); +} +ATF_TC_BODY(system_false, tc) +{ + ATF_REQUIRE_EQ(W_EXITCODE(1, 0), system("false")); +} + +ATF_TC(system_touch); +ATF_TC_HEAD(system_touch, tc) +{ + atf_tc_set_md_var(tc, "descr", "system(\"touch file\")"); +} +ATF_TC_BODY(system_touch, tc) +{ + /* The file does not exist */ + ATF_CHECK_ERRNO(ENOENT, unlink("file")); + + /* Run a command that creates it */ + ATF_REQUIRE_EQ(W_EXITCODE(0, 0), system("touch file")); + + /* Now the file exists */ + ATF_CHECK_EQ(0, unlink("file")); +} + +ATF_TC(system_null); +ATF_TC_HEAD(system_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "system(NULL)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(system_null, tc) +{ + /* First, test in a normal environment */ + ATF_REQUIRE_EQ(1, system(NULL)); + + /* Now enter an empty chroot */ + ATF_REQUIRE_EQ(0, chroot(".")); + ATF_REQUIRE_EQ(0, chdir("/")); + + /* Test again with no shell available */ + ATF_REQUIRE_EQ(0, system(NULL)); + ATF_REQUIRE_EQ(W_EXITCODE(127, 0), system("true")); +} + +/* + * Define PROCMASK_IS_THREADMASK if sigprocmask() gets / sets the thread + * mask in multithreaded programs, which makes it impossible to verify + * that system(3) correctly blocks and unblocks SIGCHLD. + */ +#ifdef __FreeBSD__ +#define PROCMASK_IS_THREADMASK 1 +#endif + +static void * +system_thread(void *arg) +{ + char cmd[64]; + int i = (int)(intptr_t)arg; + + snprintf(cmd, sizeof(cmd), "rm flag%d ; lockf -ns lock%d true", i, i); + return ((void *)(intptr_t)system(cmd)); +} + +static inline int +sigcmpset(const sigset_t *a, const sigset_t *b) +{ + return (memcmp(a, b, sizeof(sigset_t))); +} + +ATF_TC(system_concurrent); +ATF_TC_HEAD(system_concurrent, tc) +{ + atf_tc_set_md_var(tc, "descr", "Concurrent calls"); +} +ATF_TC_BODY(system_concurrent, tc) +{ + enum { N = 3 }; + struct sigaction sigint, sigquit, sigact; + sigset_t normset, sigset; + pthread_t thr[N]; + char fn[8]; + int fd[N]; + void *arg, *ret; + + /* Create and lock the locks */ + for (int i = 0; i < N; i++) { + snprintf(fn, sizeof(fn), "lock%d", i); + fd[i] = open(fn, O_CREAT|O_EXCL|O_EXLOCK|O_CLOEXEC, 0644); + ATF_REQUIRE_MSG(fd[i] >= 0, "%s: %m", fn); + } + + /* Create the flags */ + for (int i = 0; i < N; i++) { + snprintf(fn, sizeof(fn), "flag%d", i); + ATF_REQUIRE_EQ(0, symlink(fn, fn)); + } + + /* Save the current signal dispositions */ + ATF_REQUIRE_EQ(0, sigaction(SIGINT, NULL, &sigint)); + ATF_REQUIRE_EQ(0, sigaction(SIGQUIT, NULL, &sigquit)); + ATF_REQUIRE_EQ(0, sigprocmask(0, NULL, &normset)); + + /* Spawn threads which block on these files */ + for (int i = 0; i < N; i++) { + arg = (void *)(intptr_t)i; + ATF_REQUIRE_INTEQ(0, + pthread_create(&thr[i], NULL, system_thread, arg)); + } + + /* Wait until the flags are gone */ + for (int i = 0; i < N; i++) { + snprintf(fn, sizeof(fn), "flag%d", i); + while (readlink(fn, fn, sizeof(fn)) > 0) + usleep(10000); + ATF_REQUIRE_EQ(ENOENT, errno); + } + + /* Release the locks */ + for (int i = 0; i < N; i++) { + /* Check the signal dispositions */ + ATF_REQUIRE_EQ(0, sigaction(SIGINT, NULL, &sigact)); + ATF_CHECK_EQ(SIG_IGN, sigact.sa_handler); + ATF_REQUIRE_EQ(0, sigaction(SIGQUIT, NULL, &sigact)); + ATF_CHECK_EQ(SIG_IGN, sigact.sa_handler); +#ifndef PROCMASK_IS_THREADMASK + ATF_REQUIRE_EQ(0, sigprocmask(0, NULL, &sigset)); + ATF_CHECK(sigismember(&sigset, SIGCHLD)); +#endif + + /* Close the file, releasing the lock */ + ATF_REQUIRE_INTEQ(0, close(fd[i])); + + /* Join the thread and check the return value */ + ATF_CHECK_INTEQ(0, pthread_join(thr[i], &ret)); + ATF_CHECK_INTEQ(W_EXITCODE(0, 0), (int)(intptr_t)ret); + } + + /* Check the signal dispositions */ + ATF_REQUIRE_EQ(0, sigaction(SIGINT, NULL, &sigact)); + ATF_CHECK_EQ(sigint.sa_handler, sigact.sa_handler); + ATF_CHECK_EQ(sigint.sa_flags, sigact.sa_flags); + ATF_CHECK_EQ(0, sigcmpset(&sigint.sa_mask, &sigact.sa_mask)); + ATF_REQUIRE_EQ(0, sigaction(SIGQUIT, NULL, &sigact)); + ATF_CHECK_EQ(sigquit.sa_handler, sigact.sa_handler); + ATF_CHECK_EQ(sigquit.sa_flags, sigact.sa_flags); + ATF_CHECK_EQ(0, sigcmpset(&sigquit.sa_mask, &sigact.sa_mask)); + ATF_REQUIRE_EQ(0, sigprocmask(0, NULL, &sigset)); + ATF_CHECK_EQ(0, sigcmpset(&sigset, &normset)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, system_true); + ATF_TP_ADD_TC(tp, system_false); + ATF_TP_ADD_TC(tp, system_touch); + ATF_TP_ADD_TC(tp, system_null); + ATF_TP_ADD_TC(tp, system_concurrent); + return (atf_no_error()); +} diff --git a/lib/libc/tests/string/Makefile b/lib/libc/tests/string/Makefile index a019939c30af..a4d23b2dcfe1 100644 --- a/lib/libc/tests/string/Makefile +++ b/lib/libc/tests/string/Makefile @@ -20,6 +20,7 @@ ATF_TESTS_C+= strcmp2_test ATF_TESTS_C+= strcspn_test ATF_TESTS_C+= strerror2_test ATF_TESTS_C+= strlcpy_test +ATF_TESTS_C+= strrchr2_test ATF_TESTS_C+= strspn_test ATF_TESTS_C+= strverscmp_test ATF_TESTS_C+= strxfrm_test @@ -49,6 +50,7 @@ NETBSD_ATF_TESTS_C+= swab_test SRCS.memset2_test= memset_test.c SRCS.strcmp2_test= strcmp_test.c SRCS.strerror2_test= strerror_test.c +SRCS.strrchr2_test= strrchr_test.c .include "../Makefile.netbsd-tests" diff --git a/lib/libc/tests/string/strrchr_test.c b/lib/libc/tests/string/strrchr_test.c new file mode 100644 index 000000000000..1c3d912ec3f8 --- /dev/null +++ b/lib/libc/tests/string/strrchr_test.c @@ -0,0 +1,156 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023, 2026 Robert Clausecker <fuz@FreeBSD.org> + * + * Adapted from memrchr_test.c. + */ + +#include <sys/cdefs.h> + +#include <dlfcn.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +#include <atf-c.h> + +static char *(*strrchr_fn)(const char *, int); + +/* + * Check that when looking for the character NUL, we find the + * string terminator, and not some NUL character after it. + */ +ATF_TC_WITHOUT_HEAD(nul); +ATF_TC_BODY(nul, tc) +{ + size_t i, j, k; + char buf[1+15+64]; /* offset [0+15] + 64 buffer bytes + sentinels */ + + buf[0] = '\0'; + memset(buf + 1, '-', sizeof(buf) - 1); + + for (i = 0; i < 16; i++) + for (j = 0; j < 64; j++) + for (k = j; k < 64; k++) { + buf[i + j + 1] = '\0'; + buf[i + k + 1] = '\0'; + ATF_CHECK_EQ(strrchr_fn(buf + i + 1, '\0'), buf + i + j + 1); + buf[i + j + 1] = '-'; + buf[i + k + 1] = '-'; + } +} + +/* + * Check that if the character 'X' does not occur in the string + * (but occurs before and after it), we correctly return NULL. + */ +ATF_TC_WITHOUT_HEAD(not_found); +ATF_TC_BODY(not_found, tc) +{ + size_t i, j; + char buf[1+15+64+2]; /* offset [0..15] + 64 buffer bytes + sentinels */ + + buf[0] = 'X'; + memset(buf + 1, '-', sizeof(buf) - 1); + + for (i = 0; i < 16; i++) + for (j = 0; j < 64; j++) { + buf[i + j + 1] = '\0'; + buf[i + j + 2] = 'X'; + ATF_CHECK_EQ(strrchr_fn(buf + i + 1, 'X'), NULL); + buf[i + j + 1] = '-'; + buf[i + j + 2] = '-'; + } +} + +static void +do_found_test(char buf[], size_t first, size_t second) +{ + /* invariant: first <= second */ + + buf[first] = 'X'; + buf[second] = 'X'; + ATF_CHECK_EQ(strrchr_fn(buf, 'X'), buf + second); + buf[first] = '-'; + buf[second] = '-'; +} + +/* + * Check that if the character 'X' occurs in the string multiple + * times (i. e. twice), its last encounter is returned. + */ +ATF_TC_WITHOUT_HEAD(found); +ATF_TC_BODY(found, tc) +{ + size_t i, j, k, l; + char buf[1+15+64+2]; + + buf[0] = 'X'; + memset(buf + 1, '-', sizeof(buf) - 1); + + for (i = 0; i < 16; i++) + for (j = 0; j < 64; j++) + for (k = 0; k < j; k++) + for (l = 0; l <= k; l++) { + buf[i + j + 1] = '\0'; + buf[i + j + 2] = 'X'; + do_found_test(buf + i + 1, l, k); + buf[i + j + 1] = '-'; + buf[i + j + 2] = '-'; + } +} + +static void +do_values_test(char buf[], size_t len, size_t i, int c) +{ + /* sentinels */ + buf[-1] = c; + buf[len] = '\0'; + buf[len + 1] = 'c'; + + /* fill the string with some other character, but not with NUL */ + memset(buf, c == UCHAR_MAX ? c - 1 : c + 1, len); + + if (i < len) { + buf[i] = c; + ATF_CHECK_EQ(strrchr_fn(buf, c), buf + i); + } else + ATF_CHECK_EQ(strrchr_fn(buf, c), c == 0 ? buf + len : NULL); +} + +/* + * Check that the character is found regardless of its value. + * This catches arithmetic (overflow) errors in incorrect SWAR + * implementations of byte-parallel character matching. + */ +ATF_TC_WITHOUT_HEAD(values); +ATF_TC_BODY(values, tc) +{ + size_t i, j, k; + int c; + char buf[1+15+64+2]; + + for (i = 0; i < 16; i++) + for (j = 0; j < 64; j++) + for (k = 0; k <= j; k++) + for (c = 0; c <= UCHAR_MAX; c++) + do_values_test(buf + i + 1, j, k, c); +} + +ATF_TP_ADD_TCS(tp) +{ + void *dl_handle; + + dl_handle = dlopen(NULL, RTLD_LAZY); + strrchr_fn = dlsym(dl_handle, "test_strrchr"); + if (strrchr_fn == NULL) + strrchr_fn = strrchr; + + ATF_TP_ADD_TC(tp, nul); + ATF_TP_ADD_TC(tp, not_found); + ATF_TP_ADD_TC(tp, found); + ATF_TP_ADD_TC(tp, values); + + return (atf_no_error()); +} diff --git a/lib/libc/xdr/xdr.c b/lib/libc/xdr/xdr.c index 59a843405abf..47aafea4bc30 100644 --- a/lib/libc/xdr/xdr.c +++ b/lib/libc/xdr/xdr.c @@ -696,6 +696,13 @@ xdr_string(XDR *xdrs, char **cpp, u_int maxsize) if (sp == NULL) { return(TRUE); /* already free */ } + /* + * XXX: buggy software may call this without a third + * argument via xdr_free(). Ignore maxsize since it may + * be invalid. Otherwise, if it's very small, we might + * fail to free the string. + */ + maxsize = RPC_MAXDATASIZE; /* FALLTHROUGH */ case XDR_ENCODE: size = strlen(sp); |
