diff --git a/lib/libc/aarch64/gen/_ctx_start.S b/lib/libc/aarch64/gen/_ctx_start.S index 1aeea94d0229..15edcf21d463 100644 --- a/lib/libc/aarch64/gen/_ctx_start.S +++ b/lib/libc/aarch64/gen/_ctx_start.S @@ -1,36 +1,35 @@ /*- * Copyright (c) 2015 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 ENTRY(_ctx_start) blr x19 /* Call func from makecontext */ mov x0, x20 /* Load ucp saved in makecontext */ bl _C_LABEL(ctx_done) bl _C_LABEL(abort) END(_ctx_start) diff --git a/lib/libc/aarch64/gen/fabs.S b/lib/libc/aarch64/gen/fabs.S index 79f74ecc2647..29e4b89d5ee1 100644 --- a/lib/libc/aarch64/gen/fabs.S +++ b/lib/libc/aarch64/gen/fabs.S @@ -1,31 +1,30 @@ /*- * Copyright (c) 2015 The FreeBSD Foundation - * 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. */ #include ENTRY(fabs) fabs d0, d0 ret END(fabs) diff --git a/lib/libc/aarch64/gen/fpgetmask.c b/lib/libc/aarch64/gen/fpgetmask.c index 34309d86959f..7bc56a9d75be 100644 --- a/lib/libc/aarch64/gen/fpgetmask.c +++ b/lib/libc/aarch64/gen/fpgetmask.c @@ -1,45 +1,44 @@ /*- * Copyright (c) 2015 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 #include #include #define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) fp_except_t fpgetmask(void) { uint64_t mask; /* Read the current mask */ __asm __volatile("mrs %0, fpcr" : "=&r"(mask)); return (mask & FP_X_MASK); } diff --git a/lib/libc/aarch64/gen/fpsetmask.c b/lib/libc/aarch64/gen/fpsetmask.c index c91ba2498b13..1ad3f49d603d 100644 --- a/lib/libc/aarch64/gen/fpsetmask.c +++ b/lib/libc/aarch64/gen/fpsetmask.c @@ -1,50 +1,49 @@ /*- * Copyright (c) 2015 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 #include #include #define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) fp_except_t fpsetmask(fp_except_t mask) { uint64_t old, new; mask &= FP_X_MASK; /* Read the current mask */ __asm __volatile("mrs %0, fpcr" : "=&r"(old)); new = old & ~FP_X_MASK; new |= mask; __asm __volatile("msr fpcr, %0" :: "r"(new)); return ((fp_except_t)old); } diff --git a/lib/libc/aarch64/gen/makecontext.c b/lib/libc/aarch64/gen/makecontext.c index d1775efa4725..ae23ad87d3a2 100644 --- a/lib/libc/aarch64/gen/makecontext.c +++ b/lib/libc/aarch64/gen/makecontext.c @@ -1,84 +1,83 @@ /*- * Copyright (c) 2015 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include void _ctx_start(void); void ctx_done(ucontext_t *ucp) { if (ucp->uc_link == NULL) { exit(0); } else { setcontext((const ucontext_t *)ucp->uc_link); abort(); } } __weak_reference(__makecontext, makecontext); void __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) { struct gpregs *gp; va_list ap; int i; /* A valid context is required. */ if (ucp == NULL) return; if ((argc < 0) || (argc > 8)) return; gp = &ucp->uc_mcontext.mc_gpregs; va_start(ap, argc); /* Pass up to eight arguments in x0-7. */ for (i = 0; i < argc && i < 8; i++) gp->gp_x[i] = va_arg(ap, uint64_t); va_end(ap); /* Set the stack */ gp->gp_sp = STACKALIGN(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; gp->gp_x[20] = (__register_t)ucp; } diff --git a/lib/libc/aarch64/gen/sigsetjmp.S b/lib/libc/aarch64/gen/sigsetjmp.S index df75b9399d73..cdff7a46c85b 100644 --- a/lib/libc/aarch64/gen/sigsetjmp.S +++ b/lib/libc/aarch64/gen/sigsetjmp.S @@ -1,55 +1,54 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 #include ENTRY(sigsetjmp) cmp x1, #0 b.eq 1f b _C_LABEL(setjmp) 1: b _C_LABEL(_setjmp) END(sigsetjmp) ENTRY(siglongjmp) /* Load the _setjmp magic */ ldr x2, .Lmagic ldr x3, [x0] /* Check the magic */ cmp x2, x3 b.eq 1f b _C_LABEL(longjmp) 1: b _C_LABEL(_longjmp) .align 3 .Lmagic: .quad _JB_MAGIC__SETJMP END(siglongjmp) diff --git a/lib/libc/aarch64/sys/syscall.S b/lib/libc/aarch64/sys/syscall.S index d373e1d6c52e..2c7e207f82f7 100644 --- a/lib/libc/aarch64/sys/syscall.S +++ b/lib/libc/aarch64/sys/syscall.S @@ -1,33 +1,32 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * * 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 #include "SYS.h" RSYSCALL(syscall) diff --git a/lib/libc/capability/cap_rights_init.3 b/lib/libc/capability/cap_rights_init.3 index 3267cc632498..80b522820097 100644 --- a/lib/libc/capability/cap_rights_init.3 +++ b/lib/libc/capability/cap_rights_init.3 @@ -1,251 +1,250 @@ .\" .\" Copyright (c) 2013 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 May 5, 2020 .Dt CAP_RIGHTS_INIT 3 .Os .Sh NAME .Nm cap_rights_init , .Nm cap_rights_set , .Nm cap_rights_clear , .Nm cap_rights_is_set , .Nm cap_rights_is_valid , .Nm cap_rights_merge , .Nm cap_rights_remove , .Nm cap_rights_contains .Nd manage cap_rights_t structure .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/capsicum.h .Ft cap_rights_t * .Fn cap_rights_init "cap_rights_t *rights" "..." .Ft cap_rights_t * .Fn cap_rights_set "cap_rights_t *rights" "..." .Ft cap_rights_t * .Fn cap_rights_clear "cap_rights_t *rights" "..." .Ft bool .Fn cap_rights_is_set "const cap_rights_t *rights" "..." .Ft bool .Fn cap_rights_is_valid "const cap_rights_t *rights" .Ft cap_rights_t * .Fn cap_rights_merge "cap_rights_t *dst" "const cap_rights_t *src" .Ft cap_rights_t * .Fn cap_rights_remove "cap_rights_t *dst" "const cap_rights_t *src" .Ft bool .Fn cap_rights_contains "const cap_rights_t *big" "const cap_rights_t *little" .Sh DESCRIPTION The functions documented here allow to manage the .Vt cap_rights_t structure. .Pp Capability rights should be separated with comma when passed to the .Fn cap_rights_init , .Fn cap_rights_set , .Fn cap_rights_clear and .Fn cap_rights_is_set functions. For example: .Bd -literal cap_rights_set(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT, CAP_SEEK); .Ed .Pp The complete list of the capability rights can be found in the .Xr rights 4 manual page. .Pp The .Fn cap_rights_init function initialize provided .Vt cap_rights_t structure. Only properly initialized structure can be passed to the remaining functions. For convenience the structure can be filled with capability rights instead of calling the .Fn cap_rights_set function later. For even more convenience pointer to the given structure is returned, so it can be directly passed to .Xr cap_rights_limit 2 : .Bd -literal cap_rights_t rights; if (cap_rights_limit(fd, cap_rights_init(&rights, CAP_READ, CAP_WRITE)) < 0) err(1, "Unable to limit capability rights"); .Ed .Pp The .Fn cap_rights_set function adds the given capability rights to the given .Vt cap_rights_t structure. .Pp The .Fn cap_rights_clear function removes the given capability rights from the given .Vt cap_rights_t structure. .Pp The .Fn cap_rights_is_set function checks if all the given capability rights are set for the given .Vt cap_rights_t structure. .Pp The .Fn cap_rights_is_valid function verifies if the given .Vt cap_rights_t structure is valid. .Pp The .Fn cap_rights_merge function merges all capability rights present in the .Fa src structure into the .Fa dst structure. .Pp The .Fn cap_rights_remove function removes all capability rights present in the .Fa src structure from the .Fa dst structure. .Pp The .Fn cap_rights_contains function checks if the .Fa big structure contains all capability rights present in the .Fa little structure. .Sh RETURN VALUES The functions never fail. In case an invalid capability right or an invalid .Vt cap_rights_t structure is given as an argument, the program will be aborted. .Pp The .Fn cap_rights_init , .Fn cap_rights_set and .Fn cap_rights_clear functions return pointer to the .Vt cap_rights_t structure given in the .Fa rights argument. .Pp The .Fn cap_rights_merge and .Fn cap_rights_remove functions return pointer to the .Vt cap_rights_t structure given in the .Fa dst argument. .Pp The .Fn cap_rights_is_set returns .Va true if all the given capability rights are set in the .Fa rights argument. .Pp The .Fn cap_rights_is_valid function performs various checks to see if the given .Vt cap_rights_t structure is valid and returns .Va true if it is. .Pp The .Fn cap_rights_contains function returns .Va true if all capability rights set in the .Fa little structure are also present in the .Fa big structure. .Sh EXAMPLES The following example demonstrates how to prepare a .Vt cap_rights_t structure to be passed to the .Xr cap_rights_limit 2 system call. .Bd -literal cap_rights_t rights; int fd; fd = open("/tmp/foo", O_RDWR); if (fd < 0) err(1, "open() failed"); cap_rights_init(&rights, CAP_FSTAT, CAP_READ); if (allow_write_and_seek) cap_rights_set(&rights, CAP_WRITE, CAP_SEEK); if (dont_allow_seek) cap_rights_clear(&rights, CAP_SEEK); if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) err(1, "cap_rights_limit() failed"); .Ed .Sh SEE ALSO .Xr cap_rights_limit 2 , .Xr open 2 , .Xr capsicum 4 , .Xr rights 4 .Sh HISTORY The functions .Fn cap_rights_init , .Fn cap_rights_set , .Fn cap_rights_clear , .Fn cap_rights_is_set , .Fn cap_rights_is_valid , .Fn cap_rights_merge , .Fn cap_rights_remove and .Fn cap_rights_contains first appeared in .Fx 8.3 . Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD Project. .Sh AUTHORS This family of functions was created by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship from the FreeBSD Foundation. diff --git a/lib/libc/gdtoa/machdep_ldisQ.c b/lib/libc/gdtoa/machdep_ldisQ.c index a6045f59e5d0..d39d57e9d292 100644 --- a/lib/libc/gdtoa/machdep_ldisQ.c +++ b/lib/libc/gdtoa/machdep_ldisQ.c @@ -1,52 +1,52 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2003 David Schultz * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ /* * Machine-dependent glue to integrate David Gay's gdtoa * package into libc for architectures where a long double * uses quad precision, such as aarch64 or riscv. */ #include #include #include "gdtoaimp.h" long double strtold_l(const char * __restrict s, char ** __restrict sp, locale_t locale) { long double result; strtorQ_l(s, sp, FLT_ROUNDS, &result, locale); return result; } diff --git a/lib/libc/gdtoa/machdep_ldisd.c b/lib/libc/gdtoa/machdep_ldisd.c index 776b3d8f898a..79370e05c604 100644 --- a/lib/libc/gdtoa/machdep_ldisd.c +++ b/lib/libc/gdtoa/machdep_ldisd.c @@ -1,49 +1,49 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2003 David Schultz * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ /* * Machine-dependent glue to integrate David Gay's gdtoa * package into libc for architectures where a long double * is the same as a double, such as the Alpha. */ #include #include "gdtoaimp.h" #undef strtold_l long double strtold_l(const char * __restrict s, char ** __restrict sp, locale_t locale) { return strtod_l(s, sp, locale); } diff --git a/lib/libc/gdtoa/machdep_ldisx.c b/lib/libc/gdtoa/machdep_ldisx.c index cc77946de0b7..7c7c0d9e5d28 100644 --- a/lib/libc/gdtoa/machdep_ldisx.c +++ b/lib/libc/gdtoa/machdep_ldisx.c @@ -1,53 +1,53 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2003 David Schultz * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ /* * Machine-dependent glue to integrate David Gay's gdtoa * package into libc for architectures where a long double * is an IEEE extended precision number. */ #include #include #include "gdtoaimp.h" long double strtold_l(const char * __restrict s, char ** __restrict sp, locale_t locale) { long double result; FIX_LOCALE(locale); strtorx_l(s, sp, FLT_ROUNDS, &result, locale); return result; } diff --git a/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c b/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c index ee7a12f1c1ac..1f0a8f7a944d 100644 --- a/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c +++ b/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c @@ -1,43 +1,42 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include "libc_private.h" int _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, void *(calloc_cb)(size_t, size_t)) { return (0); } diff --git a/lib/libc/gen/cap_rights_get.3 b/lib/libc/gen/cap_rights_get.3 index 46013a06ea3c..e99424c7afdc 100644 --- a/lib/libc/gen/cap_rights_get.3 +++ b/lib/libc/gen/cap_rights_get.3 @@ -1,121 +1,120 @@ .\" .\" Copyright (c) 2013 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 May 5, 2020 .Dt CAP_RIGHTS_GET 3 .Os .Sh NAME .Nm cap_rights_get .Nd obtain capability rights .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/capsicum.h .Ft int .Fn cap_rights_get "int fd" "cap_rights_t *rights" .Sh DESCRIPTION The .Nm cap_rights_get function allows to obtain current capability rights for the given descriptor. The function will fill the .Fa rights argument with all capability rights if they were not limited or capability rights configured during the last successful call of .Xr cap_rights_limit 2 on the given descriptor. .Pp The .Fa rights argument can be inspected using .Xr cap_rights_init 3 family of functions. .Pp The complete list of the capability rights can be found in the .Xr rights 4 manual page. .Sh RETURN VALUES .Rv -std .Sh EXAMPLES The following example demonstrates how to limit file descriptor capability rights and how to obtain them. .Bd -literal cap_rights_t setrights, getrights; int fd; memset(&setrights, 0, sizeof(setrights)); memset(&getrights, 0, sizeof(getrights)); fd = open("/tmp/foo", O_RDONLY); if (fd < 0) err(1, "open() failed"); cap_rights_init(&setrights, CAP_FSTAT, CAP_READ); if (cap_rights_limit(fd, &setrights) < 0 && errno != ENOSYS) err(1, "cap_rights_limit() failed"); if (cap_rights_get(fd, &getrights) < 0 && errno != ENOSYS) err(1, "cap_rights_get() failed"); assert(memcmp(&setrights, &getrights, sizeof(setrights)) == 0); .Ed .Sh ERRORS .Fn cap_rights_get succeeds unless: .Bl -tag -width Er .It Bq Er EBADF The .Fa fd argument is not a valid active descriptor. .It Bq Er EFAULT The .Fa rights argument points at an invalid address. .El .Sh SEE ALSO .Xr cap_rights_limit 2 , .Xr errno 2 , .Xr open 2 , .Xr assert 3 , .Xr cap_rights_init 3 , .Xr err 3 , .Xr memcmp 3 , .Xr memset 3 , .Xr capsicum 4 , .Xr rights 4 .Sh HISTORY The .Fn cap_rights_get function first appeared in .Fx 9.2 . Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD Project. .Sh AUTHORS This function was created by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/gen/cap_sandboxed.3 b/lib/libc/gen/cap_sandboxed.3 index e3e19d709741..6e2004fb7a29 100644 --- a/lib/libc/gen/cap_sandboxed.3 +++ b/lib/libc/gen/cap_sandboxed.3 @@ -1,74 +1,73 @@ .\" .\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 May 5, 2020 .Dt CAP_SANDBOXED 3 .Os .Sh NAME .Nm cap_sandboxed .Nd Check if in a capability mode sandbox .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/capsicum.h .In stdbool.h .Ft bool .Fn cap_sandboxed "void" .Sh DESCRIPTION .Fn cap_sandboxed returns .Va true if the process is in a capability mode sandbox or .Va false if it is not. This function is a more handy alternative to the .Xr cap_getmode 2 system call as it always succeeds, so there is no need for error checking. If the support for capability mode is not compiled into the kernel, .Fn cap_sandboxed will always return .Va false . .Sh RETURN VALUES Function .Fn cap_sandboxed is always successful and will return either .Va true or .Va false . .Sh SEE ALSO .Xr cap_enter 2 , .Xr capsicum 4 .Sh HISTORY The .Fn cap_sandboxed function first appeared in .Fx 9.2 . .Sh AUTHORS This function was implemented and manual page was written by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/gen/cap_sandboxed.c b/lib/libc/gen/cap_sandboxed.c index 0252a702c6e4..d01d94735bec 100644 --- a/lib/libc/gen/cap_sandboxed.c +++ b/lib/libc/gen/cap_sandboxed.c @@ -1,50 +1,49 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from * the FreeBSD Foundation. * * 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 AUTHORS 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 AUTHORS 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 #include #include #include #include bool cap_sandboxed(void) { u_int mode; if (cap_getmode(&mode) != 0) { assert(errno == ENOSYS); return (false); } assert(mode == 0 || mode == 1); return (mode == 1); } diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index ebf18fc6a1c4..e211f3d535ad 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -1,308 +1,308 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include __SCCSID("@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"); /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ /* * Some notes on multibyte character support: * 1. Patterns with illegal byte sequences match nothing. * 2. Illegal byte sequences in the "string" argument are handled by treating * them as single-byte characters with a value of the first byte of the * sequence cast to wchar_t. * 3. Multibyte conversion state objects (mbstate_t) are passed around and * used for most, but not all, conversions. Further work will be required * to support state-dependent encodings. */ #include #include #include #include #include #include "collate.h" #define EOS '\0' #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, mbstate_t); int fnmatch(const char *pattern, const char *string, int flags) { static const mbstate_t initial; return (fnmatch1(pattern, string, string, flags, initial, initial)); } static int fnmatch1(const char *pattern, const char *string, const char *stringstart, int flags, mbstate_t patmbs, mbstate_t strmbs) { const char *bt_pattern, *bt_string; mbstate_t bt_patmbs, bt_strmbs; char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; bt_pattern = bt_string = NULL; for (;;) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; memset(&strmbs, 0, sizeof(strmbs)); } switch (pc) { case EOS: if ((flags & FNM_LEADING_DIR) && sc == '/') return (0); if (sc == EOS) return (0); goto backtrack; case '?': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; string += sclen; break; case '*': c = *pattern; /* Collapse multiple stars. */ while (c == '*') c = *++pattern; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; /* Optimize for pattern with * at end or before /. */ if (c == EOS) if (flags & FNM_PATHNAME) return ((flags & FNM_LEADING_DIR) || strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); else return (0); else if (c == '/' && flags & FNM_PATHNAME) { if ((string = strchr(string, '/')) == NULL) return (FNM_NOMATCH); break; } /* * First try the shortest match for the '*' that * could work. We can forget any earlier '*' since * there is no way having it match more characters * can help us, given that we are already here. */ bt_pattern = pattern, bt_patmbs = patmbs; bt_string = string, bt_strmbs = strmbs; break; case '[': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; switch (rangematch(pattern, sc, flags, &newp, &patmbs)) { case RANGE_ERROR: goto norm; case RANGE_MATCH: pattern = newp; break; case RANGE_NOMATCH: goto backtrack; } string += sclen; break; case '\\': if (!(flags & FNM_NOESCAPE)) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == 0 || pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; } /* FALLTHROUGH */ default: norm: string += sclen; if (pc == sc) ; else if ((flags & FNM_CASEFOLD) && (towlower(pc) == towlower(sc))) ; else { backtrack: /* * If we have a mismatch (other than hitting * the end of the string), go back to the last * '*' seen and have it match one additional * character. */ if (bt_pattern == NULL) return (FNM_NOMATCH); sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX, &bt_strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*bt_string; sclen = 1; memset(&bt_strmbs, 0, sizeof(bt_strmbs)); } if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && flags & FNM_PATHNAME) return (FNM_NOMATCH); bt_string += sclen; pattern = bt_pattern, patmbs = bt_patmbs; string = bt_string, strmbs = bt_strmbs; } break; } } /* NOTREACHED */ } static int rangematch(const char *pattern, wchar_t test, int flags, char **newp, mbstate_t *patmbs) { int negate, ok; wchar_t c, c2; size_t pclen; const char *origpat; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* * A bracket expression starting with an unquoted circumflex * character produces unspecified results (IEEE 1003.2-1992, * 3.13.2). This implementation treats it like '!', for * consistency with the regular expression syntax. * J.T. Conklin (conklin@ngai.kaleida.com) */ if ((negate = (*pattern == '!' || *pattern == '^'))) ++pattern; if (flags & FNM_CASEFOLD) test = towlower(test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 */ ok = 0; origpat = pattern; for (;;) { if (*pattern == ']' && pattern > origpat) { pattern++; break; } else if (*pattern == '\0') { return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (flags & FNM_CASEFOLD) c = towlower(c); if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) if (*pattern != EOS) pattern++; pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_CASEFOLD) c2 = towlower(c2); if (table->__collate_load_error ? c <= test && test <= c2 : __wcollate_range_cmp(c, test) <= 0 && __wcollate_range_cmp(test, c2) <= 0 ) ok = 1; } else if (c == test) ok = 1; } *newp = (char *)pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); } diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c index c2744b80ac69..52a5ce4e7197 100644 --- a/lib/libc/gen/glob.c +++ b/lib/libc/gen/glob.c @@ -1,1117 +1,1117 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include __SCCSID("@(#)glob.c 8.3 (Berkeley) 10/13/93"); /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * * The [!...] convention to negate a range is supported (SysV, Posix, ksh). * * Optional extra services, controlled by flags not defined by POSIX: * * GLOB_QUOTE: * Escaping convention: \ inhibits any special meaning the following * character might have (except \ at end of string is retained). * GLOB_MAGCHAR: * Set in gl_flags if pattern contained a globbing character. * GLOB_NOMAGIC: * Same as GLOB_NOCHECK, but it will only append pattern if it did * not contain any magic characters. [Used in csh style globbing] * GLOB_ALTDIRFUNC: * Use alternately specified directory access functions. * GLOB_TILDE: * expand ~user/foo to the /home/dir/of/user/foo * GLOB_BRACE: * expand {1,2}{a,b} to 1a 1b 2a 2b * gl_matchc: * Number of matches in the current invocation of glob. */ /* * Some notes on multibyte character support: * 1. Patterns with illegal byte sequences match nothing - even if * GLOB_NOCHECK is specified. * 2. Illegal byte sequences in filenames are handled by treating them as * single-byte characters with a values of such bytes of the sequence * cast to wchar_t. * 3. State-dependent encodings are not currently supported. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "collate.h" /* * glob(3) expansion limits. Stop the expansion if any of these limits * is reached. This caps the runtime in the face of DoS attacks. See * also CVE-2010-2632 */ #define GLOB_LIMIT_BRACE 128 /* number of brace calls */ #define GLOB_LIMIT_PATH 65536 /* number of path elements */ #define GLOB_LIMIT_READDIR 16384 /* number of readdirs */ #define GLOB_LIMIT_STAT 1024 /* number of stat system calls */ #define GLOB_LIMIT_STRING ARG_MAX /* maximum total size for paths */ struct glob_limit { size_t l_brace_cnt; size_t l_path_lim; size_t l_readdir_cnt; size_t l_stat_cnt; size_t l_string_cnt; }; #define DOT L'.' #define EOS L'\0' #define LBRACKET L'[' #define NOT L'!' #define QUESTION L'?' #define QUOTE L'\\' #define RANGE L'-' #define RBRACKET L']' #define SEP L'/' #define STAR L'*' #define TILDE L'~' #define LBRACE L'{' #define RBRACE L'}' #define COMMA L',' #define M_QUOTE 0x8000000000ULL #define M_PROTECT 0x4000000000ULL #define M_MASK 0xffffffffffULL #define M_CHAR 0x00ffffffffULL typedef uint_fast64_t Char; #define CHAR(c) ((Char)((c)&M_CHAR)) #define META(c) ((Char)((c)|M_QUOTE)) #define UNPROT(c) ((c) & ~M_PROTECT) #define M_ALL META(L'*') #define M_END META(L']') #define M_NOT META(L'!') #define M_ONE META(L'?') #define M_RNG META(L'-') #define M_SET META(L'[') #define ismeta(c) (((c)&M_QUOTE) != 0) #ifdef DEBUG #define isprot(c) (((c)&M_PROTECT) != 0) #endif static int compare(const void *, const void *); static int g_Ctoc(const Char *, char *, size_t); static int g_lstat(Char *, struct stat *, glob_t *); static DIR *g_opendir(Char *, glob_t *); static const Char *g_strchr(const Char *, wchar_t); #ifdef notdef static Char *g_strcat(Char *, const Char *); #endif static int g_stat(Char *, struct stat *, glob_t *); static int glob0(const Char *, glob_t *, struct glob_limit *, const char *); static int glob1(Char *, glob_t *, struct glob_limit *); static int glob2(Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *); static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *); static int globextend(const Char *, glob_t *, struct glob_limit *, const char *); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); static int globexp0(const Char *, glob_t *, struct glob_limit *, const char *); static int globexp1(const Char *, glob_t *, struct glob_limit *); static int globexp2(const Char *, const Char *, glob_t *, struct glob_limit *); static int globfinal(glob_t *, struct glob_limit *, size_t, const char *); static int match(Char *, Char *, Char *); static int err_nomatch(glob_t *, struct glob_limit *, const char *); static int err_aborted(glob_t *, int, char *); #ifdef DEBUG static void qprintf(const char *, Char *); #endif int glob(const char * __restrict pattern, int flags, int (*errfunc)(const char *, int), glob_t * __restrict pglob) { struct glob_limit limit = { 0, 0, 0, 0, 0 }; const char *patnext; Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; mbstate_t mbs; wchar_t wc; size_t clen; int too_long; patnext = pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } if (flags & GLOB_LIMIT) { limit.l_path_lim = pglob->gl_matchc; if (limit.l_path_lim == 0) limit.l_path_lim = GLOB_LIMIT_PATH; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; too_long = 1; if (flags & GLOB_NOESCAPE) { memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc; patnext += clen; } } else { /* Protect the quoted characters. */ memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { if (*patnext == '\\') { if (*++patnext == '\0') { *bufnext++ = QUOTE; continue; } prot = M_PROTECT; } else prot = 0; clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc | prot; patnext += clen; } } if (too_long) return (err_nomatch(pglob, &limit, pattern)); *bufnext = EOS; if (flags & GLOB_BRACE) return (globexp0(patbuf, pglob, &limit, pattern)); else return (glob0(patbuf, pglob, &limit, pattern)); } static int globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, const char *origpat) { int rv; size_t oldpathc; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (glob0(pattern, pglob, limit, origpat)); } oldpathc = pglob->gl_pathc; if ((rv = globexp1(pattern, pglob, limit)) != 0) return rv; return (globfinal(pglob, limit, oldpathc, origpat)); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit) { const Char* ptr; if ((ptr = g_strchr(pattern, LBRACE)) != NULL) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (globexp2(ptr, pattern, pglob, limit)); } return (glob0(pattern, pglob, limit, NULL)); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, struct glob_limit *limit) { int i, rv; Char *lm, *ls; const Char *pe, *pm, *pm1, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) continue; *lm = EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe != EOS; pe++) if (*pe == LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) continue; if (*pe == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pe = pm; } } else if (*pe == LBRACE) i++; else if (*pe == RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) return (glob0(pattern, pglob, limit, NULL)); for (i = 0, pl = pm = ptr; pm <= pe; pm++) switch (*pm) { case LBRACKET: /* Ignore everything between [] */ for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) continue; if (*pm == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pm = pm1; } break; case LBRACE: i++; break; case RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case COMMA: if (i && *pm == COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) continue; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != EOS;) continue; /* Expand the current pattern */ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif rv = globexp1(patbuf, pglob, limit); if (rv) return (rv); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } return (0); } /* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h, *sc; const Char *p; Char *b, *eb; wchar_t wc; wchar_t wbuf[MAXPATHLEN]; wchar_t *wbufend, *dc; size_t clen; mbstate_t mbs; int too_long; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return (pattern); /* * Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, b = patbuf; b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++) continue; if (*p != EOS && UNPROT(*p) != SEP) return (NULL); *b = EOS; h = NULL; if (patbuf[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME first (iff * we're not running setuid or setgid) and then trying * the password file */ if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { if (((h = getlogin()) != NULL && (pwd = getpwnam(h)) != NULL) || (pwd = getpwuid(getuid())) != NULL) h = pwd->pw_dir; else return (pattern); } } else { /* * Expand a ~user */ if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf))) return (NULL); if ((pwd = getpwnam((char *)wbuf)) == NULL) return (pattern); else h = pwd->pw_dir; } /* Copy the home directory */ dc = wbuf; sc = h; wbufend = wbuf + MAXPATHLEN - 1; too_long = 1; memset(&mbs, 0, sizeof(mbs)); while (dc <= wbufend) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long) return (NULL); dc = wbuf; for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT) continue; if (*dc != EOS) return (NULL); /* Append the rest of the pattern */ if (*p != EOS) { too_long = 1; while (b <= eb) { if ((*b++ = *p++) == EOS) { too_long = 0; break; } } if (too_long) return (NULL); } else *b = EOS; return (patbuf); } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. */ static int glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, const char *origpat) { const Char *qpatnext; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); if (qpatnext == NULL) { errno = E2BIG; return (GLOB_NOSPACE); } oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to ensure "**" at the end continues to match the * empty string */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, pglob, limit)) != 0) return(err); if (origpat != NULL) return (globfinal(pglob, limit, oldpathc, origpat)); return (0); } static int globfinal(glob_t *pglob, struct glob_limit *limit, size_t oldpathc, const char *origpat) { if (pglob->gl_pathc == oldpathc) return (err_nomatch(pglob, limit, origpat)); if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return (0); } static int compare(const void *p, const void *q) { return (strcoll(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return (0); return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, pattern, pglob, limit)); } /* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, glob_t *pglob, struct glob_limit *limit) { struct stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return (0); if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) { errno = E2BIG; return (GLOB_NOSPACE); } if ((pglob->gl_flags & GLOB_MARK) && UNPROT(pathend[-1]) != SEP && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && g_stat(pathbuf, &sb, pglob) == 0 && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return (globextend(pathbuf, pglob, limit, NULL)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && UNPROT(*p) != SEP) { if (ismeta(*p)) anymeta = 1; if (q + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (UNPROT(*pattern) == SEP) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return (glob3(pathbuf, pathend, pathend_last, pattern, p, pglob, limit)); } /* NOTREACHED */ } static int glob3(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, glob_t *pglob, struct glob_limit *limit) { struct dirent *dp; DIR *dirp; int err, too_long, saverrno, saverrno2; char buf[MAXPATHLEN + MB_LEN_MAX - 1]; struct dirent *(*readdirfunc)(DIR *); if (pathend > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend = EOS; if (pglob->gl_errfunc != NULL && g_Ctoc(pathbuf, buf, sizeof(buf))) { errno = E2BIG; return (GLOB_NOSPACE); } saverrno = errno; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { if (errno == ENOENT || errno == ENOTDIR) return (0); err = err_aborted(pglob, errno, buf); if (errno == 0) errno = saverrno; return (err); } err = 0; /* pglob->gl_readdir takes a void *, fix this manually */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir; else readdirfunc = readdir; errno = 0; /* Search directory for matching names. */ while ((dp = (*readdirfunc)(dirp)) != NULL) { char *sc; Char *dc; wchar_t wc; size_t clen; mbstate_t mbs; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) { errno = E2BIG; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) { errno = 0; continue; } memset(&mbs, 0, sizeof(mbs)); dc = pathend; sc = dp->d_name; too_long = 1; while (dc <= pathend_last) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long && (err = err_aborted(pglob, ENAMETOOLONG, buf))) { errno = ENAMETOOLONG; break; } if (too_long || !match(pathend, pattern, restpattern)) { *pathend = EOS; errno = 0; continue; } if (errno == 0) errno = saverrno; err = glob2(pathbuf, --dc, pathend_last, restpattern, pglob, limit); if (err) break; errno = 0; } saverrno2 = errno; if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); errno = saverrno2; if (err) return (err); if (dp == NULL && errno != 0 && (err = err_aborted(pglob, errno, buf))) return (err); if (errno == 0) errno = saverrno; return (0); } /* * Extend the gl_pathv member of a glob_t structure to accommodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, const char *origpat) { char **pathv; size_t i, newn, len; char *copy; const Char *p; if ((pglob->gl_flags & GLOB_LIMIT) && pglob->gl_matchc > limit->l_path_lim) { errno = E2BIG; return (GLOB_NOSPACE); } newn = 2 + pglob->gl_pathc + pglob->gl_offs; /* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */ pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv)); if (pathv == NULL) return (GLOB_NOSPACE); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; for (i = pglob->gl_offs + 1; --i > 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; if (origpat != NULL) copy = strdup(origpat); else { for (p = path; *p++ != EOS;) continue; len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ if ((copy = malloc(len)) != NULL) { if (g_Ctoc(path, copy, len)) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } } } if (copy != NULL) { limit->l_string_cnt += strlen(copy) + 1; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_string_cnt >= GLOB_LIMIT_STRING) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; return (copy == NULL ? GLOB_NOSPACE : 0); } /* * pattern matching function for filenames. */ static int match(Char *name, Char *pat, Char *patend) { int ok, negate_range; Char c, k, *nextp, *nextn; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; nextn = NULL; nextp = NULL; while (1) { while (pat < patend) { c = *pat++; switch (c & M_MASK) { case M_ALL: if (pat == patend) return (1); if (*name == EOS) return (0); nextn = name + 1; nextp = pat - 1; break; case M_ONE: if (*name++ == EOS) goto fail; break; case M_SET: ok = 0; if ((k = *name++) == EOS) goto fail; negate_range = ((*pat & M_MASK) == M_NOT); if (negate_range != 0) ++pat; while (((c = *pat++) & M_MASK) != M_END) if ((*pat & M_MASK) == M_RNG) { if (table->__collate_load_error ? CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : __wcollate_range_cmp(CHAR(c), CHAR(k)) <= 0 && __wcollate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0) ok = 1; pat += 2; } else if (c == k) ok = 1; if (ok == negate_range) goto fail; break; default: if (*name++ != c) goto fail; break; } } if (*name == EOS) return (1); fail: if (nextn == NULL) break; pat = nextp; name = nextn; } return (0); } /* Free allocated data belonging to a glob_t structure. */ void globfree(glob_t *pglob) { size_t i; char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) free(*pp); free(pglob->gl_pathv); pglob->gl_pathv = NULL; } } static DIR * g_opendir(Char *str, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (*str == EOS) strcpy(buf, "."); else { if (g_Ctoc(str, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (NULL); } } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_opendir)(buf)); return (opendir(buf)); } static int g_lstat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return (lstat(buf, sb)); } static int g_stat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_stat)(buf, sb)); return (stat(buf, sb)); } static const Char * g_strchr(const Char *str, wchar_t ch) { do { if (*str == ch) return (str); } while (*str++); return (NULL); } static int g_Ctoc(const Char *str, char *buf, size_t len) { mbstate_t mbs; size_t clen; memset(&mbs, 0, sizeof(mbs)); while (len >= MB_CUR_MAX) { clen = wcrtomb(buf, CHAR(*str), &mbs); if (clen == (size_t)-1) { /* XXX See initial comment #2. */ *buf = (char)CHAR(*str); clen = 1; memset(&mbs, 0, sizeof(mbs)); } if (CHAR(*str) == EOS) return (0); str++; buf += clen; len -= clen; } return (1); } static int err_nomatch(glob_t *pglob, struct glob_limit *limit, const char *origpat) { /* * If there was no match we are going to append the origpat * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the origpat did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return (globextend(NULL, pglob, limit, origpat)); return (GLOB_NOMATCH); } static int err_aborted(glob_t *pglob, int err, char *buf) { if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABORTED); return (0); } #ifdef DEBUG static void qprintf(const char *str, Char *s) { Char *p; (void)printf("%s\n", str); if (s != NULL) { for (p = s; *p != EOS; p++) (void)printf("%c", (char)CHAR(*p)); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (isprot(*p) ? '\\' : ' ')); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (ismeta(*p) ? '_' : ' ')); (void)printf("\n"); } } #endif diff --git a/lib/libc/gen/memalign.c b/lib/libc/gen/memalign.c index 60daeaf3a884..af64c998dbd4 100644 --- a/lib/libc/gen/memalign.c +++ b/lib/libc/gen/memalign.c @@ -1,45 +1,44 @@ /*- * Copyright (c) 2020 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include #include void * memalign(size_t align, size_t size) { /* * glibc allows align == 0, but that is not valid for roundup. * Just pass through to malloc in that case. */ if (align != 0) return (aligned_alloc(align, roundup(size, align))); else return (malloc(size)); } diff --git a/lib/libc/locale/ascii.c b/lib/libc/locale/ascii.c index 2bf62386dc14..55761626d67b 100644 --- a/lib/libc/locale/ascii.c +++ b/lib/libc/locale/ascii.c @@ -1,194 +1,194 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include #include #include #include #include "mblocal.h" static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _ascii_mbsinit(const mbstate_t *); static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused); static size_t _ascii_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); int _ascii_init(struct xlocale_ctype *l,_RuneLocale *rl) { l->__mbrtowc = _ascii_mbrtowc; l->__mbsinit = _ascii_mbsinit; l->__mbsnrtowcs = _ascii_mbsnrtowcs; l->__wcrtomb = _ascii_wcrtomb; l->__wcsnrtombs = _ascii_wcsnrtombs; l->runes = rl; l->__mb_cur_max = 1; l->__mb_sb_limit = 128; return(0); } static int _ascii_mbsinit(const mbstate_t *ps __unused) { /* * Encoding is not state dependent - we are always in the * initial state. */ return (1); } static size_t _ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused) { if (s == NULL) /* Reset to initial shift state (no-op) */ return (0); if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (*s & 0x80) { errno = EILSEQ; return ((size_t)-1); } if (pwc != NULL) *pwc = (unsigned char)*s; return (*s == '\0' ? 0 : 1); } static size_t _ascii_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused) { if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if (wc < 0 || wc > 127) { errno = EILSEQ; return ((size_t)-1); } *s = (unsigned char)wc; return (1); } static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused) { const char *s; size_t nchr; if (dst == NULL) { for (s = *src; nms > 0 && *s != '\0'; s++, nms--) { if (*s & 0x80) { errno = EILSEQ; return ((size_t)-1); } } return (s - *src); } s = *src; nchr = 0; while (len-- > 0 && nms-- > 0) { if (*s & 0x80) { *src = s; errno = EILSEQ; return ((size_t)-1); } if ((*dst++ = (unsigned char)*s++) == L'\0') { *src = NULL; return (nchr); } nchr++; } *src = s; return (nchr); } static size_t _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps __unused) { const wchar_t *s; size_t nchr; if (dst == NULL) { for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { if (*s < 0 || *s > 127) { errno = EILSEQ; return ((size_t)-1); } } return (s - *src); } s = *src; nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > 127) { *src = s; errno = EILSEQ; return ((size_t)-1); } if ((*dst++ = *s++) == '\0') { *src = NULL; return (nchr); } nchr++; } *src = s; return (nchr); } diff --git a/lib/libc/locale/big5.c b/lib/libc/locale/big5.c index de0c10ce3f28..77c19e9d7c0e 100644 --- a/lib/libc/locale/big5.c +++ b/lib/libc/locale/big5.c @@ -1,198 +1,198 @@ /*- * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include "mblocal.h" extern int __mb_sb_limit; static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _BIG5_mbsinit(const mbstate_t *); static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _BIG5_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _BIG5_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { wchar_t ch; } _BIG5State; int _BIG5_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _BIG5_mbrtowc; l->__wcrtomb = _BIG5_wcrtomb; l->__mbsnrtowcs = _BIG5_mbsnrtowcs; l->__wcsnrtombs = _BIG5_wcsnrtombs; l->__mbsinit = _BIG5_mbsinit; l->runes = rl; l->__mb_cur_max = 2; l->__mb_sb_limit = 128; return (0); } static int _BIG5_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _BIG5State *)ps)->ch == 0); } static __inline int _big5_check(u_int c) { c &= 0xff; return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1); } static size_t _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _BIG5State *bs; wchar_t wc; size_t len; bs = (_BIG5State *)ps; if ((bs->ch & ~0xFF) != 0) { /* Bad conversion state. */ errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (bs->ch != 0) { if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (bs->ch << 8) | (*s & 0xFF); if (pwc != NULL) *pwc = wc; bs->ch = 0; return (1); } len = (size_t)_big5_check(*s); wc = *s++ & 0xff; if (len == 2) { if (n < 2) { /* Incomplete multibyte sequence */ bs->ch = wc; return ((size_t)-2); } if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (wc << 8) | (*s++ & 0xff); if (pwc != NULL) *pwc = wc; return (2); } else { if (pwc != NULL) *pwc = wc; return (wc == L'\0' ? 0 : 1); } } static size_t _BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _BIG5State *bs; bs = (_BIG5State *)ps; if (bs->ch != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if (wc & 0x8000) { *s++ = (wc >> 8) & 0xff; *s = wc & 0xff; return (2); } *s = wc & 0xff; return (1); } static size_t _BIG5_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _BIG5_mbrtowc)); } static size_t _BIG5_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _BIG5_wcrtomb)); } diff --git a/lib/libc/locale/btowc.c b/lib/libc/locale/btowc.c index cd9e11524369..e5e4951fedd8 100644 --- a/lib/libc/locale/btowc.c +++ b/lib/libc/locale/btowc.c @@ -1,64 +1,64 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002, 2003 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include "mblocal.h" wint_t btowc_l(int c, locale_t l) { static const mbstate_t initial; mbstate_t mbs = initial; char cc; wchar_t wc; FIX_LOCALE(l); if (c == EOF) return (WEOF); /* * We expect mbrtowc() to return 0 or 1, hence the check for n > 1 * which detects error return values as well as "impossible" byte * counts. */ cc = (char)c; if (XLOCALE_CTYPE(l)->__mbrtowc(&wc, &cc, 1, &mbs) > 1) return (WEOF); return (wc); } wint_t btowc(int c) { return btowc_l(c, __get_locale()); } diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c index be995a5b963f..60c14a7de552 100644 --- a/lib/libc/locale/collate.c +++ b/lib/libc/locale/collate.c @@ -1,735 +1,735 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2014 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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. * * Adapted to xlocale by John Marino */ #include #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "collate.h" #include "setlocale.h" #include "ldpart.h" #include "libc_private.h" struct xlocale_collate __xlocale_global_collate = { {{0}, "C"}, 1, 0, 0, 0 }; struct xlocale_collate __xlocale_C_collate = { {{0}, "C"}, 1, 0, 0, 0 }; struct xlocale_collate __xlocale_POSIX_collate = { {{0}, "POSIX"}, 1, 0, 0, 0 }; struct xlocale_collate __xlocale_CUTF8_collate = { {{0}, "C.UTF-8"}, 1, 0, 0, 0 }; static int __collate_load_tables_l(const char *encoding, struct xlocale_collate *table); static void destruct_collate(void *t) { struct xlocale_collate *table = t; if (table->map && (table->maplen > 0)) { (void) munmap(table->map, table->maplen); } free(t); } void * __collate_load(const char *encoding, __unused locale_t unused) { if (strcmp(encoding, "C") == 0) return (&__xlocale_C_collate); else if (strcmp(encoding, "POSIX") == 0) return (&__xlocale_POSIX_collate); else if (strcmp(encoding, "C.UTF-8") == 0) return (&__xlocale_CUTF8_collate); struct xlocale_collate *table = calloc(sizeof(struct xlocale_collate), 1); if (table == NULL) return (NULL); table->header.header.destructor = destruct_collate; /* * FIXME: Make sure that _LDP_CACHE is never returned. We * should be doing the caching outside of this section. */ if (__collate_load_tables_l(encoding, table) != _LDP_LOADED) { xlocale_release(table); return (NULL); } return (table); } /** * Load the collation tables for the specified encoding into the global table. */ int __collate_load_tables(const char *encoding) { return (__collate_load_tables_l(encoding, &__xlocale_global_collate)); } static int __collate_load_tables_l(const char *encoding, struct xlocale_collate *table) { int i, chains, z; char *buf; char *TMP; char *map; collate_info_t *info; struct stat sbuf; int fd; table->__collate_load_error = 1; /* 'encoding' must be already checked. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0 || strncmp(encoding, "C.", 2) == 0) { return (_LDP_CACHE); } if (asprintf(&buf, "%s/%s/LC_COLLATE", _PathLocale, encoding) == -1) return (_LDP_ERROR); if ((fd = _open(buf, O_RDONLY | O_CLOEXEC)) < 0) { free(buf); return (_LDP_ERROR); } free(buf); if (_fstat(fd, &sbuf) < 0) { (void) _close(fd); return (_LDP_ERROR); } if (sbuf.st_size < (COLLATE_FMT_VERSION_LEN + XLOCALE_DEF_VERSION_LEN + sizeof (*info))) { (void) _close(fd); errno = EINVAL; return (_LDP_ERROR); } map = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); (void) _close(fd); if ((TMP = map) == MAP_FAILED) { return (_LDP_ERROR); } if (strncmp(TMP, COLLATE_FMT_VERSION, COLLATE_FMT_VERSION_LEN) != 0) { (void) munmap(map, sbuf.st_size); errno = EINVAL; return (_LDP_ERROR); } TMP += COLLATE_FMT_VERSION_LEN; strlcat(table->header.version, TMP, sizeof (table->header.version)); TMP += XLOCALE_DEF_VERSION_LEN; info = (void *)TMP; TMP += sizeof (*info); if ((info->directive_count < 1) || (info->directive_count >= COLL_WEIGHTS_MAX) || ((chains = info->chain_count) < 0)) { (void) munmap(map, sbuf.st_size); errno = EINVAL; return (_LDP_ERROR); } i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) + (sizeof (collate_chain_t) * chains) + (sizeof (collate_large_t) * info->large_count); for (z = 0; z < info->directive_count; z++) { i += sizeof (collate_subst_t) * info->subst_count[z]; } if (i != (sbuf.st_size - (TMP - map))) { (void) munmap(map, sbuf.st_size); errno = EINVAL; return (_LDP_ERROR); } if (table->map && (table->maplen > 0)) { (void) munmap(table->map, table->maplen); } table->map = map; table->maplen = sbuf.st_size; table->info = info; table->char_pri_table = (void *)TMP; TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1); for (z = 0; z < info->directive_count; z++) { if (info->subst_count[z] > 0) { table->subst_table[z] = (void *)TMP; TMP += info->subst_count[z] * sizeof (collate_subst_t); } else { table->subst_table[z] = NULL; } } if (chains > 0) { table->chain_pri_table = (void *)TMP; TMP += chains * sizeof (collate_chain_t); } else table->chain_pri_table = NULL; if (info->large_count > 0) table->large_pri_table = (void *)TMP; else table->large_pri_table = NULL; table->__collate_load_error = 0; return (_LDP_LOADED); } static const int32_t * substsearch(struct xlocale_collate *table, const wchar_t key, int pass) { const collate_subst_t *p; int n = table->info->subst_count[pass]; if (n == 0) return (NULL); if (pass >= table->info->directive_count) return (NULL); if (!(key & COLLATE_SUBST_PRIORITY)) return (NULL); p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY); assert(p->key == key); return (p->pri); } static collate_chain_t * chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len) { int low = 0; int high = table->info->chain_count - 1; int next, compar, l; collate_chain_t *p; collate_chain_t *tab = table->chain_pri_table; if (high < 0) return (NULL); while (low <= high) { next = (low + high) / 2; p = tab + next; compar = *key - *p->str; if (compar == 0) { l = wcsnlen(p->str, COLLATE_STR_LEN); compar = wcsncmp(key, p->str, l); if (compar == 0) { *len = l; return (p); } } if (compar > 0) low = next + 1; else high = next - 1; } return (NULL); } static collate_large_t * largesearch(struct xlocale_collate *table, const wchar_t key) { int low = 0; int high = table->info->large_count - 1; int next, compar; collate_large_t *p; collate_large_t *tab = table->large_pri_table; if (high < 0) return (NULL); while (low <= high) { next = (low + high) / 2; p = tab + next; compar = key - p->val; if (compar == 0) return (p); if (compar > 0) low = next + 1; else high = next - 1; } return (NULL); } void _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len, int *pri, int which, const int **state) { collate_chain_t *p2; collate_large_t *match; int p, l; const int *sptr; /* * If this is the "last" pass for the UNDEFINED, then * we just return the priority itself. */ if (which >= table->info->directive_count) { *pri = *t; *len = 1; *state = NULL; return; } /* * If we have remaining substitution data from a previous * call, consume it first. */ if ((sptr = *state) != NULL) { *pri = *sptr; sptr++; if ((sptr == *state) || (sptr == NULL)) *state = NULL; else *state = sptr; *len = 0; return; } /* No active substitutions */ *len = 1; /* * Check for composites such as diphthongs that collate as a * single element (aka chains or collating-elements). */ if (((p2 = chainsearch(table, t, &l)) != NULL) && ((p = p2->pri[which]) >= 0)) { *len = l; *pri = p; } else if (*t <= UCHAR_MAX) { /* * Character is a small (8-bit) character. * We just look these up directly for speed. */ *pri = table->char_pri_table[*t].pri[which]; } else if ((table->info->large_count > 0) && ((match = largesearch(table, *t)) != NULL)) { /* * Character was found in the extended table. */ *pri = match->pri.pri[which]; } else { /* * Character lacks a specific definition. */ if (table->info->directive[which] & DIRECTIVE_UNDEFINED) { /* Mask off sign bit to prevent ordering confusion. */ *pri = (*t & COLLATE_MAX_PRIORITY); } else { *pri = table->info->undef_pri[which]; } /* No substitutions for undefined characters! */ return; } /* * Try substituting (expanding) the character. We are * currently doing this *after* the chain compression. I * think it should not matter, but this way might be slightly * faster. * * We do this after the priority search, as this will help us * to identify a single key value. In order for this to work, * its important that the priority assigned to a given element * to be substituted be unique for that level. The localedef * code ensures this for us. */ if ((sptr = substsearch(table, *pri, which)) != NULL) { if ((*pri = *sptr) > 0) { sptr++; *state = *sptr ? sptr : NULL; } } } /* * This is the meaty part of wcsxfrm & strxfrm. Note that it does * NOT NULL terminate. That is left to the caller. */ size_t _collate_wxfrm(struct xlocale_collate *table, const wchar_t *src, wchar_t *xf, size_t room) { int pri; int len; const wchar_t *t; wchar_t *tr = NULL; int direc; int pass; const int32_t *state; size_t want = 0; size_t need = 0; int ndir = table->info->directive_count; assert(src); for (pass = 0; pass <= ndir; pass++) { state = NULL; if (pass != 0) { /* insert level separator from the previous pass */ if (room) { *xf++ = 1; room--; } want++; } /* special pass for undefined */ if (pass == ndir) { direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED; } else { direc = table->info->directive[pass]; } t = src; if (direc & DIRECTIVE_BACKWARD) { wchar_t *bp, *fp, c; free(tr); if ((tr = wcsdup(t)) == NULL) { errno = ENOMEM; goto fail; } bp = tr; fp = tr + wcslen(tr) - 1; while (bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } t = (const wchar_t *)tr; } if (direc & DIRECTIVE_POSITION) { while (*t || state) { _collate_lookup(table, t, &len, &pri, pass, &state); t += len; if (pri <= 0) { if (pri < 0) { errno = EINVAL; goto fail; } state = NULL; pri = COLLATE_MAX_PRIORITY; } if (room) { *xf++ = pri; room--; } want++; need = want; } } else { while (*t || state) { _collate_lookup(table, t, &len, &pri, pass, &state); t += len; if (pri <= 0) { if (pri < 0) { errno = EINVAL; goto fail; } state = NULL; continue; } if (room) { *xf++ = pri; room--; } want++; need = want; } } } free(tr); return (need); fail: free(tr); return ((size_t)(-1)); } /* * In the non-POSIX case, we transform each character into a string of * characters representing the character's priority. Since char is usually * signed, we are limited by 7 bits per byte. To avoid zero, we need to add * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6 * bits per byte. * * It turns out that we sometimes have real priorities that are * 31-bits wide. (But: be careful using priorities where the high * order bit is set -- i.e. the priority is negative. The sort order * may be surprising!) * * TODO: This would be a good area to optimize somewhat. It turns out * that real prioririties *except for the last UNDEFINED pass* are generally * very small. We need the localedef code to precalculate the max * priority for us, and ideally also give us a mask, and then we could * severely limit what we expand to. */ #define XFRM_BYTES 6 #define XFRM_OFFSET ('0') /* make all printable characters */ #define XFRM_SHIFT 6 #define XFRM_MASK ((1 << XFRM_SHIFT) - 1) #define XFRM_SEP ('.') /* chosen to be less than XFRM_OFFSET */ static int xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass) { /* we use unsigned to ensure zero fill on right shift */ uint32_t val = (uint32_t)table->info->pri_count[pass]; int nc = 0; while (val) { *p = (pri & XFRM_MASK) + XFRM_OFFSET; pri >>= XFRM_SHIFT; val >>= XFRM_SHIFT; p++; nc++; } return (nc); } size_t _collate_sxfrm(struct xlocale_collate *table, const wchar_t *src, char *xf, size_t room) { int pri; int len; const wchar_t *t; wchar_t *tr = NULL; int direc; int pass; const int32_t *state; size_t want = 0; size_t need = 0; int b; uint8_t buf[XFRM_BYTES]; int ndir = table->info->directive_count; assert(src); for (pass = 0; pass <= ndir; pass++) { state = NULL; if (pass != 0) { /* insert level separator from the previous pass */ if (room) { *xf++ = XFRM_SEP; room--; } want++; } /* special pass for undefined */ if (pass == ndir) { direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED; } else { direc = table->info->directive[pass]; } t = src; if (direc & DIRECTIVE_BACKWARD) { wchar_t *bp, *fp, c; free(tr); if ((tr = wcsdup(t)) == NULL) { errno = ENOMEM; goto fail; } bp = tr; fp = tr + wcslen(tr) - 1; while (bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } t = (const wchar_t *)tr; } if (direc & DIRECTIVE_POSITION) { while (*t || state) { _collate_lookup(table, t, &len, &pri, pass, &state); t += len; if (pri <= 0) { if (pri < 0) { errno = EINVAL; goto fail; } state = NULL; pri = COLLATE_MAX_PRIORITY; } b = xfrm(table, buf, pri, pass); want += b; if (room) { while (b) { b--; if (room) { *xf++ = buf[b]; room--; } } } need = want; } } else { while (*t || state) { _collate_lookup(table, t, &len, &pri, pass, &state); t += len; if (pri <= 0) { if (pri < 0) { errno = EINVAL; goto fail; } state = NULL; continue; } b = xfrm(table, buf, pri, pass); want += b; if (room) { while (b) { b--; if (room) { *xf++ = buf[b]; room--; } } } need = want; } } } free(tr); return (need); fail: free(tr); return ((size_t)(-1)); } /* * __collate_equiv_value returns the primary collation value for the given * collating symbol specified by str and len. Zero or negative is returned * if the collating symbol was not found. This function is used by bracket * code in the TRE regex library. */ int __collate_equiv_value(locale_t locale, const wchar_t *str, size_t len) { int32_t e; if (len < 1 || len >= COLLATE_STR_LEN) return (-1); FIX_LOCALE(locale); struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; if (table->__collate_load_error) return ((len == 1 && *str <= UCHAR_MAX) ? *str : -1); if (len == 1) { e = -1; if (*str <= UCHAR_MAX) e = table->char_pri_table[*str].pri[0]; else if (table->info->large_count > 0) { collate_large_t *match_large; match_large = largesearch(table, *str); if (match_large) e = match_large->pri.pri[0]; } if (e == 0) return (1); return (e > 0 ? e : 0); } if (table->info->chain_count > 0) { wchar_t name[COLLATE_STR_LEN]; collate_chain_t *match_chain; int clen; wcsncpy (name, str, len); name[len] = 0; match_chain = chainsearch(table, name, &clen); if (match_chain) { e = match_chain->pri[0]; if (e == 0) return (1); return (e < 0 ? -e : e); } } return (0); } diff --git a/lib/libc/locale/collate.h b/lib/libc/locale/collate.h index 8a0b61db6ee1..2d3723b49f5b 100644 --- a/lib/libc/locale/collate.h +++ b/lib/libc/locale/collate.h @@ -1,142 +1,142 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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. */ #ifndef _COLLATE_H_ #define _COLLATE_H_ #include #include #include #include "xlocale_private.h" /* * Work around buildworld bootstrapping from older systems whose limits.h * sets COLL_WEIGHTS_MAX to 0. */ #if COLL_WEIGHTS_MAX == 0 #undef COLL_WEIGHTS_MAX #define COLL_WEIGHTS_MAX 10 #endif #define COLLATE_STR_LEN 24 /* should be 64-bit multiple */ #define COLLATE_FMT_VERSION_LEN 12 #define COLLATE_FMT_VERSION "BSD 1.0\n" #define COLLATE_MAX_PRIORITY (0x7fffffff) /* max signed value */ #define COLLATE_SUBST_PRIORITY (0x40000000) /* bit indicates subst table */ #define DIRECTIVE_UNDEF 0x00 #define DIRECTIVE_FORWARD 0x01 #define DIRECTIVE_BACKWARD 0x02 #define DIRECTIVE_POSITION 0x04 #define DIRECTIVE_UNDEFINED 0x08 /* special last weight for UNDEFINED */ #define DIRECTIVE_DIRECTION_MASK (DIRECTIVE_FORWARD | DIRECTIVE_BACKWARD) /* * The collate file format is as follows: * * char fmt_version[COLLATE_FMT_VERSION_LEN]; // must be COLLATE_FMT_VERSION * char def_version[XLOCALE_DEF_VERSION_LEN]; // NUL-terminated, may be empty * collate_info_t info; // see below, includes padding * collate_char_pri_t char_data[256]; // 8 bit char values * collate_subst_t subst[*]; // 0 or more substitutions * collate_chain_pri_t chains[*]; // 0 or more chains * collate_large_pri_t large[*]; // extended char priorities * * Note that all structures must be 32-bit aligned, as each structure * contains 32-bit member fields. The entire file is mmap'd, so its * critical that alignment be observed. It is not generally safe to * use any 64-bit values in the structures. */ typedef struct collate_info { uint8_t directive_count; uint8_t directive[COLL_WEIGHTS_MAX]; int32_t pri_count[COLL_WEIGHTS_MAX]; int32_t flags; int32_t chain_count; int32_t large_count; int32_t subst_count[COLL_WEIGHTS_MAX]; int32_t undef_pri[COLL_WEIGHTS_MAX]; } collate_info_t; typedef struct collate_char { int32_t pri[COLL_WEIGHTS_MAX]; } collate_char_t; typedef struct collate_chain { wchar_t str[COLLATE_STR_LEN]; int32_t pri[COLL_WEIGHTS_MAX]; } collate_chain_t; typedef struct collate_large { int32_t val; collate_char_t pri; } collate_large_t; typedef struct collate_subst { int32_t key; int32_t pri[COLLATE_STR_LEN]; } collate_subst_t; struct xlocale_collate { struct xlocale_component header; int __collate_load_error; char * map; size_t maplen; collate_info_t *info; collate_char_t *char_pri_table; collate_large_t *large_pri_table; collate_chain_t *chain_pri_table; collate_subst_t *subst_table[COLL_WEIGHTS_MAX]; }; __BEGIN_DECLS int __collate_load_tables(const char *); int __collate_equiv_value(locale_t, const wchar_t *, size_t); void _collate_lookup(struct xlocale_collate *,const wchar_t *, int *, int *, int, const int **); int __collate_range_cmp(char, char); int __wcollate_range_cmp(wchar_t, wchar_t); size_t _collate_wxfrm(struct xlocale_collate *, const wchar_t *, wchar_t *, size_t); size_t _collate_sxfrm(struct xlocale_collate *, const wchar_t *, char *, size_t); __END_DECLS #endif /* !_COLLATE_H_ */ diff --git a/lib/libc/locale/collcmp.c b/lib/libc/locale/collcmp.c index c3fe384aee4b..7b2d6723411b 100644 --- a/lib/libc/locale/collcmp.c +++ b/lib/libc/locale/collcmp.c @@ -1,63 +1,63 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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. */ #include #include #include #include "collate.h" /* * Compare two characters using collate */ int __collate_range_cmp(char c1, char c2) { char s1[2], s2[2]; s1[0] = c1; s1[1] = '\0'; s2[0] = c2; s2[1] = '\0'; return (strcoll(s1, s2)); } int __wcollate_range_cmp(wchar_t c1, wchar_t c2) { wchar_t s1[2], s2[2]; s1[0] = c1; s1[1] = L'\0'; s2[0] = c2; s2[1] = L'\0'; return (wcscoll(s1, s2)); } diff --git a/lib/libc/locale/ctype.c b/lib/libc/locale/ctype.c index 2d5866a751ee..a907ac4234fd 100644 --- a/lib/libc/locale/ctype.c +++ b/lib/libc/locale/ctype.c @@ -1,33 +1,32 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. * * This software was developed by David Chisnall under sponsorship from * the FreeBSD Foundation. * * 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. */ #define _XLOCALE_INLINE #include #include #include diff --git a/lib/libc/locale/ctype_l.3 b/lib/libc/locale/ctype_l.3 index 7c45e240e2d6..6879ba72706e 100644 --- a/lib/libc/locale/ctype_l.3 +++ b/lib/libc/locale/ctype_l.3 @@ -1,144 +1,143 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 December 19, 2022 .Dt CTYPE_L 3 .Os .Sh NAME .Nm digittoint_l , .Nm isalnum_l , .Nm isalpha_l , .Nm isblank_l , .Nm iscntrl_l , .Nm isdigit_l , .Nm isgraph_l , .Nm ishexnumber_l , .Nm isideogram_l , .Nm islower_l , .Nm isnumber_l , .Nm isphonogram_l , .Nm isprint_l , .Nm ispunct_l , .Nm isrune_l , .Nm isspace_l , .Nm isspecial_l , .Nm isupper_l , .Nm isxdigit_l , .Nm tolower_l , .Nm toupper_l .Nd character classification functions .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In ctype.h .Ft int .Fn digittoint_l "int c" "locale_t loc" .Ft int .Fn isalnum_l "int c" "locale_t loc" .Ft int .Fn isalpha_l "int c" "locale_t loc" .Ft int .Fn iscntrl_l "int c" "locale_t loc" .Ft int .Fn isdigit_l "int c" "locale_t loc" .Ft int .Fn isgraph_l "int c" "locale_t loc" .Ft int .Fn ishexnumber_l "int c" "locale_t loc" .Ft int .Fn isideogram_l "int c" "locale_t loc" .Ft int .Fn islower_l "int c" "locale_t loc" .Ft int .Fn isnumber_l "int c" "locale_t loc" .Ft int .Fn isphonogram_l "int c" "locale_t loc" .Ft int .Fn isspecial_l "int c" "locale_t loc" .Ft int .Fn isprint_l "int c" "locale_t loc" .Ft int .Fn ispunct_l "int c" "locale_t loc" .Ft int .Fn isrune_l "int c" "locale_t loc" .Ft int .Fn isspace_l "int c" "locale_t loc" .Ft int .Fn isupper_l "int c" "locale_t loc" .Ft int .Fn isxdigit_l "int c" "locale_t loc" .Ft int .Fn tolower_l "int c" "locale_t loc" .Ft int .Fn toupper_l "int c" "locale_t loc" .Sh DESCRIPTION The above functions perform character tests and conversions on the integer .Fa c in the locale .Fa loc . They behave in the same way as the versions without the _l suffix, but use the specified locale rather than the global or per-thread locale. .In ctype.h , or as true functions in the C library. See the specific manual pages for more information. .Sh SEE ALSO .Xr digittoint_l 3 , .Xr isalnum_l 3 , .Xr isalpha_l 3 , .Xr isblank_l 3 , .Xr iscntrl_l 3 , .Xr isdigit_l 3 , .Xr isgraph_l 3 , .Xr isideogram_l 3 , .Xr islower_l 3 , .Xr isphonogram_l 3 , .Xr isprint_l 3 , .Xr ispunct_l 3 , .Xr isrune_l 3 , .Xr isspace_l 3 , .Xr isspecial_l 3 , .Xr isupper_l 3 , .Xr isxdigit_l 3 , .Xr tolower_l 3 , .Xr toupper_l 3 , .Xr wctype_l 3 , .Xr xlocale_l 3 .Sh STANDARDS These functions conform to .St -p1003.1-2008 , except for .Fn digittoint_l , .Fn ishexnumber_l , .Fn isideogram_l , .Fn isnumber_l , .Fn isphonogram_l , .Fn isrune_l and .Fn isspecial_l which are .Fx extensions. diff --git a/lib/libc/locale/duplocale.3 b/lib/libc/locale/duplocale.3 index 4c3d94f54534..2e44df8c63a5 100644 --- a/lib/libc/locale/duplocale.3 +++ b/lib/libc/locale/duplocale.3 @@ -1,77 +1,76 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 September 17, 2011 .Dt DUPLOCALE 3 .Os .Sh NAME .Nm duplocale .Nd duplicate an locale .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In locale.h .Ft locale_t .Fn duplocale "locale_t locale" .Sh DESCRIPTION Duplicates an existing .Fa locale_t returning a new .Fa locale_t that refers to the same locale values but has an independent internal state. Various functions, such as .Xr mblen 3 require a persistent state. These functions formerly used static variables and calls to them from multiple threads had undefined behavior. They now use fields in the .Fa locale_t associated with the current thread by .Xr uselocale 3 . These calls are therefore only thread safe on threads with a unique per-thread locale. The locale returned by this call must be freed with .Xr freelocale 3 . .Sh SEE ALSO .Xr freelocale 3 , .Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , .Xr uselocale 3 , .Xr xlocale 3 .Sh STANDARDS This function conforms to .St -p1003.1-2008 . .Sh BUGS Ideally, .Xr uselocale 3 should make a copy of the .Fa locale_t implicitly to ensure thread safety, and a copy of the global locale should be installed lazily on each thread. The FreeBSD implementation does not do this, for compatibility with Darwin. diff --git a/lib/libc/locale/euc.c b/lib/libc/locale/euc.c index 0ce49e070d1f..823928ff745b 100644 --- a/lib/libc/locale/euc.c +++ b/lib/libc/locale/euc.c @@ -1,455 +1,455 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include "mblocal.h" extern int __mb_sb_limit; static size_t _EUC_mbrtowc_impl(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, uint8_t, uint8_t, uint8_t, uint8_t); static size_t _EUC_wcrtomb_impl(char * __restrict, wchar_t, mbstate_t * __restrict, uint8_t, uint8_t, uint8_t, uint8_t); static size_t _EUC_CN_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static size_t _EUC_JP_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static size_t _EUC_KR_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static size_t _EUC_TW_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static size_t _EUC_CN_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _EUC_JP_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _EUC_KR_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _EUC_TW_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _EUC_CN_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_JP_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_KR_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_TW_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_CN_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_JP_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_KR_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _EUC_TW_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); static int _EUC_mbsinit(const mbstate_t *); typedef struct { wchar_t ch; int set; int want; } _EucState; static int _EUC_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _EucState *)ps)->want == 0); } /* * EUC-CN uses CS0, CS1 and CS2 (4 bytes). */ int _EUC_CN_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _EUC_CN_mbrtowc; l->__wcrtomb = _EUC_CN_wcrtomb; l->__mbsnrtowcs = _EUC_CN_mbsnrtowcs; l->__wcsnrtombs = _EUC_CN_wcsnrtombs; l->__mbsinit = _EUC_mbsinit; l->runes = rl; l->__mb_cur_max = 4; l->__mb_sb_limit = 128; return (0); } static size_t _EUC_CN_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0)); } static size_t _EUC_CN_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_CN_mbrtowc)); } static size_t _EUC_CN_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0)); } static size_t _EUC_CN_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_CN_wcrtomb)); } /* * EUC-KR uses only CS0 and CS1. */ int _EUC_KR_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _EUC_KR_mbrtowc; l->__wcrtomb = _EUC_KR_wcrtomb; l->__mbsnrtowcs = _EUC_KR_mbsnrtowcs; l->__wcsnrtombs = _EUC_KR_wcsnrtombs; l->__mbsinit = _EUC_mbsinit; l->runes = rl; l->__mb_cur_max = 2; l->__mb_sb_limit = 128; return (0); } static size_t _EUC_KR_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return (_EUC_mbrtowc_impl(pwc, s, n, ps, 0, 0, 0, 0)); } static size_t _EUC_KR_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_KR_mbrtowc)); } static size_t _EUC_KR_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { return (_EUC_wcrtomb_impl(s, wc, ps, 0, 0, 0, 0)); } static size_t _EUC_KR_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_KR_wcrtomb)); } /* * EUC-JP uses CS0, CS1, CS2, and CS3. */ int _EUC_JP_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _EUC_JP_mbrtowc; l->__wcrtomb = _EUC_JP_wcrtomb; l->__mbsnrtowcs = _EUC_JP_mbsnrtowcs; l->__wcsnrtombs = _EUC_JP_wcsnrtombs; l->__mbsinit = _EUC_mbsinit; l->runes = rl; l->__mb_cur_max = 3; l->__mb_sb_limit = 128; return (0); } static size_t _EUC_JP_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 2, SS3, 3)); } static size_t _EUC_JP_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_JP_mbrtowc)); } static size_t _EUC_JP_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 2, SS3, 3)); } static size_t _EUC_JP_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_JP_wcrtomb)); } /* * EUC-TW uses CS0, CS1, and CS2. */ int _EUC_TW_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _EUC_TW_mbrtowc; l->__wcrtomb = _EUC_TW_wcrtomb; l->__mbsnrtowcs = _EUC_TW_mbsnrtowcs; l->__wcsnrtombs = _EUC_TW_wcsnrtombs; l->__mbsinit = _EUC_mbsinit; l->runes = rl; l->__mb_cur_max = 4; l->__mb_sb_limit = 128; return (0); } static size_t _EUC_TW_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return (_EUC_mbrtowc_impl(pwc, s, n, ps, SS2, 4, 0, 0)); } static size_t _EUC_TW_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _EUC_TW_mbrtowc)); } static size_t _EUC_TW_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { return (_EUC_wcrtomb_impl(s, wc, ps, SS2, 4, 0, 0)); } static size_t _EUC_TW_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _EUC_TW_wcrtomb)); } /* * Common EUC code. */ static size_t _EUC_mbrtowc_impl(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps, uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width) { _EucState *es; int i, want; wchar_t wc = 0; unsigned char ch, chs; es = (_EucState *)ps; if (es->want < 0 || es->want > MB_CUR_MAX) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (es->want == 0) { /* Fast path for plain ASCII (CS0) */ if (((ch = (unsigned char)*s) & 0x80) == 0) { if (pwc != NULL) *pwc = ch; return (ch != '\0' ? 1 : 0); } if (ch >= 0xa1) { /* CS1 */ want = 2; } else if (ch == cs2) { want = cs2width; } else if (ch == cs3) { want = cs3width; } else { errno = EILSEQ; return ((size_t)-1); } es->want = want; es->ch = 0; } else { want = es->want; wc = es->ch; } for (i = 0; i < MIN(want, n); i++) { wc <<= 8; chs = *s; wc |= chs; s++; } if (i < want) { /* Incomplete multibyte sequence */ es->want = want - i; es->ch = wc; errno = EILSEQ; return ((size_t)-2); } if (pwc != NULL) *pwc = wc; es->want = 0; return (wc == L'\0' ? 0 : want); } static size_t _EUC_wcrtomb_impl(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width) { _EucState *es; int i, len; wchar_t nm; es = (_EucState *)ps; if (es->want != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if ((wc & ~0x7f) == 0) { /* Fast path for plain ASCII (CS0) */ *s = (char)wc; return (1); } /* Determine the "length" */ if ((unsigned)wc > 0xffffff) { len = 4; } else if ((unsigned)wc > 0xffff) { len = 3; } else if ((unsigned)wc > 0xff) { len = 2; } else { len = 1; } if (len > MB_CUR_MAX) { errno = EILSEQ; return ((size_t)-1); } /* This first check excludes CS1, which is implicitly valid. */ if ((wc < 0xa100) || (wc > 0xffff)) { /* Check for valid CS2 or CS3 */ nm = (wc >> ((len - 1) * 8)); if (nm == cs2) { if (len != cs2width) { errno = EILSEQ; return ((size_t)-1); } } else if (nm == cs3) { if (len != cs3width) { errno = EILSEQ; return ((size_t)-1); } } else { errno = EILSEQ; return ((size_t)-1); } } /* Stash the bytes, least significant last */ for (i = len - 1; i >= 0; i--) { s[i] = (wc & 0xff); wc >>= 8; } return (len); } diff --git a/lib/libc/locale/freelocale.3 b/lib/libc/locale/freelocale.3 index c37b21477c8f..594720f4dfab 100644 --- a/lib/libc/locale/freelocale.3 +++ b/lib/libc/locale/freelocale.3 @@ -1,57 +1,56 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 July 26, 2016 .Dt FREELOCALE 3 .Os .Sh NAME .Nm freelocale .Nd Frees a locale created with .Xr duplocale 3 or .Xr newlocale 3 .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In locale.h .Ft void .Fn freelocale "locale_t locale" .Sh DESCRIPTION Frees a .Fa locale_t . This relinquishes any resources held exclusively by this locale. Note that locales share reference-counted components, so a call to this function is not guaranteed to free all of the components. .Sh SEE ALSO .Xr duplocale 3 , .Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , .Xr uselocale 3 , .Xr xlocale 3 .Sh STANDARDS This function conforms to .St -p1003.1-2008 . diff --git a/lib/libc/locale/gb18030.c b/lib/libc/locale/gb18030.c index f2f2847578eb..1ddb3e463872 100644 --- a/lib/libc/locale/gb18030.c +++ b/lib/libc/locale/gb18030.c @@ -1,252 +1,252 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ /* * PRC National Standard GB 18030-2000 encoding of Chinese text. * * See gb18030(5) for details. */ #include #include #include #include #include #include #include "mblocal.h" static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _GB18030_mbsinit(const mbstate_t *); static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _GB18030_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _GB18030_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { int count; u_char bytes[4]; } _GB18030State; int _GB18030_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _GB18030_mbrtowc; l->__wcrtomb = _GB18030_wcrtomb; l->__mbsinit = _GB18030_mbsinit; l->__mbsnrtowcs = _GB18030_mbsnrtowcs; l->__wcsnrtombs = _GB18030_wcsnrtombs; l->runes = rl; l->__mb_cur_max = 4; l->__mb_sb_limit = 128; return (0); } static int _GB18030_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _GB18030State *)ps)->count == 0); } static size_t _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _GB18030State *gs; wchar_t wch; int ch, len, ocount; size_t ncopy; gs = (_GB18030State *)ps; if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(gs->bytes) - gs->count); memcpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; s = (char *)gs->bytes; n = gs->count; if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); /* * Single byte: [00-7f] * Two byte: [81-fe][40-7e,80-fe] * Four byte: [81-fe][30-39][81-fe][30-39] */ ch = (unsigned char)*s++; if (ch <= 0x7f) { len = 1; wch = ch; } else if (ch >= 0x81 && ch <= 0xfe) { wch = ch; if (n < 2) return ((size_t)-2); ch = (unsigned char)*s++; if ((ch >= 0x40 && ch <= 0x7e) || (ch >= 0x80 && ch <= 0xfe)) { wch = (wch << 8) | ch; len = 2; } else if (ch >= 0x30 && ch <= 0x39) { /* * Strip high bit off the wide character we will * eventually output so that it is positive when * cast to wint_t on 32-bit twos-complement machines. */ wch = ((wch & 0x7f) << 8) | ch; if (n < 3) return ((size_t)-2); ch = (unsigned char)*s++; if (ch < 0x81 || ch > 0xfe) goto ilseq; wch = (wch << 8) | ch; if (n < 4) return ((size_t)-2); ch = (unsigned char)*s++; if (ch < 0x30 || ch > 0x39) goto ilseq; wch = (wch << 8) | ch; len = 4; } else goto ilseq; } else goto ilseq; if (pwc != NULL) *pwc = wch; gs->count = 0; return (wch == L'\0' ? 0 : len - ocount); ilseq: errno = EILSEQ; return ((size_t)-1); } static size_t _GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GB18030State *gs; size_t len; int c; gs = (_GB18030State *)ps; if (gs->count != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if ((wc & ~0x7fffffff) != 0) goto ilseq; if (wc & 0x7f000000) { /* Replace high bit that mbrtowc() removed. */ wc |= 0x80000000; c = (wc >> 24) & 0xff; if (c < 0x81 || c > 0xfe) goto ilseq; *s++ = c; c = (wc >> 16) & 0xff; if (c < 0x30 || c > 0x39) goto ilseq; *s++ = c; c = (wc >> 8) & 0xff; if (c < 0x81 || c > 0xfe) goto ilseq; *s++ = c; c = wc & 0xff; if (c < 0x30 || c > 0x39) goto ilseq; *s++ = c; len = 4; } else if (wc & 0x00ff0000) goto ilseq; else if (wc & 0x0000ff00) { c = (wc >> 8) & 0xff; if (c < 0x81 || c > 0xfe) goto ilseq; *s++ = c; c = wc & 0xff; if (c < 0x40 || c == 0x7f || c == 0xff) goto ilseq; *s++ = c; len = 2; } else if (wc <= 0x7f) { *s++ = wc; len = 1; } else goto ilseq; return (len); ilseq: errno = EILSEQ; return ((size_t)-1); } static size_t _GB18030_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GB18030_mbrtowc)); } static size_t _GB18030_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GB18030_wcrtomb)); } diff --git a/lib/libc/locale/gb2312.c b/lib/libc/locale/gb2312.c index a3472117a4aa..dbcb56435ab6 100644 --- a/lib/libc/locale/gb2312.c +++ b/lib/libc/locale/gb2312.c @@ -1,187 +1,187 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2004 Tim J. Robbins. All rights reserved. * Copyright (c) 2003 David Xu * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include "mblocal.h" static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _GB2312_mbsinit(const mbstate_t *); static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _GB2312_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _GB2312_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { int count; u_char bytes[2]; } _GB2312State; int _GB2312_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->runes = rl; l->__mbrtowc = _GB2312_mbrtowc; l->__wcrtomb = _GB2312_wcrtomb; l->__mbsinit = _GB2312_mbsinit; l->__mbsnrtowcs = _GB2312_mbsnrtowcs; l->__wcsnrtombs = _GB2312_wcsnrtombs; l->__mb_cur_max = 2; l->__mb_sb_limit = 128; return (0); } static int _GB2312_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _GB2312State *)ps)->count == 0); } static int _GB2312_check(const char *str, size_t n) { const u_char *s = (const u_char *)str; if (n == 0) /* Incomplete multibyte sequence */ return (-2); if (s[0] >= 0xa1 && s[0] <= 0xfe) { if (n < 2) /* Incomplete multibyte sequence */ return (-2); if (s[1] < 0xa1 || s[1] > 0xfe) /* Invalid multibyte sequence */ return (-1); return (2); } else if (s[0] & 0x80) { /* Invalid multibyte sequence */ return (-1); } return (1); } static size_t _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _GB2312State *gs; wchar_t wc; int i, len, ocount; size_t ncopy; gs = (_GB2312State *)ps; if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(gs->bytes) - gs->count); memcpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; s = (char *)gs->bytes; n = gs->count; if ((len = _GB2312_check(s, n)) < 0) return ((size_t)len); wc = 0; i = len; while (i-- > 0) wc = (wc << 8) | (unsigned char)*s++; if (pwc != NULL) *pwc = wc; gs->count = 0; return (wc == L'\0' ? 0 : len - ocount); } static size_t _GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GB2312State *gs; gs = (_GB2312State *)ps; if (gs->count != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if (wc & 0x8000) { *s++ = (wc >> 8) & 0xff; *s = wc & 0xff; return (2); } *s = wc & 0xff; return (1); } static size_t _GB2312_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GB2312_mbrtowc)); } static size_t _GB2312_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GB2312_wcrtomb)); } diff --git a/lib/libc/locale/gbk.c b/lib/libc/locale/gbk.c index a0ed8a10cedc..045e0645b1b5 100644 --- a/lib/libc/locale/gbk.c +++ b/lib/libc/locale/gbk.c @@ -1,197 +1,197 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include #include #include "mblocal.h" extern int __mb_sb_limit; static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _GBK_mbsinit(const mbstate_t *); static size_t _GBK_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _GBK_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _GBK_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { wchar_t ch; } _GBKState; int _GBK_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _GBK_mbrtowc; l->__wcrtomb = _GBK_wcrtomb; l->__mbsinit = _GBK_mbsinit; l->__mbsnrtowcs = _GBK_mbsnrtowcs; l->__wcsnrtombs = _GBK_wcsnrtombs; l->runes = rl; l->__mb_cur_max = 2; l->__mb_sb_limit = 128; return (0); } static int _GBK_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _GBKState *)ps)->ch == 0); } static int _gbk_check(u_int c) { c &= 0xff; return ((c >= 0x81 && c <= 0xfe) ? 2 : 1); } static size_t _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _GBKState *gs; wchar_t wc; size_t len; gs = (_GBKState *)ps; if ((gs->ch & ~0xFF) != 0) { /* Bad conversion state. */ errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (gs->ch != 0) { if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (gs->ch << 8) | (*s & 0xFF); if (pwc != NULL) *pwc = wc; gs->ch = 0; return (1); } len = (size_t)_gbk_check(*s); wc = *s++ & 0xff; if (len == 2) { if (n < 2) { /* Incomplete multibyte sequence */ gs->ch = wc; return ((size_t)-2); } if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (wc << 8) | (*s++ & 0xff); if (pwc != NULL) *pwc = wc; return (2); } else { if (pwc != NULL) *pwc = wc; return (wc == L'\0' ? 0 : 1); } } static size_t _GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _GBKState *gs; gs = (_GBKState *)ps; if (gs->ch != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if (wc & 0x8000) { *s++ = (wc >> 8) & 0xff; *s = wc & 0xff; return (2); } *s = wc & 0xff; return (1); } static size_t _GBK_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _GBK_mbrtowc)); } static size_t _GBK_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _GBK_wcrtomb)); } diff --git a/lib/libc/locale/lmessages.c b/lib/libc/locale/lmessages.c index ae562eaf688e..90757b131fbb 100644 --- a/lib/libc/locale/lmessages.c +++ b/lib/libc/locale/lmessages.c @@ -1,134 +1,134 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "ldpart.h" #include "lmessages.h" #define LCMESSAGES_SIZE_FULL (sizeof(struct lc_messages_T) / sizeof(char *)) #define LCMESSAGES_SIZE_MIN \ (offsetof(struct lc_messages_T, yesstr) / sizeof(char *)) struct xlocale_messages { struct xlocale_component header; char *buffer; struct lc_messages_T locale; }; struct xlocale_messages __xlocale_global_messages; static char empty[] = ""; static const struct lc_messages_T _C_messages_locale = { "^[yY]" , /* yesexpr */ "^[nN]" , /* noexpr */ "yes" , /* yesstr */ "no" /* nostr */ }; static void destruct_messages(void *v) { struct xlocale_messages *l = v; if (l->buffer) free(l->buffer); free(l); } static int messages_load_locale(struct xlocale_messages *loc, int *using_locale, const char *name) { int ret; struct lc_messages_T *l = &loc->locale; ret = __part_load_locale(name, using_locale, &loc->buffer, "LC_MESSAGES", LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, (const char **)l); if (ret == _LDP_LOADED) { if (l->yesstr == NULL) l->yesstr = empty; if (l->nostr == NULL) l->nostr = empty; } return (ret); } int __messages_load_locale(const char *name) { return (messages_load_locale(&__xlocale_global_messages, &__xlocale_global_locale.using_messages_locale, name)); } void * __messages_load(const char *name, locale_t l) { struct xlocale_messages *new = calloc(sizeof(struct xlocale_messages), 1); if (new == NULL) return (NULL); new->header.header.destructor = destruct_messages; if (messages_load_locale(new, &l->using_messages_locale, name) == _LDP_ERROR) { xlocale_release(new); return (NULL); } return (new); } struct lc_messages_T * __get_current_messages_locale(locale_t loc) { return (loc->using_messages_locale ? &((struct xlocale_messages *) loc->components[XLC_MESSAGES])->locale : (struct lc_messages_T *)&_C_messages_locale); } #ifdef LOCALE_DEBUG void msgdebug(void) { printf( "yesexpr = %s\n" "noexpr = %s\n" "yesstr = %s\n" "nostr = %s\n", _messages_locale.yesexpr, _messages_locale.noexpr, _messages_locale.yesstr, _messages_locale.nostr ); } #endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lmessages.h b/lib/libc/locale/lmessages.h index a83473d9db9a..a6057caa0ecf 100644 --- a/lib/libc/locale/lmessages.h +++ b/lib/libc/locale/lmessages.h @@ -1,49 +1,49 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000, 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #ifndef _LMESSAGES_H_ #define _LMESSAGES_H_ #include "xlocale_private.h" struct lc_messages_T { const char *yesexpr; const char *noexpr; const char *yesstr; const char *nostr; }; struct lc_messages_T *__get_current_messages_locale(locale_t); int __messages_load_locale(const char *); #endif /* !_LMESSAGES_H_ */ diff --git a/lib/libc/locale/lmonetary.c b/lib/libc/locale/lmonetary.c index 116f32ae3623..d2875e102b31 100644 --- a/lib/libc/locale/lmonetary.c +++ b/lib/libc/locale/lmonetary.c @@ -1,229 +1,229 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000, 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "ldpart.h" #include "lmonetary.h" extern const char * __fix_locale_grouping_str(const char *); #define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) #define LCMONETARY_SIZE_MIN \ (offsetof(struct lc_monetary_T, int_p_cs_precedes) / \ sizeof(char *)) static char empty[] = ""; static char numempty[] = { CHAR_MAX, '\0'}; static const struct lc_monetary_T _C_monetary_locale = { empty, /* int_curr_symbol */ empty, /* currency_symbol */ empty, /* mon_decimal_point */ empty, /* mon_thousands_sep */ numempty, /* mon_grouping */ empty, /* positive_sign */ empty, /* negative_sign */ numempty, /* int_frac_digits */ numempty, /* frac_digits */ numempty, /* p_cs_precedes */ numempty, /* p_sep_by_space */ numempty, /* n_cs_precedes */ numempty, /* n_sep_by_space */ numempty, /* p_sign_posn */ numempty, /* n_sign_posn */ numempty, /* int_p_cs_precedes */ numempty, /* int_n_cs_precedes */ numempty, /* int_p_sep_by_space */ numempty, /* int_n_sep_by_space */ numempty, /* int_p_sign_posn */ numempty /* int_n_sign_posn */ }; struct xlocale_monetary __xlocale_global_monetary; static char cnv(const char *str) { int i = strtol(str, NULL, 10); if (i == -1) i = CHAR_MAX; return ((char)i); } static void destruct_monetary(void *v) { struct xlocale_monetary *l = v; if (l->buffer) free(l->buffer); free(l); } static int monetary_load_locale_l(struct xlocale_monetary *loc, int *using_locale, int *changed, const char *name) { int ret; struct lc_monetary_T *l = &loc->locale; ret = __part_load_locale(name, using_locale, &loc->buffer, "LC_MONETARY", LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, (const char **)l); if (ret != _LDP_ERROR) *changed = 1; if (ret == _LDP_LOADED) { l->mon_grouping = __fix_locale_grouping_str(l->mon_grouping); #define M_ASSIGN_CHAR(NAME) (((char *)l->NAME)[0] = \ cnv(l->NAME)) M_ASSIGN_CHAR(int_frac_digits); M_ASSIGN_CHAR(frac_digits); M_ASSIGN_CHAR(p_cs_precedes); M_ASSIGN_CHAR(p_sep_by_space); M_ASSIGN_CHAR(n_cs_precedes); M_ASSIGN_CHAR(n_sep_by_space); M_ASSIGN_CHAR(p_sign_posn); M_ASSIGN_CHAR(n_sign_posn); /* * The six additional C99 international monetary formatting * parameters default to the national parameters when * reading FreeBSD LC_MONETARY data files. */ #define M_ASSIGN_ICHAR(NAME) \ do { \ if (l->int_##NAME == NULL) \ l->int_##NAME = \ l->NAME; \ else \ M_ASSIGN_CHAR(int_##NAME); \ } while (0) M_ASSIGN_ICHAR(p_cs_precedes); M_ASSIGN_ICHAR(n_cs_precedes); M_ASSIGN_ICHAR(p_sep_by_space); M_ASSIGN_ICHAR(n_sep_by_space); M_ASSIGN_ICHAR(p_sign_posn); M_ASSIGN_ICHAR(n_sign_posn); } return (ret); } int __monetary_load_locale(const char *name) { return (monetary_load_locale_l(&__xlocale_global_monetary, &__xlocale_global_locale.using_monetary_locale, &__xlocale_global_locale.monetary_locale_changed, name)); } void * __monetary_load(const char *name, locale_t l) { struct xlocale_monetary *new = calloc(sizeof(struct xlocale_monetary), 1); if (new == NULL) return (NULL); new->header.header.destructor = destruct_monetary; if (monetary_load_locale_l(new, &l->using_monetary_locale, &l->monetary_locale_changed, name) == _LDP_ERROR) { xlocale_release(new); return (NULL); } return (new); } struct lc_monetary_T * __get_current_monetary_locale(locale_t loc) { return (loc->using_monetary_locale ? &((struct xlocale_monetary*)loc->components[XLC_MONETARY])->locale : (struct lc_monetary_T *)&_C_monetary_locale); } #ifdef LOCALE_DEBUG void monetdebug(void) { printf( "int_curr_symbol = %s\n" "currency_symbol = %s\n" "mon_decimal_point = %s\n" "mon_thousands_sep = %s\n" "mon_grouping = %s\n" "positive_sign = %s\n" "negative_sign = %s\n" "int_frac_digits = %d\n" "frac_digits = %d\n" "p_cs_precedes = %d\n" "p_sep_by_space = %d\n" "n_cs_precedes = %d\n" "n_sep_by_space = %d\n" "p_sign_posn = %d\n" "n_sign_posn = %d\n" "int_p_cs_precedes = %d\n" "int_p_sep_by_space = %d\n" "int_n_cs_precedes = %d\n" "int_n_sep_by_space = %d\n" "int_p_sign_posn = %d\n" "int_n_sign_posn = %d\n", _monetary_locale.int_curr_symbol, _monetary_locale.currency_symbol, _monetary_locale.mon_decimal_point, _monetary_locale.mon_thousands_sep, _monetary_locale.mon_grouping, _monetary_locale.positive_sign, _monetary_locale.negative_sign, _monetary_locale.int_frac_digits[0], _monetary_locale.frac_digits[0], _monetary_locale.p_cs_precedes[0], _monetary_locale.p_sep_by_space[0], _monetary_locale.n_cs_precedes[0], _monetary_locale.n_sep_by_space[0], _monetary_locale.p_sign_posn[0], _monetary_locale.n_sign_posn[0], _monetary_locale.int_p_cs_precedes[0], _monetary_locale.int_p_sep_by_space[0], _monetary_locale.int_n_cs_precedes[0], _monetary_locale.int_n_sep_by_space[0], _monetary_locale.int_p_sign_posn[0], _monetary_locale.int_n_sign_posn[0] ); } #endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lmonetary.h b/lib/libc/locale/lmonetary.h index c9f835bf880c..11e39545482d 100644 --- a/lib/libc/locale/lmonetary.h +++ b/lib/libc/locale/lmonetary.h @@ -1,70 +1,70 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000, 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #ifndef _LMONETARY_H_ #define _LMONETARY_H_ #include "xlocale_private.h" struct lc_monetary_T { const char *int_curr_symbol; const char *currency_symbol; const char *mon_decimal_point; const char *mon_thousands_sep; const char *mon_grouping; const char *positive_sign; const char *negative_sign; const char *int_frac_digits; const char *frac_digits; const char *p_cs_precedes; const char *p_sep_by_space; const char *n_cs_precedes; const char *n_sep_by_space; const char *p_sign_posn; const char *n_sign_posn; const char *int_p_cs_precedes; const char *int_n_cs_precedes; const char *int_p_sep_by_space; const char *int_n_sep_by_space; const char *int_p_sign_posn; const char *int_n_sign_posn; }; struct xlocale_monetary { struct xlocale_component header; char *buffer; struct lc_monetary_T locale; }; struct lc_monetary_T *__get_current_monetary_locale(locale_t loc); int __monetary_load_locale(const char *); #endif /* !_LMONETARY_H_ */ diff --git a/lib/libc/locale/lnumeric.c b/lib/libc/locale/lnumeric.c index b37af113e319..28016777edb3 100644 --- a/lib/libc/locale/lnumeric.c +++ b/lib/libc/locale/lnumeric.c @@ -1,130 +1,130 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000, 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "ldpart.h" #include "lnumeric.h" extern const char *__fix_locale_grouping_str(const char *); #define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) static char numempty[] = { CHAR_MAX, '\0' }; static const struct lc_numeric_T _C_numeric_locale = { ".", /* decimal_point */ "", /* thousands_sep */ numempty /* grouping */ }; static void destruct_numeric(void *v) { struct xlocale_numeric *l = v; if (l->buffer) free(l->buffer); free(l); } struct xlocale_numeric __xlocale_global_numeric; static int numeric_load_locale(struct xlocale_numeric *loc, int *using_locale, int *changed, const char *name) { int ret; struct lc_numeric_T *l = &loc->locale; ret = __part_load_locale(name, using_locale, &loc->buffer, "LC_NUMERIC", LCNUMERIC_SIZE, LCNUMERIC_SIZE, (const char**)l); if (ret != _LDP_ERROR) *changed= 1; if (ret == _LDP_LOADED) { /* Can't be empty according to C99 */ if (*l->decimal_point == '\0') l->decimal_point = _C_numeric_locale.decimal_point; l->grouping = __fix_locale_grouping_str(l->grouping); } return (ret); } int __numeric_load_locale(const char *name) { return (numeric_load_locale(&__xlocale_global_numeric, &__xlocale_global_locale.using_numeric_locale, &__xlocale_global_locale.numeric_locale_changed, name)); } void * __numeric_load(const char *name, locale_t l) { struct xlocale_numeric *new = calloc(sizeof(struct xlocale_numeric), 1); if (new == NULL) return (NULL); new->header.header.destructor = destruct_numeric; if (numeric_load_locale(new, &l->using_numeric_locale, &l->numeric_locale_changed, name) == _LDP_ERROR) { xlocale_release(new); return (NULL); } return (new); } struct lc_numeric_T * __get_current_numeric_locale(locale_t loc) { return (loc->using_numeric_locale ? &((struct xlocale_numeric *)loc->components[XLC_NUMERIC])->locale : (struct lc_numeric_T *)&_C_numeric_locale); } #ifdef LOCALE_DEBUG void numericdebug(void) { printf( "decimal_point = %s\n" "thousands_sep = %s\n" "grouping = %s\n", _numeric_locale.decimal_point, _numeric_locale.thousands_sep, _numeric_locale.grouping ); } #endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lnumeric.h b/lib/libc/locale/lnumeric.h index aa1c4a7a231c..eaba6ed0bf54 100644 --- a/lib/libc/locale/lnumeric.h +++ b/lib/libc/locale/lnumeric.h @@ -1,52 +1,52 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000, 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #ifndef _LNUMERIC_H_ #define _LNUMERIC_H_ #include "xlocale_private.h" struct lc_numeric_T { const char *decimal_point; const char *thousands_sep; const char *grouping; }; struct xlocale_numeric { struct xlocale_component header; char *buffer; struct lc_numeric_T locale; }; struct lc_numeric_T *__get_current_numeric_locale(locale_t loc); int __numeric_load_locale(const char *); #endif /* !_LNUMERIC_H_ */ diff --git a/lib/libc/locale/localeconv.c b/lib/libc/locale/localeconv.c index 144bada3d89f..ae68d2687663 100644 --- a/lib/libc/locale/localeconv.c +++ b/lib/libc/locale/localeconv.c @@ -1,117 +1,117 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 2001 Alexey Zelkin * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include "lmonetary.h" #include "lnumeric.h" /* * The localeconv() function constructs a struct lconv from the current * monetary and numeric locales. * * Because localeconv() may be called many times (especially by library * routines like printf() & strtod()), the approprate members of the * lconv structure are computed only when the monetary or numeric * locale has been changed. */ /* * Return the current locale conversion. */ struct lconv * localeconv_l(locale_t loc) { FIX_LOCALE(loc); struct lconv *ret = &loc->lconv; if (loc->monetary_locale_changed) { /* LC_MONETARY part */ struct lc_monetary_T * mptr; #define M_ASSIGN_STR(NAME) (ret->NAME = (char*)mptr->NAME) #define M_ASSIGN_CHAR(NAME) (ret->NAME = mptr->NAME[0]) mptr = __get_current_monetary_locale(loc); M_ASSIGN_STR(int_curr_symbol); M_ASSIGN_STR(currency_symbol); M_ASSIGN_STR(mon_decimal_point); M_ASSIGN_STR(mon_thousands_sep); M_ASSIGN_STR(mon_grouping); M_ASSIGN_STR(positive_sign); M_ASSIGN_STR(negative_sign); M_ASSIGN_CHAR(int_frac_digits); M_ASSIGN_CHAR(frac_digits); M_ASSIGN_CHAR(p_cs_precedes); M_ASSIGN_CHAR(p_sep_by_space); M_ASSIGN_CHAR(n_cs_precedes); M_ASSIGN_CHAR(n_sep_by_space); M_ASSIGN_CHAR(p_sign_posn); M_ASSIGN_CHAR(n_sign_posn); M_ASSIGN_CHAR(int_p_cs_precedes); M_ASSIGN_CHAR(int_n_cs_precedes); M_ASSIGN_CHAR(int_p_sep_by_space); M_ASSIGN_CHAR(int_n_sep_by_space); M_ASSIGN_CHAR(int_p_sign_posn); M_ASSIGN_CHAR(int_n_sign_posn); loc->monetary_locale_changed = 0; } if (loc->numeric_locale_changed) { /* LC_NUMERIC part */ struct lc_numeric_T * nptr; #define N_ASSIGN_STR(NAME) (ret->NAME = (char*)nptr->NAME) nptr = __get_current_numeric_locale(loc); N_ASSIGN_STR(decimal_point); N_ASSIGN_STR(thousands_sep); N_ASSIGN_STR(grouping); loc->numeric_locale_changed = 0; } return ret; } struct lconv * localeconv(void) { return localeconv_l(__get_locale()); } diff --git a/lib/libc/locale/mblen.c b/lib/libc/locale/mblen.c index 00d0ec4d2feb..a0ff1660ce5d 100644 --- a/lib/libc/locale/mblen.c +++ b/lib/libc/locale/mblen.c @@ -1,62 +1,62 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include "mblocal.h" int mblen_l(const char *s, size_t n, locale_t locale) { static const mbstate_t initial; size_t rval; FIX_LOCALE(locale); if (s == NULL) { /* No support for state dependent encodings. */ XLOCALE_CTYPE(locale)->mblen = initial; return (0); } rval = XLOCALE_CTYPE(locale)->__mbrtowc(NULL, s, n, &(XLOCALE_CTYPE(locale)->mblen)); if (rval == (size_t)-1 || rval == (size_t)-2) return (-1); return ((int)rval); } int mblen(const char *s, size_t n) { return mblen_l(s, n, __get_locale()); } diff --git a/lib/libc/locale/mblocal.h b/lib/libc/locale/mblocal.h index 14eb4b69fc82..a39117cc6352 100644 --- a/lib/libc/locale/mblocal.h +++ b/lib/libc/locale/mblocal.h @@ -1,118 +1,118 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #ifndef _MBLOCAL_H_ #define _MBLOCAL_H_ #include #include "xlocale_private.h" #define SS2 0x008e #define SS3 0x008f /* * Conversion function pointers for current encoding. */ struct xlocale_ctype { struct xlocale_component header; _RuneLocale *runes; size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); int (*__mbsinit)(const mbstate_t *); size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict); size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); int __mb_cur_max; int __mb_sb_limit; /** Persistent state used by mblen() calls. */ __mbstate_t mblen; /** Persistent state used by mbrlen() calls. */ __mbstate_t mbrlen; /** Persistent state used by mbrtoc16() calls. */ __mbstate_t mbrtoc16; /** Persistent state used by mbrtoc32() calls. */ __mbstate_t mbrtoc32; /** Persistent state used by mbrtowc() calls. */ __mbstate_t mbrtowc; /** Persistent state used by mbsnrtowcs() calls. */ __mbstate_t mbsnrtowcs; /** Persistent state used by mbsrtowcs() calls. */ __mbstate_t mbsrtowcs; /** Persistent state used by mbtowc() calls. */ __mbstate_t mbtowc; /** Persistent state used by c16rtomb() calls. */ __mbstate_t c16rtomb; /** Persistent state used by c32rtomb() calls. */ __mbstate_t c32rtomb; /** Persistent state used by wcrtomb() calls. */ __mbstate_t wcrtomb; /** Persistent state used by wcsnrtombs() calls. */ __mbstate_t wcsnrtombs; /** Persistent state used by wcsrtombs() calls. */ __mbstate_t wcsrtombs; /** Persistent state used by wctomb() calls. */ __mbstate_t wctomb; }; #define XLOCALE_CTYPE(x) ((struct xlocale_ctype*)(x)->components[XLC_CTYPE]) extern struct xlocale_ctype __xlocale_global_ctype; /* * Rune initialization function prototypes. */ int _none_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _UTF8_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _EUC_CN_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _EUC_JP_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _EUC_KR_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _EUC_TW_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _GB18030_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _GB2312_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _GBK_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _BIG5_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _MSKanji_init(struct xlocale_ctype *, _RuneLocale *) __hidden; int _ascii_init(struct xlocale_ctype *, _RuneLocale *) __hidden; typedef size_t (*mbrtowc_pfn_t)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); typedef size_t (*wcrtomb_pfn_t)(char * __restrict, wchar_t, mbstate_t * __restrict); size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict, mbrtowc_pfn_t); size_t __wcsnrtombs_std(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict, wcrtomb_pfn_t); #endif /* _MBLOCAL_H_ */ diff --git a/lib/libc/locale/mbrlen.c b/lib/libc/locale/mbrlen.c index dd0154b79681..57237c86141e 100644 --- a/lib/libc/locale/mbrlen.c +++ b/lib/libc/locale/mbrlen.c @@ -1,51 +1,51 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "mblocal.h" size_t mbrlen_l(const char * __restrict s, size_t n, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->mbrlen); return (XLOCALE_CTYPE(locale)->__mbrtowc(NULL, s, n, ps)); } size_t mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return mbrlen_l(s, n, ps, __get_locale()); } diff --git a/lib/libc/locale/mbrtowc.c b/lib/libc/locale/mbrtowc.c index f4aaffb98b94..b92968156e0e 100644 --- a/lib/libc/locale/mbrtowc.c +++ b/lib/libc/locale/mbrtowc.c @@ -1,53 +1,53 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "mblocal.h" size_t mbrtowc_l(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->mbrtowc); return (XLOCALE_CTYPE(locale)->__mbrtowc(pwc, s, n, ps)); } size_t mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { return mbrtowc_l(pwc, s, n, ps, __get_locale()); } diff --git a/lib/libc/locale/mbsinit.c b/lib/libc/locale/mbsinit.c index 5947132088f8..c9aece68fe6f 100644 --- a/lib/libc/locale/mbsinit.c +++ b/lib/libc/locale/mbsinit.c @@ -1,48 +1,48 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "mblocal.h" int mbsinit_l(const mbstate_t *ps, locale_t locale) { FIX_LOCALE(locale); return (XLOCALE_CTYPE(locale)->__mbsinit(ps)); } int mbsinit(const mbstate_t *ps) { return mbsinit_l(ps, __get_locale()); } diff --git a/lib/libc/locale/mbsnrtowcs.c b/lib/libc/locale/mbsnrtowcs.c index c543a6c7e631..b667ee710757 100644 --- a/lib/libc/locale/mbsnrtowcs.c +++ b/lib/libc/locale/mbsnrtowcs.c @@ -1,104 +1,103 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. - * 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. */ #include #include #include #include #include #include "mblocal.h" size_t mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->mbsnrtowcs); return (XLOCALE_CTYPE(locale)->__mbsnrtowcs(dst, src, nms, len, ps)); } size_t mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return mbsnrtowcs_l(dst, src, nms, len, ps, __get_locale()); } size_t __mbsnrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps, mbrtowc_pfn_t pmbrtowc) { const char *s; size_t nchr; wchar_t wc; size_t nb; s = *src; nchr = 0; if (dst == NULL) { for (;;) { if ((nb = pmbrtowc(&wc, s, nms, ps)) == (size_t)-1) /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); else if (nb == 0 || nb == (size_t)-2) return (nchr); s += nb; nms -= nb; nchr++; } /*NOTREACHED*/ } while (len-- > 0) { if ((nb = pmbrtowc(dst, s, nms, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } else if (nb == (size_t)-2) { *src = s + nms; return (nchr); } else if (nb == 0) { *src = NULL; return (nchr); } s += nb; nms -= nb; nchr++; dst++; } *src = s; return (nchr); } diff --git a/lib/libc/locale/mbsrtowcs.c b/lib/libc/locale/mbsrtowcs.c index 2b2b840a8821..718d61c77ea4 100644 --- a/lib/libc/locale/mbsrtowcs.c +++ b/lib/libc/locale/mbsrtowcs.c @@ -1,55 +1,55 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include "mblocal.h" size_t mbsrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, size_t len, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->mbsrtowcs); return (XLOCALE_CTYPE(locale)->__mbsnrtowcs(dst, src, SIZE_T_MAX, len, ps)); } size_t mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, mbstate_t * __restrict ps) { return mbsrtowcs_l(dst, src, len, ps, __get_locale()); } diff --git a/lib/libc/locale/mbstowcs.c b/lib/libc/locale/mbstowcs.c index 12f164584971..805a49b3563f 100644 --- a/lib/libc/locale/mbstowcs.c +++ b/lib/libc/locale/mbstowcs.c @@ -1,56 +1,56 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "mblocal.h" size_t mbstowcs_l(wchar_t * __restrict pwcs, const char * __restrict s, size_t n, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; const char *sp; FIX_LOCALE(locale); mbs = initial; sp = s; return (XLOCALE_CTYPE(locale)->__mbsnrtowcs(pwcs, &sp, SIZE_T_MAX, n, &mbs)); } size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) { return mbstowcs_l(pwcs, s, n, __get_locale()); } diff --git a/lib/libc/locale/mbtowc.c b/lib/libc/locale/mbtowc.c index 785b898abd92..56b9b2ba8afd 100644 --- a/lib/libc/locale/mbtowc.c +++ b/lib/libc/locale/mbtowc.c @@ -1,68 +1,68 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "mblocal.h" int mbtowc_l(wchar_t * __restrict pwc, const char * __restrict s, size_t n, locale_t locale) { static const mbstate_t initial; size_t rval; FIX_LOCALE(locale); if (s == NULL) { /* No support for state dependent encodings. */ XLOCALE_CTYPE(locale)->mbtowc = initial; return (0); } rval = XLOCALE_CTYPE(locale)->__mbrtowc(pwc, s, n, &(XLOCALE_CTYPE(locale)->mbtowc)); switch (rval) { case (size_t)-2: errno = EILSEQ; /* FALLTHROUGH */ case (size_t)-1: return (-1); default: return ((int)rval); } } int mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n) { return mbtowc_l(pwc, s, n, __get_locale()); } diff --git a/lib/libc/locale/mskanji.c b/lib/libc/locale/mskanji.c index 22861edc036f..3b30ed0c6027 100644 --- a/lib/libc/locale/mskanji.c +++ b/lib/libc/locale/mskanji.c @@ -1,191 +1,191 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * * ja_JP.SJIS locale table for BSD4.4/rune * version 1.0 * (C) Sin'ichiro MIYATANI / Phase One, Inc * May 12, 1995 * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 Phase One, Inc. * 4. The name of Phase One, Inc. 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include "mblocal.h" extern int __mb_sb_limit; static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _MSKanji_mbsinit(const mbstate_t *); static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _MSKanji_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _MSKanji_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { wchar_t ch; } _MSKanjiState; int _MSKanji_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _MSKanji_mbrtowc; l->__wcrtomb = _MSKanji_wcrtomb; l->__mbsnrtowcs = _MSKanji_mbsnrtowcs; l->__wcsnrtombs = _MSKanji_wcsnrtombs; l->__mbsinit = _MSKanji_mbsinit; l->runes = rl; l->__mb_cur_max = 2; l->__mb_sb_limit = 224; return (0); } static int _MSKanji_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); } static size_t _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _MSKanjiState *ms; wchar_t wc; ms = (_MSKanjiState *)ps; if ((ms->ch & ~0xFF) != 0) { /* Bad conversion state. */ errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (ms->ch != 0) { if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (ms->ch << 8) | (*s & 0xFF); if (pwc != NULL) *pwc = wc; ms->ch = 0; return (1); } wc = *s++ & 0xff; if ((wc > 0x80 && wc < 0xa0) || (wc >= 0xe0 && wc < 0xfd)) { if (n < 2) { /* Incomplete multibyte sequence */ ms->ch = wc; return ((size_t)-2); } if (*s == '\0') { errno = EILSEQ; return ((size_t)-1); } wc = (wc << 8) | (*s++ & 0xff); if (pwc != NULL) *pwc = wc; return (2); } else { if (pwc != NULL) *pwc = wc; return (wc == L'\0' ? 0 : 1); } } static size_t _MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _MSKanjiState *ms; int len, i; ms = (_MSKanjiState *)ps; if (ms->ch != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); len = (wc > 0x100) ? 2 : 1; for (i = len; i-- > 0; ) *s++ = wc >> (i << 3); return (len); } static size_t _MSKanji_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { return (__mbsnrtowcs_std(dst, src, nms, len, ps, _MSKanji_mbrtowc)); } static size_t _MSKanji_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return (__wcsnrtombs_std(dst, src, nwc, len, ps, _MSKanji_wcrtomb)); } diff --git a/lib/libc/locale/newlocale.3 b/lib/libc/locale/newlocale.3 index 86f9d6be14a9..8dbe52e10eb9 100644 --- a/lib/libc/locale/newlocale.3 +++ b/lib/libc/locale/newlocale.3 @@ -1,123 +1,122 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 October 2, 2020 .Dt NEWLOCALE 3 .Os .Sh NAME .Nm newlocale .Nd Creates a new locale .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In locale.h .Ft locale_t .Fn newlocale "int mask" "const char * locale" "locale_t base" .Sh DESCRIPTION Creates a new locale, inheriting some properties from an existing locale. The .Fa mask defines the components that the new locale will have set to the locale with the name specified in the .Fa locale parameter. Any components not specified in .Fa mask will be inherited from the locale referenced by .Fa base , if .Fa base is not .Dv NULL . If the call is successful, the state of the locale referenced by .Fa base is unspecified, and it must not be accessed. The special locale .Dv LC_GLOBAL_LOCALE may not be specified for .Fa base . The .Fa mask is either .Fa LC_ALL_MASK , indicating all possible locale components, or the logical OR of some combination of the following: .Bl -tag -width "LC_MESSAGES_MASK" -offset indent .It LC_COLLATE_MASK The locale for string collation routines. This controls alphabetic ordering in .Xr strcoll 3 and .Xr strxfrm 3 . .It LC_CTYPE_MASK The locale for the .Xr ctype 3 and .Xr multibyte 3 functions. This controls recognition of upper and lower case, alphabetic or non-alphabetic characters, and so on. .It LC_MESSAGES_MASK Set a locale for message catalogs, see .Xr catopen 3 function. .It LC_MONETARY_MASK Set a locale for formatting monetary values; this affects the .Xr localeconv 3 function. .It LC_NUMERIC_MASK Set a locale for formatting numbers. This controls the formatting of decimal points in input and output of floating point numbers in functions such as .Xr printf 3 and .Xr scanf 3 , as well as values returned by .Xr localeconv 3 . .It LC_TIME_MASK Set a locale for formatting dates and times using the .Xr strftime 3 function. .El This function uses the same rules for loading locale components as .Xr setlocale 3 . .Sh RETURN VALUES Returns a new, valid, .Fa locale_t or NULL if an error occurs. You must free the returned locale with .Xr freelocale 3 . .Sh SEE ALSO .Xr duplocale 3 , .Xr freelocale 3 , .Xr localeconv 3 , .Xr querylocale 3 , .Xr uselocale 3 , .Xr xlocale 3 .Sh STANDARDS This function conforms to .St -p1003.1-2008 . diff --git a/lib/libc/locale/nextwctype.c b/lib/libc/locale/nextwctype.c index 73b2607e23af..dd81cd82940e 100644 --- a/lib/libc/locale/nextwctype.c +++ b/lib/libc/locale/nextwctype.c @@ -1,103 +1,103 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "mblocal.h" wint_t nextwctype_l(wint_t wc, wctype_t wct, locale_t locale) { size_t lim; FIX_LOCALE(locale); _RuneLocale *runes = XLOCALE_CTYPE(locale)->runes; _RuneRange *rr = &runes->__runetype_ext; _RuneEntry *base, *re; int noinc; noinc = 0; if (wc < _CACHED_RUNES) { wc++; while (wc < _CACHED_RUNES) { if (runes->__runetype[wc] & wct) return (wc); wc++; } wc--; } if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { wc = rr->__ranges[0].__min; noinc = 1; } /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { re = base + (lim >> 1); if (re->__min <= wc && wc <= re->__max) goto found; else if (wc > re->__max) { base = re + 1; lim--; } } return (-1); found: if (!noinc) wc++; if (re->__min <= wc && wc <= re->__max) { if (re->__types != NULL) { for (; wc <= re->__max; wc++) if (re->__types[wc - re->__min] & wct) return (wc); } else if (re->__map & wct) return (wc); } while (++re < rr->__ranges + rr->__nranges) { wc = re->__min; if (re->__types != NULL) { for (; wc <= re->__max; wc++) if (re->__types[wc - re->__min] & wct) return (wc); } else if (re->__map & wct) return (wc); } return (-1); } wint_t nextwctype(wint_t wc, wctype_t wct) { return nextwctype_l(wc, wct, __get_locale()); } diff --git a/lib/libc/locale/nl_langinfo.c b/lib/libc/locale/nl_langinfo.c index 5a0991412c29..b7055f3eaa62 100644 --- a/lib/libc/locale/nl_langinfo.c +++ b/lib/libc/locale/nl_langinfo.c @@ -1,207 +1,207 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2001, 2003 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include #include #include "mblocal.h" #include "lnumeric.h" #include "lmessages.h" #include "lmonetary.h" #include "../stdtime/timelocal.h" #define _REL(BASE) ((int)item-BASE) char * nl_langinfo_l(nl_item item, locale_t loc) { char *ret, *cs; const char *s; FIX_LOCALE(loc); switch (item) { case CODESET: s = XLOCALE_CTYPE(loc)->runes->__encoding; if (strcmp(s, "EUC-CN") == 0) ret = "eucCN"; else if (strcmp(s, "EUC-JP") == 0) ret = "eucJP"; else if (strcmp(s, "EUC-KR") == 0) ret = "eucKR"; else if (strcmp(s, "EUC-TW") == 0) ret = "eucTW"; else if (strcmp(s, "BIG5") == 0) ret = "Big5"; else if (strcmp(s, "MSKanji") == 0) ret = "SJIS"; else if (strcmp(s, "NONE") == 0) ret = "US-ASCII"; else if (strncmp(s, "NONE:", 5) == 0) ret = (char *)(s + 5); else ret = (char *)s; break; case D_T_FMT: ret = (char *) __get_current_time_locale(loc)->c_fmt; break; case D_FMT: ret = (char *) __get_current_time_locale(loc)->x_fmt; break; case T_FMT: ret = (char *) __get_current_time_locale(loc)->X_fmt; break; case T_FMT_AMPM: ret = (char *) __get_current_time_locale(loc)->ampm_fmt; break; case AM_STR: ret = (char *) __get_current_time_locale(loc)->am; break; case PM_STR: ret = (char *) __get_current_time_locale(loc)->pm; break; case DAY_1: case DAY_2: case DAY_3: case DAY_4: case DAY_5: case DAY_6: case DAY_7: ret = (char*) __get_current_time_locale(loc)->weekday[_REL(DAY_1)]; break; case ABDAY_1: case ABDAY_2: case ABDAY_3: case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: ret = (char*) __get_current_time_locale(loc)->wday[_REL(ABDAY_1)]; break; case MON_1: case MON_2: case MON_3: case MON_4: case MON_5: case MON_6: case MON_7: case MON_8: case MON_9: case MON_10: case MON_11: case MON_12: ret = (char*) __get_current_time_locale(loc)->month[_REL(MON_1)]; break; case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: ret = (char*) __get_current_time_locale(loc)->mon[_REL(ABMON_1)]; break; case ALTMON_1: case ALTMON_2: case ALTMON_3: case ALTMON_4: case ALTMON_5: case ALTMON_6: case ALTMON_7: case ALTMON_8: case ALTMON_9: case ALTMON_10: case ALTMON_11: case ALTMON_12: ret = (char*) __get_current_time_locale(loc)->alt_month[_REL(ALTMON_1)]; break; case ERA: /* XXX: need to be implemented */ ret = ""; break; case ERA_D_FMT: /* XXX: need to be implemented */ ret = ""; break; case ERA_D_T_FMT: /* XXX: need to be implemented */ ret = ""; break; case ERA_T_FMT: /* XXX: need to be implemented */ ret = ""; break; case ALT_DIGITS: /* XXX: need to be implemented */ ret = ""; break; case RADIXCHAR: ret = (char*) __get_current_numeric_locale(loc)->decimal_point; break; case THOUSEP: ret = (char*) __get_current_numeric_locale(loc)->thousands_sep; break; case YESEXPR: ret = (char*) __get_current_messages_locale(loc)->yesexpr; break; case NOEXPR: ret = (char*) __get_current_messages_locale(loc)->noexpr; break; /* * YESSTR and NOSTR items marked with LEGACY are available, but not * recommended by SUSv2 to be used in portable applications since * they're subject to remove in future specification editions. */ case YESSTR: /* LEGACY */ ret = (char*) __get_current_messages_locale(loc)->yesstr; break; case NOSTR: /* LEGACY */ ret = (char*) __get_current_messages_locale(loc)->nostr; break; /* * SUSv2 special formatted currency string */ case CRNCYSTR: ret = ""; cs = (char*) __get_current_monetary_locale(loc)->currency_symbol; if (*cs != '\0') { char pos = localeconv_l(loc)->p_cs_precedes; if (pos == localeconv_l(loc)->n_cs_precedes) { char psn = '\0'; if (pos == CHAR_MAX) { if (strcmp(cs, __get_current_monetary_locale(loc)->mon_decimal_point) == 0) psn = '.'; } else psn = pos ? '-' : '+'; if (psn != '\0') { int clen = strlen(cs); if ((loc->csym = reallocf(loc->csym, clen + 2)) != NULL) { *loc->csym = psn; strcpy(loc->csym + 1, cs); ret = loc->csym; } } } } break; case D_MD_ORDER: /* FreeBSD local extension */ ret = (char *) __get_current_time_locale(loc)->md_order; break; default: ret = ""; } return (ret); } char * nl_langinfo(nl_item item) { return nl_langinfo_l(item, __get_locale()); } diff --git a/lib/libc/locale/none.c b/lib/libc/locale/none.c index 7fc63a74181e..a0110f8590ec 100644 --- a/lib/libc/locale/none.c +++ b/lib/libc/locale/none.c @@ -1,215 +1,215 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include "mblocal.h" static size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _none_mbsinit(const mbstate_t *); static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused); static size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); /* setup defaults */ int __mb_cur_max = 1; int __mb_sb_limit = 256; /* Expected to be <= _CACHED_RUNES */ int _none_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _none_mbrtowc; l->__mbsinit = _none_mbsinit; l->__mbsnrtowcs = _none_mbsnrtowcs; l->__wcrtomb = _none_wcrtomb; l->__wcsnrtombs = _none_wcsnrtombs; l->runes = rl; l->__mb_cur_max = 1; l->__mb_sb_limit = 256; return(0); } static int _none_mbsinit(const mbstate_t *ps __unused) { /* * Encoding is not state dependent - we are always in the * initial state. */ return (1); } static size_t _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused) { if (s == NULL) /* Reset to initial shift state (no-op) */ return (0); if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (pwc != NULL) *pwc = (unsigned char)*s; return (*s == '\0' ? 0 : 1); } static size_t _none_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused) { if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); if (wc < 0 || wc > UCHAR_MAX) { errno = EILSEQ; return ((size_t)-1); } *s = (unsigned char)wc; return (1); } static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused) { const char *s; size_t nchr; if (dst == NULL) { s = memchr(*src, '\0', nms); return (s != NULL ? s - *src : nms); } s = *src; nchr = 0; while (len-- > 0 && nms-- > 0) { if ((*dst++ = (unsigned char)*s++) == L'\0') { *src = NULL; return (nchr); } nchr++; } *src = s; return (nchr); } static size_t _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps __unused) { const wchar_t *s; size_t nchr; if (dst == NULL) { for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { if (*s < 0 || *s > UCHAR_MAX) { errno = EILSEQ; return ((size_t)-1); } } return (s - *src); } s = *src; nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > UCHAR_MAX) { *src = s; errno = EILSEQ; return ((size_t)-1); } if ((*dst++ = *s++) == '\0') { *src = NULL; return (nchr); } nchr++; } *src = s; return (nchr); } /* setup defaults */ struct xlocale_ctype __xlocale_global_ctype = { {{0}, "C"}, (_RuneLocale*)&_DefaultRuneLocale, _none_mbrtowc, _none_mbsinit, _none_mbsnrtowcs, _none_wcrtomb, _none_wcsnrtombs, 1, /* __mb_cur_max, */ 256 /* __mb_sb_limit */ }; struct xlocale_ctype __xlocale_C_ctype = { {{0}, "C"}, (_RuneLocale*)&_DefaultRuneLocale, _none_mbrtowc, _none_mbsinit, _none_mbsnrtowcs, _none_wcrtomb, _none_wcsnrtombs, 1, /* __mb_cur_max, */ 256 /* __mb_sb_limit */ }; diff --git a/lib/libc/locale/querylocale.3 b/lib/libc/locale/querylocale.3 index 69944f90d79b..6ac317ef42bf 100644 --- a/lib/libc/locale/querylocale.3 +++ b/lib/libc/locale/querylocale.3 @@ -1,72 +1,71 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 8, 2020 .Dt QUERYLOCALE 3 .Os .Sh NAME .Nm querylocale .Nd Look up the locale name or version for a specified category .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In locale.h .Ft const char * .Fn querylocale "int mask" "locale_t locale" .Sh DESCRIPTION Returns the name or version of the locale for the category specified by .Fa mask . The possible values for the mask are the same as those in .Xr newlocale 3 , when requesting the locale name. Specify the bitwise OR of .Fa LC_VERSION_MASK and another mask value to request a version string. Version strings can be compared to detect changes to the locale's definition. The structure of the version string is unspecified. Currently, version information is only available for .Fa LC_COLLATE_MASK , and an empty string is returned for other categories. If more than one bit in the mask is set, not counting .Fa LC_VERSION_MASK , the returned value is undefined. .Sh SEE ALSO .Xr duplocale 3 , .Xr freelocale 3 , .Xr localeconv 3 , .Xr newlocale 3 , .Xr uselocale 3 , .Xr xlocale 3 .Sh HISTORY The .Fn querylocale function first appeared in .Fx 9.1 , and is based on the function of the same name in Darwin. .Fa LC_VERSION_MASK first appeared in .Fx 13.0 . diff --git a/lib/libc/locale/runetype.c b/lib/libc/locale/runetype.c index b10550c501f8..1442c3a77fd5 100644 --- a/lib/libc/locale/runetype.c +++ b/lib/libc/locale/runetype.c @@ -1,89 +1,89 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include "mblocal.h" unsigned long ___runetype_l(__ct_rune_t c, locale_t locale) { size_t lim; FIX_LOCALE(locale); _RuneRange *rr = &(XLOCALE_CTYPE(locale)->runes->__runetype_ext); _RuneEntry *base, *re; if (c < 0 || c == EOF) return(0L); /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { re = base + (lim >> 1); if (re->__min <= c && c <= re->__max) { if (re->__types) return(re->__types[c - re->__min]); else return(re->__map); } else if (c > re->__max) { base = re + 1; lim--; } } return(0L); } unsigned long ___runetype(__ct_rune_t c) { return ___runetype_l(c, __get_locale()); } int ___mb_cur_max(void) { return XLOCALE_CTYPE(__get_locale())->__mb_cur_max; } int ___mb_cur_max_l(locale_t locale) { FIX_LOCALE(locale); return XLOCALE_CTYPE(locale)->__mb_cur_max; } diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c index 5d5116a95bbe..8c8ef82a1193 100644 --- a/lib/libc/locale/setrunelocale.c +++ b/lib/libc/locale/setrunelocale.c @@ -1,224 +1,224 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #define __RUNETYPE_INTERNAL 1 #include #include #include #include #include #include #include #include #include "ldpart.h" #include "mblocal.h" #include "setlocale.h" #undef _CurrentRuneLocale extern _RuneLocale const *_CurrentRuneLocale; /* * A cached version of the runes for this thread. Used by ctype.h */ _Thread_local const _RuneLocale *_ThreadRuneLocale; extern int __mb_sb_limit; extern _RuneLocale *_Read_RuneMagi(const char *); static int __setrunelocale(struct xlocale_ctype *l, const char *); static void destruct_ctype(void *v) { struct xlocale_ctype *l = v; if (&_DefaultRuneLocale != l->runes) free(l->runes); free(l); } const _RuneLocale * __getCurrentRuneLocale(void) { return (XLOCALE_CTYPE(__get_locale())->runes); } static void free_runes(_RuneLocale *rl) { if ((rl != &_DefaultRuneLocale) && (rl)) { free(rl); } } static int __setrunelocale(struct xlocale_ctype *l, const char *encoding) { _RuneLocale *rl; int ret; char *path; struct xlocale_ctype saved = *l; /* * The "C" and "POSIX" locale are always here. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { free_runes(saved.runes); (void) _none_init(l, (_RuneLocale*)&_DefaultRuneLocale); return (0); } /* Range checking not needed, encoding length already checked before */ if (asprintf(&path, "%s/%s/LC_CTYPE", _PathLocale, encoding) == -1) return (errno); if ((rl = _Read_RuneMagi(path)) == NULL) { free(path); errno = EINVAL; return (errno); } free(path); l->__mbrtowc = NULL; l->__mbsinit = NULL; l->__mbsnrtowcs = NULL; l->__wcrtomb = NULL; l->__wcsnrtombs = NULL; rl->__sputrune = NULL; rl->__sgetrune = NULL; if (strcmp(rl->__encoding, "NONE:US-ASCII") == 0) ret = _ascii_init(l, rl); else if (strncmp(rl->__encoding, "NONE", 4) == 0) ret = _none_init(l, rl); else if (strcmp(rl->__encoding, "UTF-8") == 0) ret = _UTF8_init(l, rl); else if (strcmp(rl->__encoding, "EUC-CN") == 0) ret = _EUC_CN_init(l, rl); else if (strcmp(rl->__encoding, "EUC-JP") == 0) ret = _EUC_JP_init(l, rl); else if (strcmp(rl->__encoding, "EUC-KR") == 0) ret = _EUC_KR_init(l, rl); else if (strcmp(rl->__encoding, "EUC-TW") == 0) ret = _EUC_TW_init(l, rl); else if (strcmp(rl->__encoding, "GB18030") == 0) ret = _GB18030_init(l, rl); else if (strcmp(rl->__encoding, "GB2312") == 0) ret = _GB2312_init(l, rl); else if (strcmp(rl->__encoding, "GBK") == 0) ret = _GBK_init(l, rl); else if (strcmp(rl->__encoding, "BIG5") == 0) ret = _BIG5_init(l, rl); else if (strcmp(rl->__encoding, "MSKanji") == 0) ret = _MSKanji_init(l, rl); else ret = EFTYPE; if (ret == 0) { /* Free the old runes if it exists. */ free_runes(saved.runes); /* Reset the mbstates */ memset(&l->c16rtomb, 0, sizeof(l->c16rtomb)); memset(&l->c32rtomb, 0, sizeof(l->c32rtomb)); memset(&l->mblen, 0, sizeof(l->mblen)); memset(&l->mbrlen, 0, sizeof(l->mbrlen)); memset(&l->mbrtoc16, 0, sizeof(l->mbrtoc16)); memset(&l->mbrtoc32, 0, sizeof(l->mbrtoc32)); memset(&l->mbrtowc, 0, sizeof(l->mbrtowc)); memset(&l->mbsnrtowcs, 0, sizeof(l->mbsnrtowcs)); memset(&l->mbsrtowcs, 0, sizeof(l->mbsrtowcs)); memset(&l->mbtowc, 0, sizeof(l->mbtowc)); memset(&l->wcrtomb, 0, sizeof(l->wcrtomb)); memset(&l->wcsnrtombs, 0, sizeof(l->wcsnrtombs)); memset(&l->wcsrtombs, 0, sizeof(l->wcsrtombs)); memset(&l->wctomb, 0, sizeof(l->wctomb)); } else { /* Restore the saved version if this failed. */ memcpy(l, &saved, sizeof(struct xlocale_ctype)); free(rl); } return (ret); } int __wrap_setrunelocale(const char *locale) { int ret = __setrunelocale(&__xlocale_global_ctype, locale); if (ret != 0) { errno = ret; return (_LDP_ERROR); } __mb_cur_max = __xlocale_global_ctype.__mb_cur_max; __mb_sb_limit = __xlocale_global_ctype.__mb_sb_limit; _CurrentRuneLocale = __xlocale_global_ctype.runes; return (_LDP_LOADED); } void __set_thread_rune_locale(locale_t loc) { if (loc == NULL) { _ThreadRuneLocale = &_DefaultRuneLocale; } else if (loc == LC_GLOBAL_LOCALE) { _ThreadRuneLocale = 0; } else { _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes; } } void * __ctype_load(const char *locale, locale_t unused __unused) { struct xlocale_ctype *l = calloc(sizeof(struct xlocale_ctype), 1); if (l == NULL) return (NULL); l->header.header.destructor = destruct_ctype; if (__setrunelocale(l, locale)) { free(l); return (NULL); } return (l); } diff --git a/lib/libc/locale/table.c b/lib/libc/locale/table.c index 2208a3c0455c..1c6ecacbbbfa 100644 --- a/lib/libc/locale/table.c +++ b/lib/libc/locale/table.c @@ -1,263 +1,263 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include "mblocal.h" const _RuneLocale _DefaultRuneLocale = { _RUNE_MAGIC_1, "NONE", NULL, NULL, 0xFFFD, { /*00*/ _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, /*08*/ _CTYPE_C, _CTYPE_C|_CTYPE_S|_CTYPE_B, _CTYPE_C|_CTYPE_S, _CTYPE_C|_CTYPE_S, _CTYPE_C|_CTYPE_S, _CTYPE_C|_CTYPE_S, _CTYPE_C, _CTYPE_C, /*10*/ _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, /*18*/ _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, _CTYPE_C, /*20*/ _CTYPE_S|_CTYPE_B|_CTYPE_R, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, /*28*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, /*30*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|0, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|1, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|2, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|3, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|4, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|5, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|6, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|7, /*38*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|8, _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|_CTYPE_N|9, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, /*40*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*48*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*50*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*58*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, /*60*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*68*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*70*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, /*78*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_P|_CTYPE_R|_CTYPE_G, _CTYPE_C, }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }, }; #undef _CurrentRuneLocale const _RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; _RuneLocale * __runes_for_locale(locale_t locale, int *mb_sb_limit) { FIX_LOCALE(locale); struct xlocale_ctype *c = XLOCALE_CTYPE(locale); *mb_sb_limit = c->__mb_sb_limit; return c->runes; } diff --git a/lib/libc/locale/tolower.c b/lib/libc/locale/tolower.c index fdf07b56532f..59cd24393a22 100644 --- a/lib/libc/locale/tolower.c +++ b/lib/libc/locale/tolower.c @@ -1,76 +1,76 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include "mblocal.h" __ct_rune_t ___tolower_l(__ct_rune_t c, locale_t l) { size_t lim; FIX_LOCALE(l); _RuneRange *rr = &XLOCALE_CTYPE(l)->runes->__maplower_ext; _RuneEntry *base, *re; if (c < 0 || c == EOF) return(c); /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { re = base + (lim >> 1); if (re->__min <= c && c <= re->__max) return (re->__map + c - re->__min); else if (c > re->__max) { base = re + 1; lim--; } } return(c); } __ct_rune_t ___tolower(__ct_rune_t c) { return ___tolower_l(c, __get_locale()); } diff --git a/lib/libc/locale/toupper.c b/lib/libc/locale/toupper.c index d43c03761d0f..6de0c76860bd 100644 --- a/lib/libc/locale/toupper.c +++ b/lib/libc/locale/toupper.c @@ -1,78 +1,78 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include "mblocal.h" __ct_rune_t ___toupper_l(__ct_rune_t c, locale_t l) { size_t lim; FIX_LOCALE(l); _RuneRange *rr = &XLOCALE_CTYPE(l)->runes->__mapupper_ext; _RuneEntry *base, *re; if (c < 0 || c == EOF) return(c); /* Binary search -- see bsearch.c for explanation. */ base = rr->__ranges; for (lim = rr->__nranges; lim != 0; lim >>= 1) { re = base + (lim >> 1); if (re->__min <= c && c <= re->__max) { return (re->__map + c - re->__min); } else if (c > re->__max) { base = re + 1; lim--; } } return(c); } __ct_rune_t ___toupper(__ct_rune_t c) { return ___toupper_l(c, __get_locale()); } diff --git a/lib/libc/locale/uselocale.3 b/lib/libc/locale/uselocale.3 index e0eccfe676b6..269430e40da6 100644 --- a/lib/libc/locale/uselocale.3 +++ b/lib/libc/locale/uselocale.3 @@ -1,58 +1,57 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 September 17, 2011 .Dt USELOCALE 3 .Os .Sh NAME .Nm uselocale .Nd Sets a thread-local locale .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In locale.h .Ft locale_t .Fn uselocale "locale_t locale" .Sh DESCRIPTION Specifies the locale for this thread to use. Specifying .Fa LC_GLOBAL_LOCALE disables the per-thread locale, while NULL returns the current locale without setting a new one. .Sh RETURN VALUES Returns the previous locale, or LC_GLOBAL_LOCALE if this thread has no locale associated with it. .Sh SEE ALSO .Xr duplocale 3 , .Xr freelocale 3 , .Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , .Xr xlocale 3 .Sh STANDARDS This function conforms to .St -p1003.1-2008 . diff --git a/lib/libc/locale/utf8.c b/lib/libc/locale/utf8.c index d9cd94c9b3ab..3eb5f21bc3b3 100644 --- a/lib/libc/locale/utf8.c +++ b/lib/libc/locale/utf8.c @@ -1,424 +1,424 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include #include "mblocal.h" extern int __mb_sb_limit; static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); static int _UTF8_mbsinit(const mbstate_t *); static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); typedef struct { wchar_t ch; int want; wchar_t lbound; } _UTF8State; int _UTF8_init(struct xlocale_ctype *l, _RuneLocale *rl) { l->__mbrtowc = _UTF8_mbrtowc; l->__wcrtomb = _UTF8_wcrtomb; l->__mbsinit = _UTF8_mbsinit; l->__mbsnrtowcs = _UTF8_mbsnrtowcs; l->__wcsnrtombs = _UTF8_wcsnrtombs; l->runes = rl; l->__mb_cur_max = 4; /* * UCS-4 encoding used as the internal representation, so * slots 0x0080-0x00FF are occuped and must be excluded * from the single byte ctype by setting the limit. */ l->__mb_sb_limit = 128; return (0); } static int _UTF8_mbsinit(const mbstate_t *ps) { return (ps == NULL || ((const _UTF8State *)ps)->want == 0); } static size_t _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps) { _UTF8State *us; int ch, i, mask, want; wchar_t lbound, wch; us = (_UTF8State *)ps; if (us->want < 0 || us->want > 6) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) { s = ""; n = 1; pwc = NULL; } if (n == 0) /* Incomplete multibyte sequence */ return ((size_t)-2); if (us->want == 0) { /* * Determine the number of octets that make up this character * from the first octet, and a mask that extracts the * interesting bits of the first octet. We already know * the character is at least two bytes long. * * We also specify a lower bound for the character code to * detect redundant, non-"shortest form" encodings. For * example, the sequence C0 80 is _not_ a legal representation * of the null character. This enforces a 1-to-1 mapping * between character codes and their multibyte representations. */ ch = (unsigned char)*s; if ((ch & 0x80) == 0) { /* Fast path for plain ASCII characters. */ if (pwc != NULL) *pwc = ch; return (ch != '\0' ? 1 : 0); } if ((ch & 0xe0) == 0xc0) { mask = 0x1f; want = 2; lbound = 0x80; } else if ((ch & 0xf0) == 0xe0) { mask = 0x0f; want = 3; lbound = 0x800; } else if ((ch & 0xf8) == 0xf0) { mask = 0x07; want = 4; lbound = 0x10000; } else { /* * Malformed input; input is not UTF-8. */ errno = EILSEQ; return ((size_t)-1); } } else { want = us->want; lbound = us->lbound; } /* * Decode the octet sequence representing the character in chunks * of 6 bits, most significant first. */ if (us->want == 0) wch = (unsigned char)*s++ & mask; else wch = us->ch; for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) { if ((*s & 0xc0) != 0x80) { /* * Malformed input; bad characters in the middle * of a character. */ errno = EILSEQ; return ((size_t)-1); } wch <<= 6; wch |= *s++ & 0x3f; } if (i < want) { /* Incomplete multibyte sequence. */ us->want = want - i; us->lbound = lbound; us->ch = wch; return ((size_t)-2); } if (wch < lbound) { /* * Malformed input; redundant encoding. */ errno = EILSEQ; return ((size_t)-1); } if ((wch >= 0xd800 && wch <= 0xdfff) || wch > 0x10ffff) { /* * Malformed input; invalid code points. */ errno = EILSEQ; return ((size_t)-1); } if (pwc != NULL) *pwc = wch; us->want = 0; return (wch == L'\0' ? 0 : want); } static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps) { _UTF8State *us; const char *s; size_t nchr; wchar_t wc; size_t nb; us = (_UTF8State *)ps; s = *src; nchr = 0; if (dst == NULL) { /* * The fast path in the loop below is not safe if an ASCII * character appears as anything but the first byte of a * multibyte sequence. Check now to avoid doing it in the loop. */ if (nms > 0 && us->want > 0 && (signed char)*s > 0) { errno = EILSEQ; return ((size_t)-1); } for (;;) { if (nms > 0 && (signed char)*s > 0) /* * Fast path for plain ASCII characters * excluding NUL. */ nb = 1; else if ((nb = _UTF8_mbrtowc(&wc, s, nms, ps)) == (size_t)-1) /* Invalid sequence - mbrtowc() sets errno. */ return ((size_t)-1); else if (nb == 0 || nb == (size_t)-2) return (nchr); s += nb; nms -= nb; nchr++; } /*NOTREACHED*/ } /* * The fast path in the loop below is not safe if an ASCII * character appears as anything but the first byte of a * multibyte sequence. Check now to avoid doing it in the loop. */ if (nms > 0 && len > 0 && us->want > 0 && (signed char)*s > 0) { errno = EILSEQ; return ((size_t)-1); } while (len-- > 0) { if (nms > 0 && (signed char)*s > 0) { /* * Fast path for plain ASCII characters * excluding NUL. */ *dst = (wchar_t)*s; nb = 1; } else if ((nb = _UTF8_mbrtowc(dst, s, nms, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } else if (nb == (size_t)-2) { *src = s + nms; return (nchr); } else if (nb == 0) { *src = NULL; return (nchr); } s += nb; nms -= nb; nchr++; dst++; } *src = s; return (nchr); } static size_t _UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { _UTF8State *us; unsigned char lead; int i, len; us = (_UTF8State *)ps; if (us->want != 0) { errno = EINVAL; return ((size_t)-1); } if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); /* * Determine the number of octets needed to represent this character. * We always output the shortest sequence possible. Also specify the * first few bits of the first octet, which contains the information * about the sequence length. */ if ((wc & ~0x7f) == 0) { /* Fast path for plain ASCII characters. */ *s = (char)wc; return (1); } else if ((wc & ~0x7ff) == 0) { lead = 0xc0; len = 2; } else if ((wc & ~0xffff) == 0) { if (wc >= 0xd800 && wc <= 0xdfff) { errno = EILSEQ; return ((size_t)-1); } lead = 0xe0; len = 3; } else if (wc >= 0 && wc <= 0x10ffff) { lead = 0xf0; len = 4; } else { errno = EILSEQ; return ((size_t)-1); } /* * Output the octets representing the character in chunks * of 6 bits, least significant last. The first octet is * a special case because it contains the sequence length * information. */ for (i = len - 1; i > 0; i--) { s[i] = (wc & 0x3f) | 0x80; wc >>= 6; } *s = (wc & 0xff) | lead; return (len); } static size_t _UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { _UTF8State *us; char buf[MB_LEN_MAX]; const wchar_t *s; size_t nbytes; size_t nb; us = (_UTF8State *)ps; if (us->want != 0) { errno = EINVAL; return ((size_t)-1); } s = *src; nbytes = 0; if (dst == NULL) { while (nwc-- > 0) { if (0 <= *s && *s < 0x80) /* Fast path for plain ASCII characters. */ nb = 1; else if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); if (*s == L'\0') return (nbytes + nb - 1); s++; nbytes += nb; } return (nbytes); } while (len > 0 && nwc-- > 0) { if (0 <= *s && *s < 0x80) { /* Fast path for plain ASCII characters. */ nb = 1; *dst = *s; } else if (len > (size_t)MB_CUR_MAX) { /* Enough space to translate in-place. */ if ((nb = _UTF8_wcrtomb(dst, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } } else { /* * May not be enough space; use temp. buffer. */ if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } if (nb > (int)len) /* MB sequence for character won't fit. */ break; memcpy(dst, buf, nb); } if (*s == L'\0') { *src = NULL; return (nbytes + nb - 1); } s++; dst += nb; len -= nb; nbytes += nb; } *src = s; return (nbytes); } diff --git a/lib/libc/locale/wcrtomb.c b/lib/libc/locale/wcrtomb.c index 9ba0707f0723..83321e4a41c9 100644 --- a/lib/libc/locale/wcrtomb.c +++ b/lib/libc/locale/wcrtomb.c @@ -1,52 +1,52 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "mblocal.h" size_t wcrtomb_l(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->wcrtomb); return (XLOCALE_CTYPE(locale)->__wcrtomb(s, wc, ps)); } size_t wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { return wcrtomb_l(s, wc, ps, __get_locale()); } diff --git a/lib/libc/locale/wcsftime.c b/lib/libc/locale/wcsftime.c index 2b47f939c804..ce67d35846e8 100644 --- a/lib/libc/locale/wcsftime.c +++ b/lib/libc/locale/wcsftime.c @@ -1,122 +1,122 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include "xlocale_private.h" /* * Convert date and time to a wide-character string. * * This is the wide-character counterpart of strftime(). So that we do not * have to duplicate the code of strftime(), we convert the format string to * multibyte, call strftime(), then convert the result back into wide * characters. * * This technique loses in the presence of stateful multibyte encoding if any * of the conversions in the format string change conversion state. When * stateful encoding is implemented, we will need to reset the state between * format specifications in the format string. */ size_t wcsftime_l(wchar_t * __restrict wcs, size_t maxsize, const wchar_t * __restrict format, const struct tm * __restrict timeptr, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; char *dst, *sformat; const char *dstp; const wchar_t *formatp; size_t n, sflen; int sverrno; FIX_LOCALE(locale); sformat = dst = NULL; /* * Convert the supplied format string to a multibyte representation * for strftime(), which only handles single-byte characters. */ mbs = initial; formatp = format; sflen = wcsrtombs_l(NULL, &formatp, 0, &mbs, locale); if (sflen == (size_t)-1) goto error; if ((sformat = malloc(sflen + 1)) == NULL) goto error; mbs = initial; wcsrtombs_l(sformat, &formatp, sflen + 1, &mbs, locale); /* * Allocate memory for longest multibyte sequence that will fit * into the caller's buffer and call strftime() to fill it. * Then, copy and convert the result back into wide characters in * the caller's buffer. */ if (SIZE_T_MAX / MB_CUR_MAX <= maxsize) { /* maxsize is prepostorously large - avoid int. overflow. */ errno = EINVAL; goto error; } if ((dst = malloc(maxsize * MB_CUR_MAX)) == NULL) goto error; if (strftime_l(dst, maxsize, sformat, timeptr, locale) == 0) goto error; dstp = dst; mbs = initial; n = mbsrtowcs_l(wcs, &dstp, maxsize, &mbs, locale); if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) goto error; free(sformat); free(dst); return (n); error: sverrno = errno; free(sformat); free(dst); errno = sverrno; return (0); } size_t wcsftime(wchar_t * __restrict wcs, size_t maxsize, const wchar_t * __restrict format, const struct tm * __restrict timeptr) { return wcsftime_l(wcs, maxsize, format, timeptr, __get_locale()); } diff --git a/lib/libc/locale/wcsnrtombs.c b/lib/libc/locale/wcsnrtombs.c index 2a0c15fecb31..fc47c1c7cce2 100644 --- a/lib/libc/locale/wcsnrtombs.c +++ b/lib/libc/locale/wcsnrtombs.c @@ -1,125 +1,125 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2013 Garrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include "mblocal.h" size_t wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->wcsnrtombs); return (XLOCALE_CTYPE(locale)->__wcsnrtombs(dst, src, nwc, len, ps)); } size_t wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps) { return wcsnrtombs_l(dst, src, nwc, len, ps, __get_locale()); } size_t __wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps, wcrtomb_pfn_t pwcrtomb) { mbstate_t mbsbak; char buf[MB_LEN_MAX]; const wchar_t *s; size_t nbytes; size_t nb; s = *src; nbytes = 0; if (dst == NULL) { while (nwc-- > 0) { if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1) /* Invalid character - wcrtomb() sets errno. */ return ((size_t)-1); else if (*s == L'\0') return (nbytes + nb - 1); s++; nbytes += nb; } return (nbytes); } while (len > 0 && nwc-- > 0) { if (len > (size_t)MB_CUR_MAX) { /* Enough space to translate in-place. */ if ((nb = pwcrtomb(dst, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } } else { /* * May not be enough space; use temp. buffer. * * We need to save a copy of the conversion state * here so we can restore it if the multibyte * character is too long for the buffer. */ mbsbak = *ps; if ((nb = pwcrtomb(buf, *s, ps)) == (size_t)-1) { *src = s; return ((size_t)-1); } if (nb > (int)len) { /* MB sequence for character won't fit. */ *ps = mbsbak; break; } memcpy(dst, buf, nb); } if (*s == L'\0') { *src = NULL; return (nbytes + nb - 1); } s++; dst += nb; len -= nb; nbytes += nb; } *src = s; return (nbytes); } diff --git a/lib/libc/locale/wcsrtombs.c b/lib/libc/locale/wcsrtombs.c index 001b7950cd42..2e472f1a0ff9 100644 --- a/lib/libc/locale/wcsrtombs.c +++ b/lib/libc/locale/wcsrtombs.c @@ -1,56 +1,56 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include "mblocal.h" size_t wcsrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, size_t len, mbstate_t * __restrict ps, locale_t locale) { FIX_LOCALE(locale); if (ps == NULL) ps = &(XLOCALE_CTYPE(locale)->wcsrtombs); return (XLOCALE_CTYPE(locale)->__wcsnrtombs(dst, src, SIZE_T_MAX, len, ps)); } size_t wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, mbstate_t * __restrict ps) { return wcsrtombs_l(dst, src, len, ps, __get_locale()); } diff --git a/lib/libc/locale/wcstod.c b/lib/libc/locale/wcstod.c index e97ca7d219f9..570bf4474ff4 100644 --- a/lib/libc/locale/wcstod.c +++ b/lib/libc/locale/wcstod.c @@ -1,116 +1,116 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "xlocale_private.h" /* * Convert a string to a double-precision number. * * This is the wide-character counterpart of strtod(). So that we do not * have to duplicate the code of strtod() here, we convert the supplied * wide character string to multibyte and call strtod() on the result. * This assumes that the multibyte encoding is compatible with ASCII * for at least the digits, radix character and letters. */ double wcstod_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; double val; char *buf, *end; const wchar_t *wcp; size_t len; size_t spaces; FIX_LOCALE(locale); wcp = nptr; spaces = 0; while (iswspace_l(*wcp, locale)) { wcp++; spaces++; } /* * Convert the supplied numeric wide char. string to multibyte. * * We could attempt to find the end of the numeric portion of the * wide char. string to avoid converting unneeded characters but * choose not to bother; optimising the uncommon case where * the input string contains a lot of text after the number * duplicates a lot of strtod()'s functionality and slows down the * most common cases. */ mbs = initial; if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, locale)) == (size_t)-1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } if ((buf = malloc(len + 1)) == NULL) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } mbs = initial; wcsrtombs_l(buf, &wcp, len + 1, &mbs, locale); /* Let strtod() do most of the work for us. */ val = strtod_l(buf, &end, locale); /* * We only know where the number ended in the _multibyte_ * representation of the string. If the caller wants to know * where it ended, count multibyte characters to find the * corresponding position in the wide char string. */ if (endptr != NULL) { *endptr = (wchar_t *)nptr + (end - buf); if (buf != end) *endptr += spaces; } free(buf); return (val); } double wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) { return wcstod_l(nptr, endptr, __get_locale()); } diff --git a/lib/libc/locale/wcstof.c b/lib/libc/locale/wcstof.c index c2a428043798..2d35f0b82f25 100644 --- a/lib/libc/locale/wcstof.c +++ b/lib/libc/locale/wcstof.c @@ -1,93 +1,93 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002, 2003 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "xlocale_private.h" /* * See wcstod() for comments as to the logic used. */ float wcstof_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; float val; char *buf, *end; const wchar_t *wcp; size_t len; size_t spaces; FIX_LOCALE(locale); wcp = nptr; spaces = 0; while (iswspace_l(*wcp, locale)) { wcp++; spaces++; } mbs = initial; if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, locale)) == (size_t)-1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } if ((buf = malloc(len + 1)) == NULL) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } mbs = initial; wcsrtombs_l(buf, &wcp, len + 1, &mbs, locale); val = strtof_l(buf, &end, locale); if (endptr != NULL) { *endptr = (wchar_t *)nptr + (end - buf); if (buf != end) *endptr += spaces; } free(buf); return (val); } float wcstof(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) { return wcstof_l(nptr, endptr, __get_locale()); } diff --git a/lib/libc/locale/wcstoimax.c b/lib/libc/locale/wcstoimax.c index e7b1c71e5d71..259faa2b011c 100644 --- a/lib/libc/locale/wcstoimax.c +++ b/lib/libc/locale/wcstoimax.c @@ -1,140 +1,140 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif #include #include #include #include #include #include "xlocale_private.h" /* * Convert a wide character string to an intmax_t integer. */ intmax_t wcstoimax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; uintmax_t acc; wchar_t c; uintmax_t cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoimax for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX : INTMAX_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= 'a' && c <= 'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? INTMAX_MIN : INTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } intmax_t wcstoimax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstoimax_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wcstol.c b/lib/libc/locale/wcstol.c index facf2bd9ee35..b0b787384f39 100644 --- a/lib/libc/locale/wcstol.c +++ b/lib/libc/locale/wcstol.c @@ -1,133 +1,133 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to a long integer. */ long wcstol_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; unsigned long acc; wchar_t c; unsigned long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtol for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= L'a' && c <= L'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } long wcstol(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstol_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wcstold.c b/lib/libc/locale/wcstold.c index 586aa9728dea..dc15631a22f0 100644 --- a/lib/libc/locale/wcstold.c +++ b/lib/libc/locale/wcstold.c @@ -1,93 +1,93 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002, 2003 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "xlocale_private.h" /* * See wcstod() for comments as to the logic used. */ long double wcstold_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; long double val; char *buf, *end; const wchar_t *wcp; size_t len; size_t spaces; FIX_LOCALE(locale); wcp = nptr; spaces = 0; while (iswspace_l(*wcp, locale)) { wcp++; spaces++; } mbs = initial; if ((len = wcsrtombs_l(NULL, &wcp, 0, &mbs, locale)) == (size_t)-1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } if ((buf = malloc(len + 1)) == NULL) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); } mbs = initial; wcsrtombs_l(buf, &wcp, len + 1, &mbs, locale); val = strtold_l(buf, &end, locale); if (endptr != NULL) { *endptr = (wchar_t *)nptr + (end - buf); if (buf != end) *endptr += spaces; } free(buf); return (val); } long double wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) { return wcstold_l(nptr, endptr, __get_locale()); } diff --git a/lib/libc/locale/wcstoll.c b/lib/libc/locale/wcstoll.c index c8cf66c1bb01..ac07d6c6adbf 100644 --- a/lib/libc/locale/wcstoll.c +++ b/lib/libc/locale/wcstoll.c @@ -1,139 +1,139 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp "); #endif #include #include #include #include #include #include "xlocale_private.h" /* * Convert a wide character string to a long long integer. */ long long wcstoll_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; unsigned long long acc; wchar_t c; unsigned long long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoll for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= L'a' && c <= L'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LLONG_MIN : LLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } long long wcstoll(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstoll_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wcstombs.c b/lib/libc/locale/wcstombs.c index b83bc9c7273c..0b9303cd79e1 100644 --- a/lib/libc/locale/wcstombs.c +++ b/lib/libc/locale/wcstombs.c @@ -1,58 +1,58 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "mblocal.h" size_t wcstombs_l(char * __restrict s, const wchar_t * __restrict pwcs, size_t n, locale_t locale) { static const mbstate_t initial; mbstate_t mbs; const wchar_t *pwcsp; FIX_LOCALE(locale); mbs = initial; pwcsp = pwcs; return (XLOCALE_CTYPE(locale)->__wcsnrtombs(s, &pwcsp, SIZE_T_MAX, n, &mbs)); } size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) { return wcstombs_l(s, pwcs, n, __get_locale()); } diff --git a/lib/libc/locale/wcstoul.c b/lib/libc/locale/wcstoul.c index 0f6fe4152dea..9f58db799c0e 100644 --- a/lib/libc/locale/wcstoul.c +++ b/lib/libc/locale/wcstoul.c @@ -1,131 +1,131 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #include #include #include "xlocale_private.h" /* * Convert a wide character string to an unsigned long integer. */ unsigned long wcstoul_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; unsigned long acc; wchar_t c; unsigned long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtol for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULONG_MAX / base; cutlim = ULONG_MAX % base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= L'a' && c <= L'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } unsigned long wcstoul(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstoul_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wcstoull.c b/lib/libc/locale/wcstoull.c index df68c5681433..cbc7253f884d 100644 --- a/lib/libc/locale/wcstoull.c +++ b/lib/libc/locale/wcstoull.c @@ -1,138 +1,138 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp "); #endif #include #include #include #include #include #include "xlocale_private.h" /* * Convert a wide character string to an unsigned long long integer. */ unsigned long long wcstoull_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; unsigned long long acc; wchar_t c; unsigned long long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoull for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULLONG_MAX / base; cutlim = ULLONG_MAX % base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= L'a' && c <= L'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } unsigned long long wcstoull(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstoull_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wcstoumax.c b/lib/libc/locale/wcstoumax.c index d6e92f4d3305..4380cccf2424 100644 --- a/lib/libc/locale/wcstoumax.c +++ b/lib/libc/locale/wcstoumax.c @@ -1,138 +1,138 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); #endif #include #include #include #include #include #include "xlocale_private.h" /* * Convert a wide character string to a uintmax_t integer. */ uintmax_t wcstoumax_l(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base, locale_t locale) { const wchar_t *s; uintmax_t acc; wchar_t c; uintmax_t cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoimax for comments as to the logic used. */ s = nptr; do { c = *s++; } while (iswspace_l(c, locale)); if (c == L'-') { neg = 1; c = *s++; } else { neg = 0; if (c == L'+') c = *s++; } if ((base == 0 || base == 16) && c == L'0' && (*s == L'x' || *s == L'X') && ((s[1] >= L'0' && s[1] <= L'9') || (s[1] >= L'A' && s[1] <= L'F') || (s[1] >= L'a' && s[1] <= L'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == L'0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = UINTMAX_MAX / base; cutlim = UINTMAX_MAX % base; for ( ; ; c = *s++) { #ifdef notyet if (iswdigit_l(c, locale)) c = digittoint_l(c, locale); else #endif if (c >= L'0' && c <= L'9') c -= L'0'; else if (c >= L'A' && c <= L'Z') c -= L'A' - 10; else if (c >= L'a' && c <= L'z') c -= L'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = UINTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (wchar_t *)(any ? s - 1 : nptr); return (acc); } uintmax_t wcstoumax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) { return wcstoumax_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/locale/wctob.c b/lib/libc/locale/wctob.c index 2060020a9202..d3c9318cc70d 100644 --- a/lib/libc/locale/wctob.c +++ b/lib/libc/locale/wctob.c @@ -1,56 +1,56 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "mblocal.h" int wctob_l(wint_t c, locale_t locale) { static const mbstate_t initial; mbstate_t mbs = initial; char buf[MB_LEN_MAX]; FIX_LOCALE(locale); if (c == WEOF || XLOCALE_CTYPE(locale)->__wcrtomb(buf, c, &mbs) != 1) return (EOF); return ((unsigned char)*buf); } int wctob(wint_t c) { return wctob_l(c, __get_locale()); } diff --git a/lib/libc/locale/wctomb.c b/lib/libc/locale/wctomb.c index 9611488f5a92..72bce6567b76 100644 --- a/lib/libc/locale/wctomb.c +++ b/lib/libc/locale/wctomb.c @@ -1,60 +1,60 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include "mblocal.h" int wctomb_l(char *s, wchar_t wchar, locale_t locale) { static const mbstate_t initial; size_t rval; FIX_LOCALE(locale); if (s == NULL) { /* No support for state dependent encodings. */ XLOCALE_CTYPE(locale)->wctomb = initial; return (0); } if ((rval = XLOCALE_CTYPE(locale)->__wcrtomb(s, wchar, &(XLOCALE_CTYPE(locale)->wctomb))) == (size_t)-1) return (-1); return ((int)rval); } int wctomb(char *s, wchar_t wchar) { return wctomb_l(s, wchar, __get_locale()); } diff --git a/lib/libc/locale/wctrans.c b/lib/libc/locale/wctrans.c index 8b847821f6e0..947629a8bad8 100644 --- a/lib/libc/locale/wctrans.c +++ b/lib/libc/locale/wctrans.c @@ -1,101 +1,101 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include "xlocale_private.h" enum { _WCT_ERROR = 0, _WCT_TOLOWER = 1, _WCT_TOUPPER = 2 }; wint_t towctrans_l(wint_t wc, wctrans_t desc, locale_t locale) { switch (desc) { case _WCT_TOLOWER: wc = towlower_l(wc, locale); break; case _WCT_TOUPPER: wc = towupper_l(wc, locale); break; case _WCT_ERROR: default: errno = EINVAL; break; } return (wc); } wint_t towctrans(wint_t wc, wctrans_t desc) { return towctrans_l(wc, desc, __get_locale()); } /* * wctrans() calls this will a 0 locale. If this is ever modified to actually * use the locale, wctrans() must be modified to call __get_locale(). */ wctrans_t wctrans_l(const char *charclass, locale_t locale) { struct { const char *name; wctrans_t trans; } ccls[] = { { "tolower", _WCT_TOLOWER }, { "toupper", _WCT_TOUPPER }, { NULL, _WCT_ERROR }, /* Default */ }; int i; i = 0; while (ccls[i].name != NULL && strcmp(ccls[i].name, charclass) != 0) i++; if (ccls[i].trans == _WCT_ERROR) errno = EINVAL; return (ccls[i].trans); } wctrans_t wctrans(const char *charclass) { return wctrans_l(charclass, 0); } diff --git a/lib/libc/locale/wctype.c b/lib/libc/locale/wctype.c index 51065bba5ec9..a738a075f982 100644 --- a/lib/libc/locale/wctype.c +++ b/lib/libc/locale/wctype.c @@ -1,115 +1,115 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #undef iswctype int iswctype(wint_t wc, wctype_t charclass) { return (__istype(wc, charclass)); } int iswctype_l(wint_t wc, wctype_t charclass, locale_t locale) { return __istype_l(wc, charclass, locale); } /* * IMPORTANT: The 0 in the call to this function in wctype() must be changed to * __get_locale() if wctype_l() is ever modified to actually use the locale * parameter. */ wctype_t wctype_l(const char *property, locale_t locale) { const char *propnames = "alnum\0" "alpha\0" "blank\0" "cntrl\0" "digit\0" "graph\0" "lower\0" "print\0" "punct\0" "space\0" "upper\0" "xdigit\0" "ideogram\0" /* BSD extension */ "special\0" /* BSD extension */ "phonogram\0" /* BSD extension */ "number\0" /* BSD extension */ "rune\0"; /* BSD extension */ static const wctype_t propmasks[] = { _CTYPE_A|_CTYPE_N, _CTYPE_A, _CTYPE_B, _CTYPE_C, _CTYPE_D, _CTYPE_G, _CTYPE_L, _CTYPE_R, _CTYPE_P, _CTYPE_S, _CTYPE_U, _CTYPE_X, _CTYPE_I, _CTYPE_T, _CTYPE_Q, _CTYPE_N, 0xFFFFFF00L }; size_t len1, len2; const char *p; const wctype_t *q; len1 = strlen(property); q = propmasks; for (p = propnames; (len2 = strlen(p)) != 0; p += len2 + 1) { if (len1 == len2 && memcmp(property, p, len1) == 0) return (*q); q++; } return (0UL); } wctype_t wctype(const char *property) { return wctype_l(property, 0); } diff --git a/lib/libc/locale/wcwidth.c b/lib/libc/locale/wcwidth.c index f79060c52ef7..4c256033ac47 100644 --- a/lib/libc/locale/wcwidth.c +++ b/lib/libc/locale/wcwidth.c @@ -1,61 +1,61 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include #undef wcwidth int wcwidth(wchar_t wc) { return (__wcwidth(wc)); } int wcwidth_l(wchar_t wc, locale_t locale) { return (__wcwidth_l(wc, locale)); } diff --git a/lib/libc/locale/xlocale.3 b/lib/libc/locale/xlocale.3 index cea5c6f27d80..945fe9ad3b67 100644 --- a/lib/libc/locale/xlocale.3 +++ b/lib/libc/locale/xlocale.3 @@ -1,278 +1,277 @@ .\" Copyright (c) 2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by David Chisnall under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 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 September 17, 2011 .Dt XLOCALE 3 .Os .Sh NAME .Nm xlocale .Nd Thread-safe extended locale support .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In xlocale.h .Sh DESCRIPTION The extended locale support includes a set of functions for setting thread-local locales, as well convenience functions for performing locale-aware calls with a specified locale. .Pp The core of the xlocale API is the .Fa locale_t type. This is an opaque type encapsulating a locale. Instances of this can be either set as the locale for a specific thread or passed directly to the .Fa _l suffixed variants of various standard C functions. Two special .Fa locale_t values are available: .Bl -bullet -offset indent .It NULL refers to the current locale for the thread, or to the global locale if no locale has been set for this thread. .It LC_GLOBAL_LOCALE refers to the global locale. .El .Pp The global locale is the locale set with the .Xr setlocale 3 function. .Sh SEE ALSO .Xr duplocale 3 , .Xr freelocale 3 , .Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , .Xr uselocale 3 .Sh CONVENIENCE FUNCTIONS The xlocale API includes a number of .Fa _l suffixed convenience functions. These are variants of standard C functions that have been modified to take an explicit .Fa locale_t parameter as the final argument or, in the case of variadic functions, as an additional argument directly before the format string. Each of these functions accepts either NULL or LC_GLOBAL_LOCALE. In these functions, NULL refers to the C locale, rather than the thread's current locale. If you wish to use the thread's current locale, then use the unsuffixed version of the function. .Pp These functions are exposed by including .In xlocale.h .Em after including the relevant headers for the standard variant. For example, the .Xr strtol_l 3 function is exposed by including .In xlocale.h after .In stdlib.h , which defines .Xr strtol 3 . .Pp For reference, a complete list of the locale-aware functions that are available in this form, along with the headers that expose them, is provided here: .Bl -tag -width " " .It In wctype.h .Xr iswalnum_l 3 , .Xr iswalpha_l 3 , .Xr iswcntrl_l 3 , .Xr iswctype_l 3 , .Xr iswdigit_l 3 , .Xr iswgraph_l 3 , .Xr iswlower_l 3 , .Xr iswprint_l 3 , .Xr iswpunct_l 3 , .Xr iswspace_l 3 , .Xr iswupper_l 3 , .Xr iswxdigit_l 3 , .Xr towlower_l 3 , .Xr towupper_l 3 , .Xr wctype_l 3 , .It In ctype.h .Xr digittoint_l 3 , .Xr isalnum_l 3 , .Xr isalpha_l 3 , .Xr isblank_l 3 , .Xr iscntrl_l 3 , .Xr isdigit_l 3 , .Xr isgraph_l 3 , .Xr ishexnumber_l 3 , .Xr isideogram_l 3 , .Xr islower_l 3 , .Xr isnumber_l 3 , .Xr isphonogram_l 3 , .Xr isprint_l 3 , .Xr ispunct_l 3 , .Xr isrune_l 3 , .Xr isspace_l 3 , .Xr isspecial_l 3 , .Xr isupper_l 3 , .Xr isxdigit_l 3 , .Xr tolower_l 3 , .Xr toupper_l 3 .It In inttypes.h .Xr strtoimax_l 3 , .Xr strtoumax_l 3 , .Xr wcstoimax_l 3 , .Xr wcstoumax_l 3 .It In langinfo.h .Xr nl_langinfo_l 3 .It In monetary.h .Xr strfmon_l 3 .It In stdio.h .Xr asprintf_l 3 , .Xr fprintf_l 3 , .Xr fscanf_l 3 , .Xr printf_l 3 , .Xr scanf_l 3 , .Xr snprintf_l 3 , .Xr sprintf_l 3 , .Xr sscanf_l 3 , .Xr vasprintf_l 3 , .Xr vfprintf_l 3 , .Xr vfscanf_l 3 , .Xr vprintf_l 3 , .Xr vscanf_l 3 , .Xr vsnprintf_l 3 , .Xr vsprintf_l 3 , .Xr vsscanf_l 3 .It In stdlib.h .Xr atof_l 3 , .Xr atoi_l 3 , .Xr atol_l 3 , .Xr atoll_l 3 , .Xr mblen_l 3 , .Xr mbstowcs_l 3 , .Xr mbtowc_l 3 , .Xr strtod_l 3 , .Xr strtof_l 3 , .Xr strtol_l 3 , .Xr strtold_l 3 , .Xr strtoll_l 3 , .Xr strtoq_l 3 , .Xr strtoul_l 3 , .Xr strtoull_l 3 , .Xr strtouq_l 3 , .Xr wcstombs_l 3 , .Xr wctomb_l 3 .It In string.h .Xr strcoll_l 3 , .Xr strxfrm_l 3 , .Xr strcasecmp_l 3 , .Xr strcasestr_l 3 , .Xr strncasecmp_l 3 .It In time.h .Xr strftime_l 3 .Xr strptime_l 3 .It In wchar.h .Xr btowc_l 3 , .Xr fgetwc_l 3 , .Xr fgetws_l 3 , .Xr fputwc_l 3 , .Xr fputws_l 3 , .Xr fwprintf_l 3 , .Xr fwscanf_l 3 , .Xr getwc_l 3 , .Xr getwchar_l 3 , .Xr mbrlen_l 3 , .Xr mbrtowc_l 3 , .Xr mbsinit_l 3 , .Xr mbsnrtowcs_l 3 , .Xr mbsrtowcs_l 3 , .Xr putwc_l 3 , .Xr putwchar_l 3 , .Xr swprintf_l 3 , .Xr swscanf_l 3 , .Xr ungetwc_l 3 , .Xr vfwprintf_l 3 , .Xr vfwscanf_l 3 , .Xr vswprintf_l 3 , .Xr vswscanf_l 3 , .Xr vwprintf_l 3 , .Xr vwscanf_l 3 , .Xr wcrtomb_l 3 , .Xr wcscoll_l 3 , .Xr wcsftime_l 3 , .Xr wcsnrtombs_l 3 , .Xr wcsrtombs_l 3 , .Xr wcstod_l 3 , .Xr wcstof_l 3 , .Xr wcstol_l 3 , .Xr wcstold_l 3 , .Xr wcstoll_l 3 , .Xr wcstoul_l 3 , .Xr wcstoull_l 3 , .Xr wcswidth_l 3 , .Xr wcsxfrm_l 3 , .Xr wctob_l 3 , .Xr wcwidth_l 3 , .Xr wprintf_l 3 , .Xr wscanf_l 3 .It In wctype.h .Xr iswblank_l 3 , .Xr iswhexnumber_l 3 , .Xr iswideogram_l 3 , .Xr iswnumber_l 3 , .Xr iswphonogram_l 3 , .Xr iswrune_l 3 , .Xr iswspecial_l 3 , .Xr nextwctype_l 3 , .Xr towctrans_l 3 , .Xr wctrans_l 3 .It In xlocale.h .Xr localeconv_l 3 .El .Sh STANDARDS The functions conform to .St -p1003.1-2008 . .Sh HISTORY The xlocale APIs first appeared in Darwin 8.0. This implementation was written by David Chisnall, under sponsorship from the FreeBSD Foundation and first appeared in .Fx 9.1 . .Sh CAVEATS The .Xr setlocale 3 function, and others in the family, refer to the global locale. Other functions that depend on the locale, however, will take the thread-local locale if one has been set. This means that the idiom of setting the locale using .Xr setlocale 3 , calling a locale-dependent function, and then restoring the locale will not have the expected behavior if the current thread has had a locale set using .Xr uselocale 3 . You should avoid this idiom and prefer to use the .Fa _l suffixed versions instead. diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c index 6e155b91e2b0..0a95fda83aeb 100644 --- a/lib/libc/locale/xlocale.c +++ b/lib/libc/locale/xlocale.c @@ -1,381 +1,380 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. * * This software was developed by David Chisnall under sponsorship from * the FreeBSD Foundation. * * 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 #include #include #include #include "libc_private.h" #include "xlocale_private.h" /** * Each locale loader declares a global component. This is used by setlocale() * and also by xlocale with LC_GLOBAL_LOCALE.. */ extern struct xlocale_component __xlocale_global_collate; extern struct xlocale_component __xlocale_global_ctype; extern struct xlocale_component __xlocale_global_monetary; extern struct xlocale_component __xlocale_global_numeric; extern struct xlocale_component __xlocale_global_time; extern struct xlocale_component __xlocale_global_messages; /* * And another version for the statically-allocated C locale. We only have * components for the parts that are expected to be sensible. */ extern struct xlocale_component __xlocale_C_collate; extern struct xlocale_component __xlocale_C_ctype; /* * The locale for this thread. */ _Thread_local locale_t __thread_locale; /* * Flag indicating that one or more per-thread locales exist. */ int __has_thread_locale; /* * Private functions in setlocale.c. */ const char *__get_locale_env(int category); int __detect_path_locale(void); struct _xlocale __xlocale_global_locale = { {0}, { &__xlocale_global_collate, &__xlocale_global_ctype, &__xlocale_global_monetary, &__xlocale_global_numeric, &__xlocale_global_time, &__xlocale_global_messages }, 1, 0, 1, 0 }; struct _xlocale __xlocale_C_locale = { {0}, { &__xlocale_C_collate, &__xlocale_C_ctype, 0, 0, 0, 0 }, 1, 0, 1, 0 }; static void *(*constructors[])(const char *, locale_t) = { __collate_load, __ctype_load, __monetary_load, __numeric_load, __time_load, __messages_load }; static pthread_key_t locale_info_key; static int fake_tls; static locale_t thread_local_locale; static void init_key(void) { int error; error = pthread_key_create(&locale_info_key, xlocale_release); if (error == 0) { pthread_setspecific(locale_info_key, (void*)42); if (pthread_getspecific(locale_info_key) == (void*)42) { pthread_setspecific(locale_info_key, 0); } else { fake_tls = 1; } } else { fake_tls = 1; } /* At least one per-thread locale has now been set. */ __has_thread_locale = 1; __detect_path_locale(); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; static locale_t get_thread_locale(void) { _once(&once_control, init_key); return (fake_tls ? thread_local_locale : pthread_getspecific(locale_info_key)); } static void set_thread_locale(locale_t loc) { locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc; _once(&once_control, init_key); if (NULL != l) { xlocale_retain((struct xlocale_refcounted*)l); } locale_t old = get_thread_locale(); if ((NULL != old) && (l != old)) { xlocale_release((struct xlocale_refcounted*)old); } if (fake_tls) { thread_local_locale = l; } else { pthread_setspecific(locale_info_key, l); } __thread_locale = l; __set_thread_rune_locale(loc); } /** * Clean up a locale, once its reference count reaches zero. This function is * called by xlocale_release(), it should not be called directly. */ static void destruct_locale(void *l) { locale_t loc = l; for (int type=0 ; typecomponents[type]) { xlocale_release(loc->components[type]); } } if (loc->csym) { free(loc->csym); } free(l); } /** * Allocates a new, uninitialised, locale. */ static locale_t alloc_locale(void) { locale_t new = calloc(sizeof(struct _xlocale), 1); if (new == NULL) return (NULL); new->header.destructor = destruct_locale; new->monetary_locale_changed = 1; new->numeric_locale_changed = 1; return (new); } static void copyflags(locale_t new, locale_t old) { new->using_monetary_locale = old->using_monetary_locale; new->using_numeric_locale = old->using_numeric_locale; new->using_time_locale = old->using_time_locale; new->using_messages_locale = old->using_messages_locale; } static int dupcomponent(int type, locale_t base, locale_t new) { /* Always copy from the global locale, since it has mutable components. */ struct xlocale_component *src = base->components[type]; if (&__xlocale_global_locale == base) { new->components[type] = constructors[type](src->locale, new); if (new->components[type]) { strncpy(new->components[type]->locale, src->locale, ENCODING_LEN); strncpy(new->components[type]->version, src->version, XLOCALE_DEF_VERSION_LEN); } } else if (base->components[type]) { new->components[type] = xlocale_retain(base->components[type]); } else { /* If the component was NULL, return success - if base is a * valid locale then the flag indicating that this isn't * present should be set. If it isn't a valid locale, then * we're stuck anyway. */ return 1; } return (0 != new->components[type]); } /* * Public interfaces. These are the five public functions described by the * xlocale interface. */ locale_t newlocale(int mask, const char *locale, locale_t base) { locale_t orig_base; int type; const char *realLocale = locale; int useenv = 0; int success = 1; locale_t new = alloc_locale(); if (NULL == new) { return (NULL); } _once(&once_control, init_key); orig_base = base; FIX_LOCALE(base); copyflags(new, base); if (NULL == locale) { realLocale = "C"; } else if ('\0' == locale[0]) { useenv = 1; } for (type=0 ; typecomponents[type] = constructors[type](realLocale, new); if (new->components[type]) { strncpy(new->components[type]->locale, realLocale, ENCODING_LEN); } else { success = 0; break; } } else { if (!dupcomponent(type, base, new)) { success = 0; break; } } mask >>= 1; } if (0 == success) { xlocale_release(new); new = NULL; } else if (base == orig_base) { xlocale_release(base); } return (new); } locale_t duplocale(locale_t base) { locale_t new = alloc_locale(); int type; if (NULL == new) { return (NULL); } _once(&once_control, init_key); FIX_LOCALE(base); copyflags(new, base); for (type=0 ; type= XLC_LAST) return (NULL); if (mask & LC_VERSION_MASK) { if (loc->components[type]) return (loc->components[type]->version); return (""); } else { if (loc->components[type]) return (loc->components[type]->locale); return ("C"); } } /* * Installs the specified locale_t as this thread's locale. */ locale_t uselocale(locale_t loc) { locale_t old = get_thread_locale(); if (NULL != loc) { set_thread_locale(loc); } return (old ? old : LC_GLOBAL_LOCALE); } diff --git a/lib/libc/locale/xlocale_private.h b/lib/libc/locale/xlocale_private.h index 5bb9a58abb41..9137e2d2c2ef 100644 --- a/lib/libc/locale/xlocale_private.h +++ b/lib/libc/locale/xlocale_private.h @@ -1,226 +1,225 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. * * This software was developed by David Chisnall under sponsorship from * the FreeBSD Foundation. * * 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. */ #ifndef _XLOCALE_PRIVATE__H_ #define _XLOCALE_PRIVATE__H_ #include #include #include #include #include #include #include "setlocale.h" /** * The XLC_ values are indexes into the components array. They are defined in * the same order as the LC_ values in locale.h, but without the LC_ALL zero * value. Translating from LC_X to XLC_X is done by subtracting one. * * Any reordering of this enum should ensure that these invariants are not * violated. */ enum { XLC_COLLATE = 0, XLC_CTYPE, XLC_MONETARY, XLC_NUMERIC, XLC_TIME, XLC_MESSAGES, XLC_LAST }; _Static_assert(XLC_LAST - XLC_COLLATE == 6, "XLC values should be contiguous"); _Static_assert(XLC_COLLATE == LC_COLLATE - 1, "XLC_COLLATE doesn't match the LC_COLLATE value."); _Static_assert(XLC_CTYPE == LC_CTYPE - 1, "XLC_CTYPE doesn't match the LC_CTYPE value."); _Static_assert(XLC_MONETARY == LC_MONETARY - 1, "XLC_MONETARY doesn't match the LC_MONETARY value."); _Static_assert(XLC_NUMERIC == LC_NUMERIC - 1, "XLC_NUMERIC doesn't match the LC_NUMERIC value."); _Static_assert(XLC_TIME == LC_TIME - 1, "XLC_TIME doesn't match the LC_TIME value."); _Static_assert(XLC_MESSAGES == LC_MESSAGES - 1, "XLC_MESSAGES doesn't match the LC_MESSAGES value."); /** * Header used for objects that are reference counted. Objects may optionally * have a destructor associated, which is responsible for destroying the * structure. Global / static versions of the structure should have no * destructor set - they can then have their reference counts manipulated as * normal, but will not do anything with them. * * The header stores a retain count - objects are assumed to have a reference * count of 1 when they are created, but the retain count is 0. When the * retain count is less than 0, they are freed. */ struct xlocale_refcounted { /** Number of references to this component. */ long retain_count; /** Function used to destroy this component, if one is required*/ void(*destructor)(void*); }; #define XLOCALE_DEF_VERSION_LEN 12 /** * Header for a locale component. All locale components must begin with this * header. */ struct xlocale_component { struct xlocale_refcounted header; /** Name of the locale used for this component. */ char locale[ENCODING_LEN+1]; /** Version of the definition for this component. */ char version[XLOCALE_DEF_VERSION_LEN]; }; /** * xlocale structure, stores per-thread locale information. */ struct _xlocale { struct xlocale_refcounted header; /** Components for the locale. */ struct xlocale_component *components[XLC_LAST]; /** Flag indicating if components[XLC_MONETARY] has changed since the * last call to localeconv_l() with this locale. */ int monetary_locale_changed; /** Flag indicating whether this locale is actually using a locale for * LC_MONETARY (1), or if it should use the C default instead (0). */ int using_monetary_locale; /** Flag indicating if components[XLC_NUMERIC] has changed since the * last call to localeconv_l() with this locale. */ int numeric_locale_changed; /** Flag indicating whether this locale is actually using a locale for * LC_NUMERIC (1), or if it should use the C default instead (0). */ int using_numeric_locale; /** Flag indicating whether this locale is actually using a locale for * LC_TIME (1), or if it should use the C default instead (0). */ int using_time_locale; /** Flag indicating whether this locale is actually using a locale for * LC_MESSAGES (1), or if it should use the C default instead (0). */ int using_messages_locale; /** The structure to be returned from localeconv_l() for this locale. */ struct lconv lconv; /** Buffer used by nl_langinfo_l() */ char *csym; }; /** * Increments the reference count of a reference-counted structure. */ __attribute__((unused)) static void* xlocale_retain(void *val) { struct xlocale_refcounted *obj = val; atomic_add_long(&(obj->retain_count), 1); return (val); } /** * Decrements the reference count of a reference-counted structure, freeing it * if this is the last reference, calling its destructor if it has one. */ __attribute__((unused)) static void xlocale_release(void *val) { struct xlocale_refcounted *obj = val; long count; count = atomic_fetchadd_long(&(obj->retain_count), -1) - 1; if (count < 0 && obj->destructor != NULL) obj->destructor(obj); } /** * Load functions. Each takes the name of a locale and a pointer to the data * to be initialised as arguments. Two special values are allowed for the */ extern void* __collate_load(const char*, locale_t); extern void* __ctype_load(const char*, locale_t); extern void* __messages_load(const char*, locale_t); extern void* __monetary_load(const char*, locale_t); extern void* __numeric_load(const char*, locale_t); extern void* __time_load(const char*, locale_t); extern struct _xlocale __xlocale_global_locale; extern struct _xlocale __xlocale_C_locale; /** * Caches the rune table in TLS for fast access. */ void __set_thread_rune_locale(locale_t loc); /** * Flag indicating whether a per-thread locale has been set. If no per-thread * locale has ever been set, then we always use the global locale. */ extern int __has_thread_locale; /** * The per-thread locale. Avoids the need to use pthread lookup functions when * getting the per-thread locale. */ extern _Thread_local locale_t __thread_locale; /** * Returns the current locale for this thread, or the global locale if none is * set. The caller does not have to free the locale. The return value from * this call is not guaranteed to remain valid after the locale changes. As * such, this should only be called within libc functions. */ static inline locale_t __get_locale(void) { if (!__has_thread_locale) { return (&__xlocale_global_locale); } return (__thread_locale ? __thread_locale : &__xlocale_global_locale); } /** * Two magic values are allowed for locale_t objects. NULL and -1. This * function maps those to the real locales that they represent. */ static inline locale_t get_real_locale(locale_t locale) { switch ((intptr_t)locale) { case 0: return (&__xlocale_C_locale); case -1: return (&__xlocale_global_locale); default: return (locale); } } /** * Replace a placeholder locale with the real global or thread-local locale_t. */ #define FIX_LOCALE(l) (l = get_real_locale(l)) #endif diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index 7e2b81a9e925..791755ceb14d 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -1,2234 +1,2234 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * This code is derived from software contributed to Berkeley by * Henry Spencer. * * 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. * * @(#)regcomp.c 8.5 (Berkeley) 3/20/94 */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)regcomp.c 8.5 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include #include #ifndef LIBREGEX #include "collate.h" #endif #include "utils.h" #include "regex2.h" #include "cname.h" /* * Branching context, used to keep track of branch state for all of the branch- * aware functions. In addition to keeping track of branch positions for the * p_branch_* functions, we use this to simplify some clumsiness in BREs for * detection of whether ^ is acting as an anchor or being used erroneously and * also for whether we're in a sub-expression or not. */ struct branchc { sopno start; sopno back; sopno fwd; int nbranch; int nchain; bool outer; bool terminate; }; /* * parse structure, passed up and down to avoid global variables and * other clumsinesses */ struct parse { const char *next; /* next character in RE */ const char *end; /* end of string (-> NUL normally) */ int error; /* has an error been seen? */ int gnuext; sop *strip; /* malloced strip */ sopno ssize; /* malloced strip size (allocated) */ sopno slen; /* malloced strip length (used) */ int ncsalloc; /* number of csets allocated */ struct re_guts *g; # define NPAREN 10 /* we need to remember () 1-9 for back refs */ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ sopno pend[NPAREN]; /* -> ) ([0] unused) */ bool allowbranch; /* can this expression branch? */ bool bre; /* convenience; is this a BRE? */ int pflags; /* other parsing flags -- legacy escapes? */ bool (*parse_expr)(struct parse *, struct branchc *); void (*pre_parse)(struct parse *, struct branchc *); void (*post_parse)(struct parse *, struct branchc *); }; #define PFLAG_LEGACY_ESC 0x00000001 /* ========= begin header generated by ./mkh ========= */ #ifdef __cplusplus extern "C" { #endif /* === regcomp.c === */ static bool p_ere_exp(struct parse *p, struct branchc *bc); static void p_str(struct parse *p); static int p_branch_eat_delim(struct parse *p, struct branchc *bc); static void p_branch_ins_offset(struct parse *p, struct branchc *bc); static void p_branch_fix_tail(struct parse *p, struct branchc *bc); static bool p_branch_empty(struct parse *p, struct branchc *bc); static bool p_branch_do(struct parse *p, struct branchc *bc); static void p_bre_pre_parse(struct parse *p, struct branchc *bc); static void p_bre_post_parse(struct parse *p, struct branchc *bc); static void p_re(struct parse *p, int end1, int end2); static bool p_simp_re(struct parse *p, struct branchc *bc); static int p_count(struct parse *p); static void p_bracket(struct parse *p); static int p_range_cmp(wchar_t c1, wchar_t c2); static void p_b_term(struct parse *p, cset *cs); static int p_b_pseudoclass(struct parse *p, char c); static void p_b_cclass(struct parse *p, cset *cs); static void p_b_cclass_named(struct parse *p, cset *cs, const char[]); static void p_b_eclass(struct parse *p, cset *cs); static wint_t p_b_symbol(struct parse *p); static wint_t p_b_coll_elem(struct parse *p, wint_t endc); static bool may_escape(struct parse *p, const wint_t ch); static wint_t othercase(wint_t ch); static void bothcases(struct parse *p, wint_t ch); static void ordinary(struct parse *p, wint_t ch); static void nonnewline(struct parse *p); static void repeat(struct parse *p, sopno start, int from, int to); static int seterr(struct parse *p, int e); static cset *allocset(struct parse *p); static void freeset(struct parse *p, cset *cs); static void CHadd(struct parse *p, cset *cs, wint_t ch); static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max); static void CHaddtype(struct parse *p, cset *cs, wctype_t wct); static wint_t singleton(cset *cs); static sopno dupl(struct parse *p, sopno start, sopno finish); static void doemit(struct parse *p, sop op, size_t opnd); static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); static void dofwd(struct parse *p, sopno pos, sop value); static int enlarge(struct parse *p, sopno size); static void stripsnug(struct parse *p, struct re_guts *g); static void findmust(struct parse *p, struct re_guts *g); static int altoffset(sop *scan, int offset); static void computejumps(struct parse *p, struct re_guts *g); static void computematchjumps(struct parse *p, struct re_guts *g); static sopno pluscount(struct parse *p, struct re_guts *g); static wint_t wgetnext(struct parse *p); #ifdef __cplusplus } #endif /* ========= end header generated by ./mkh ========= */ static char nuls[10]; /* place to point scanner in event of error */ /* * macros for use with parse structure * BEWARE: these know that the parse structure is named `p' !!! */ #define PEEK() (*p->next) #define PEEK2() (*(p->next+1)) #define MORE() (p->end - p->next > 0) #define MORE2() (p->end - p->next > 1) #define SEE(c) (MORE() && PEEK() == (c)) #define SEETWO(a, b) (MORE2() && PEEK() == (a) && PEEK2() == (b)) #define SEESPEC(a) (p->bre ? SEETWO('\\', a) : SEE(a)) #define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) #define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) #define EATSPEC(a) (p->bre ? EATTWO('\\', a) : EAT(a)) #define NEXT() (p->next++) #define NEXT2() (p->next += 2) #define NEXTn(n) (p->next += (n)) #define GETNEXT() (*p->next++) #define WGETNEXT() wgetnext(p) #define SETERROR(e) seterr(p, (e)) #define REQUIRE(co, e) ((co) || SETERROR(e)) #define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) #define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) #define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) #define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) #define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) #define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) #define ASTERN(sop, pos) EMIT(sop, HERE()-pos) #define HERE() (p->slen) #define THERE() (p->slen - 1) #define THERETHERE() (p->slen - 2) #define DROP(n) (p->slen -= (n)) /* Macro used by computejump()/computematchjump() */ #define MIN(a,b) ((a)<(b)?(a):(b)) static int /* 0 success, otherwise REG_something */ regcomp_internal(regex_t * __restrict preg, const char * __restrict pattern, int cflags, int pflags) { struct parse pa; struct re_guts *g; struct parse *p = &pa; int i; size_t len; size_t maxlen; #ifdef REDEBUG # define GOODFLAGS(f) (f) #else # define GOODFLAGS(f) ((f)&~REG_DUMP) #endif cflags = GOODFLAGS(cflags); if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) return(REG_INVARG); if (cflags®_PEND) { if (preg->re_endp < pattern) return(REG_INVARG); len = preg->re_endp - pattern; } else len = strlen(pattern); /* do the mallocs early so failure handling is easy */ g = (struct re_guts *)malloc(sizeof(struct re_guts)); if (g == NULL) return(REG_ESPACE); /* * Limit the pattern space to avoid a 32-bit overflow on buffer * extension. Also avoid any signed overflow in case of conversion * so make the real limit based on a 31-bit overflow. * * Likely not applicable on 64-bit systems but handle the case * generically (who are we to stop people from using ~715MB+ * patterns?). */ maxlen = ((size_t)-1 >> 1) / sizeof(sop) * 2 / 3; if (len >= maxlen) { free((char *)g); return(REG_ESPACE); } p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ assert(p->ssize >= len); p->strip = (sop *)malloc(p->ssize * sizeof(sop)); p->slen = 0; if (p->strip == NULL) { free((char *)g); return(REG_ESPACE); } /* set things up */ p->g = g; p->next = pattern; /* convenience; we do not modify it */ p->end = p->next + len; p->error = 0; p->ncsalloc = 0; p->pflags = pflags; for (i = 0; i < NPAREN; i++) { p->pbegin[i] = 0; p->pend[i] = 0; } #ifdef LIBREGEX if (cflags®_POSIX) { p->gnuext = false; p->allowbranch = (cflags & REG_EXTENDED) != 0; } else p->gnuext = p->allowbranch = true; #else p->gnuext = false; p->allowbranch = (cflags & REG_EXTENDED) != 0; #endif if (cflags & REG_EXTENDED) { p->bre = false; p->parse_expr = p_ere_exp; p->pre_parse = NULL; p->post_parse = NULL; } else { p->bre = true; p->parse_expr = p_simp_re; p->pre_parse = p_bre_pre_parse; p->post_parse = p_bre_post_parse; } g->sets = NULL; g->ncsets = 0; g->cflags = cflags; g->iflags = 0; g->nbol = 0; g->neol = 0; g->must = NULL; g->moffset = -1; g->charjump = NULL; g->matchjump = NULL; g->mlen = 0; g->nsub = 0; g->backrefs = 0; /* do it */ EMIT(OEND, 0); g->firststate = THERE(); if (cflags & REG_NOSPEC) p_str(p); else p_re(p, OUT, OUT); EMIT(OEND, 0); g->laststate = THERE(); /* tidy up loose ends and fill things in */ stripsnug(p, g); findmust(p, g); /* only use Boyer-Moore algorithm if the pattern is bigger * than three characters */ if(g->mlen > 3) { computejumps(p, g); computematchjumps(p, g); if(g->matchjump == NULL && g->charjump != NULL) { free(g->charjump); g->charjump = NULL; } } g->nplus = pluscount(p, g); g->magic = MAGIC2; preg->re_nsub = g->nsub; preg->re_g = g; preg->re_magic = MAGIC1; #ifndef REDEBUG /* not debugging, so can't rely on the assert() in regexec() */ if (g->iflags&BAD) SETERROR(REG_ASSERT); #endif /* win or lose, we're done */ if (p->error != 0) /* lose */ regfree(preg); return(p->error); } /* - regcomp - interface for parser and compilation = extern int regcomp(regex_t *, const char *, int); = #define REG_BASIC 0000 = #define REG_EXTENDED 0001 = #define REG_ICASE 0002 = #define REG_NOSUB 0004 = #define REG_NEWLINE 0010 = #define REG_NOSPEC 0020 = #define REG_PEND 0040 = #define REG_DUMP 0200 */ int /* 0 success, otherwise REG_something */ regcomp(regex_t * __restrict preg, const char * __restrict pattern, int cflags) { return (regcomp_internal(preg, pattern, cflags, 0)); } #ifndef LIBREGEX /* * Legacy interface that requires more lax escaping behavior. */ int freebsd12_regcomp(regex_t * __restrict preg, const char * __restrict pattern, int cflags, int pflags) { return (regcomp_internal(preg, pattern, cflags, PFLAG_LEGACY_ESC)); } __sym_compat(regcomp, freebsd12_regcomp, FBSD_1.0); #endif /* !LIBREGEX */ /* - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op, - return whether we should terminate or not == static bool p_ere_exp(struct parse *p); */ static bool p_ere_exp(struct parse *p, struct branchc *bc) { char c; wint_t wc; sopno pos; int count; int count2; #ifdef LIBREGEX int i; int handled; #endif sopno subno; int wascaret = 0; (void)bc; assert(MORE()); /* caller should have ensured this */ c = GETNEXT(); #ifdef LIBREGEX handled = 0; #endif pos = HERE(); switch (c) { case '(': (void)REQUIRE(MORE(), REG_EPAREN); p->g->nsub++; subno = p->g->nsub; if (subno < NPAREN) p->pbegin[subno] = HERE(); EMIT(OLPAREN, subno); if (!SEE(')')) p_re(p, ')', IGN); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); } EMIT(ORPAREN, subno); (void)MUSTEAT(')', REG_EPAREN); break; #ifndef POSIX_MISTAKE case ')': /* happens only if no current unmatched ( */ /* * You may ask, why the ifndef? Because I didn't notice * this until slightly too late for 1003.2, and none of the * other 1003.2 regular-expression reviewers noticed it at * all. So an unmatched ) is legal POSIX, at least until * we can get it fixed. */ SETERROR(REG_EPAREN); break; #endif case '^': EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; wascaret = 1; break; case '$': EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; break; case '|': SETERROR(REG_EMPTY); break; case '*': case '+': case '?': case '{': SETERROR(REG_BADRPT); break; case '.': if (p->g->cflags®_NEWLINE) nonnewline(p); else EMIT(OANY, 0); break; case '[': p_bracket(p); break; case '\\': (void)REQUIRE(MORE(), REG_EESCAPE); wc = WGETNEXT(); #ifdef LIBREGEX if (p->gnuext) { handled = 1; switch (wc) { case '`': EMIT(OBOS, 0); break; case '\'': EMIT(OEOS, 0); break; case 'B': EMIT(ONWBND, 0); break; case 'b': EMIT(OWBND, 0); break; case 'W': case 'w': case 'S': case 's': p_b_pseudoclass(p, wc); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i = wc - '0'; assert(i < NPAREN); if (p->pend[i] != 0) { assert(i <= p->g->nsub); EMIT(OBACK_, i); assert(p->pbegin[i] != 0); assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); assert(OP(p->strip[p->pend[i]]) == ORPAREN); (void) dupl(p, p->pbegin[i]+1, p->pend[i]); EMIT(O_BACK, i); } else SETERROR(REG_ESUBREG); p->g->backrefs = 1; break; default: handled = 0; } /* Don't proceed to the POSIX bits if we've already handled it */ if (handled) break; } #endif switch (wc) { case '<': EMIT(OBOW, 0); break; case '>': EMIT(OEOW, 0); break; default: if (may_escape(p, wc)) ordinary(p, wc); else SETERROR(REG_EESCAPE); break; } break; default: if (p->error != 0) return (false); p->next--; wc = WGETNEXT(); ordinary(p, wc); break; } if (!MORE()) return (false); c = PEEK(); /* we call { a repetition if followed by a digit */ if (!( c == '*' || c == '+' || c == '?' || c == '{')) return (false); /* no repetition, we're done */ else if (c == '{') (void)REQUIRE(MORE2() && \ (isdigit((uch)PEEK2()) || PEEK2() == ','), REG_BADRPT); NEXT(); (void)REQUIRE(!wascaret, REG_BADRPT); switch (c) { case '*': /* implemented as +? */ /* this case does not require the (y|) trick, noKLUDGE */ INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); break; case '+': INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); break; case '?': /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, pos); /* offset slightly wrong */ ASTERN(OOR1, pos); /* this one's right */ AHEAD(pos); /* fix the OCH_ */ EMIT(OOR2, 0); /* offset very wrong... */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); break; case '{': count = p_count(p); if (EAT(',')) { if (isdigit((uch)PEEK())) { count2 = p_count(p); (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ count2 = count; repeat(p, pos, count, count2); if (!EAT('}')) { /* error heuristics */ while (MORE() && PEEK() != '}') NEXT(); (void)REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } break; } if (!MORE()) return (false); c = PEEK(); if (!( c == '*' || c == '+' || c == '?' || (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) ) return (false); SETERROR(REG_BADRPT); return (false); } /* - p_str - string (no metacharacters) "parser" == static void p_str(struct parse *p); */ static void p_str(struct parse *p) { (void)REQUIRE(MORE(), REG_EMPTY); while (MORE()) ordinary(p, WGETNEXT()); } /* * Eat consecutive branch delimiters for the kind of expression that we are * parsing, return the number of delimiters that we ate. */ static int p_branch_eat_delim(struct parse *p, struct branchc *bc) { int nskip; (void)bc; nskip = 0; while (EATSPEC('|')) ++nskip; return (nskip); } /* * Insert necessary branch book-keeping operations. This emits a * bogus 'next' offset, since we still have more to parse */ static void p_branch_ins_offset(struct parse *p, struct branchc *bc) { if (bc->nbranch == 0) { INSERT(OCH_, bc->start); /* offset is wrong */ bc->fwd = bc->start; bc->back = bc->start; } ASTERN(OOR1, bc->back); bc->back = THERE(); AHEAD(bc->fwd); /* fix previous offset */ bc->fwd = HERE(); EMIT(OOR2, 0); /* offset is very wrong */ ++bc->nbranch; } /* * Fix the offset of the tail branch, if we actually had any branches. * This is to correct the bogus placeholder offset that we use. */ static void p_branch_fix_tail(struct parse *p, struct branchc *bc) { /* Fix bogus offset at the tail if we actually have branches */ if (bc->nbranch > 0) { AHEAD(bc->fwd); ASTERN(O_CH, bc->back); } } /* * Signal to the parser that an empty branch has been encountered; this will, * in the future, be used to allow for more permissive behavior with empty * branches. The return value should indicate whether parsing may continue * or not. */ static bool p_branch_empty(struct parse *p, struct branchc *bc) { (void)bc; SETERROR(REG_EMPTY); return (false); } /* * Take care of any branching requirements. This includes inserting the * appropriate branching instructions as well as eating all of the branch * delimiters until we either run out of pattern or need to parse more pattern. */ static bool p_branch_do(struct parse *p, struct branchc *bc) { int ate = 0; ate = p_branch_eat_delim(p, bc); if (ate == 0) return (false); else if ((ate > 1 || (bc->outer && !MORE())) && !p_branch_empty(p, bc)) /* * Halt parsing only if we have an empty branch and p_branch_empty * indicates that we must not continue. In the future, this will not * necessarily be an error. */ return (false); p_branch_ins_offset(p, bc); return (true); } static void p_bre_pre_parse(struct parse *p, struct branchc *bc) { (void) bc; /* * Does not move cleanly into expression parser because of * ordinary interpration of * at the beginning position of * an expression. */ if (EAT('^')) { EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; } } static void p_bre_post_parse(struct parse *p, struct branchc *bc) { /* Expression is terminating due to EOL token */ if (bc->terminate) { DROP(1); EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; } } /* - p_re - Top level parser, concatenation and BRE anchoring == static void p_re(struct parse *p, int end1, int end2); * Giving end1 as OUT essentially eliminates the end1/end2 check. * * This implementation is a bit of a kludge, in that a trailing $ is first * taken as an ordinary character and then revised to be an anchor. * The amount of lookahead needed to avoid this kludge is excessive. */ static void p_re(struct parse *p, int end1, /* first terminating character */ int end2) /* second terminating character; ignored for EREs */ { struct branchc bc; bc.nbranch = 0; if (end1 == OUT && end2 == OUT) bc.outer = true; else bc.outer = false; #define SEEEND() (!p->bre ? SEE(end1) : SEETWO(end1, end2)) for (;;) { bc.start = HERE(); bc.nchain = 0; bc.terminate = false; if (p->pre_parse != NULL) p->pre_parse(p, &bc); while (MORE() && (!p->allowbranch || !SEESPEC('|')) && !SEEEND()) { bc.terminate = p->parse_expr(p, &bc); ++bc.nchain; } if (p->post_parse != NULL) p->post_parse(p, &bc); (void) REQUIRE(p->gnuext || HERE() != bc.start, REG_EMPTY); #ifdef LIBREGEX if (HERE() == bc.start && !p_branch_empty(p, &bc)) break; #endif if (!p->allowbranch) break; /* * p_branch_do's return value indicates whether we should * continue parsing or not. This is both for correctness and * a slight optimization, because it will check if we've * encountered an empty branch or the end of the string * immediately following a branch delimiter. */ if (!p_branch_do(p, &bc)) break; } #undef SEE_END if (p->allowbranch) p_branch_fix_tail(p, &bc); assert(!MORE() || SEE(end1)); } /* - p_simp_re - parse a simple RE, an atom possibly followed by a repetition == static bool p_simp_re(struct parse *p, struct branchc *bc); */ static bool /* was the simple RE an unbackslashed $? */ p_simp_re(struct parse *p, struct branchc *bc) { int c; int cc; /* convenient/control character */ int count; int count2; sopno pos; bool handled; int i; wint_t wc; sopno subno; # define BACKSL (1<gnuext) { handled = true; switch (c) { case BACKSL|'`': EMIT(OBOS, 0); break; case BACKSL|'\'': EMIT(OEOS, 0); break; case BACKSL|'B': EMIT(ONWBND, 0); break; case BACKSL|'b': EMIT(OWBND, 0); break; case BACKSL|'W': case BACKSL|'w': case BACKSL|'S': case BACKSL|'s': p_b_pseudoclass(p, cc); break; default: handled = false; } } #endif } if (!handled) { switch (c) { case '.': if (p->g->cflags®_NEWLINE) nonnewline(p); else EMIT(OANY, 0); break; case '[': p_bracket(p); break; case BACKSL|'<': EMIT(OBOW, 0); break; case BACKSL|'>': EMIT(OEOW, 0); break; case BACKSL|'{': SETERROR(REG_BADRPT); break; case BACKSL|'(': p->g->nsub++; subno = p->g->nsub; if (subno < NPAREN) p->pbegin[subno] = HERE(); EMIT(OLPAREN, subno); /* the MORE here is an error heuristic */ if (MORE() && !SEETWO('\\', ')')) p_re(p, '\\', ')'); if (subno < NPAREN) { p->pend[subno] = HERE(); assert(p->pend[subno] != 0); } EMIT(ORPAREN, subno); (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN); break; case BACKSL|')': /* should not get here -- must be user */ SETERROR(REG_EPAREN); break; case BACKSL|'1': case BACKSL|'2': case BACKSL|'3': case BACKSL|'4': case BACKSL|'5': case BACKSL|'6': case BACKSL|'7': case BACKSL|'8': case BACKSL|'9': i = (c&~BACKSL) - '0'; assert(i < NPAREN); if (p->pend[i] != 0) { assert(i <= p->g->nsub); EMIT(OBACK_, i); assert(p->pbegin[i] != 0); assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); assert(OP(p->strip[p->pend[i]]) == ORPAREN); (void) dupl(p, p->pbegin[i]+1, p->pend[i]); EMIT(O_BACK, i); } else SETERROR(REG_ESUBREG); p->g->backrefs = 1; break; case '*': /* * Ordinary if used as the first character beyond BOL anchor of * a (sub-)expression, counts as a bad repetition operator if it * appears otherwise. */ (void)REQUIRE(bc->nchain == 0, REG_BADRPT); /* FALLTHROUGH */ default: if (p->error != 0) return (false); /* Definitely not $... */ p->next--; wc = WGETNEXT(); if ((c & BACKSL) == 0 || may_escape(p, wc)) ordinary(p, wc); else SETERROR(REG_EESCAPE); break; } } if (EAT('*')) { /* implemented as +? */ /* this case does not require the (y|) trick, noKLUDGE */ INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); #ifdef LIBREGEX } else if (p->gnuext && EATTWO('\\', '?')) { INSERT(OQUEST_, pos); ASTERN(O_QUEST, pos); } else if (p->gnuext && EATTWO('\\', '+')) { INSERT(OPLUS_, pos); ASTERN(O_PLUS, pos); #endif } else if (EATTWO('\\', '{')) { count = p_count(p); if (EAT(',')) { if (MORE() && isdigit((uch)PEEK())) { count2 = p_count(p); (void)REQUIRE(count <= count2, REG_BADBR); } else /* single number with comma */ count2 = INFINITY; } else /* just a single number */ count2 = count; repeat(p, pos, count, count2); if (!EATTWO('\\', '}')) { /* error heuristics */ while (MORE() && !SEETWO('\\', '}')) NEXT(); (void)REQUIRE(MORE(), REG_EBRACE); SETERROR(REG_BADBR); } } else if (c == '$') /* $ (but not \$) ends it */ return (true); return (false); } /* - p_count - parse a repetition count == static int p_count(struct parse *p); */ static int /* the value */ p_count(struct parse *p) { int count = 0; int ndigits = 0; while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { count = count*10 + (GETNEXT() - '0'); ndigits++; } (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); return(count); } /* - p_bracket - parse a bracketed character list == static void p_bracket(struct parse *p); */ static void p_bracket(struct parse *p) { cset *cs; wint_t ch; /* Dept of Truly Sickening Special-Case Kludges */ if (p->end - p->next > 5) { if (strncmp(p->next, "[:<:]]", 6) == 0) { EMIT(OBOW, 0); NEXTn(6); return; } if (strncmp(p->next, "[:>:]]", 6) == 0) { EMIT(OEOW, 0); NEXTn(6); return; } } if ((cs = allocset(p)) == NULL) return; if (p->g->cflags®_ICASE) cs->icase = 1; if (EAT('^')) cs->invert = 1; if (EAT(']')) CHadd(p, cs, ']'); else if (EAT('-')) CHadd(p, cs, '-'); while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) p_b_term(p, cs); if (EAT('-')) CHadd(p, cs, '-'); (void)MUSTEAT(']', REG_EBRACK); if (p->error != 0) /* don't mess things up further */ return; if (cs->invert && p->g->cflags®_NEWLINE) cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); if ((ch = singleton(cs)) != OUT) { /* optimize singleton sets */ ordinary(p, ch); freeset(p, cs); } else EMIT(OANYOF, (int)(cs - p->g->sets)); } static int p_range_cmp(wchar_t c1, wchar_t c2) { #ifndef LIBREGEX return __wcollate_range_cmp(c1, c2); #else /* Copied from libc/collate __wcollate_range_cmp */ wchar_t s1[2], s2[2]; s1[0] = c1; s1[1] = L'\0'; s2[0] = c2; s2[1] = L'\0'; return (wcscoll(s1, s2)); #endif } /* - p_b_term - parse one term of a bracketed character list == static void p_b_term(struct parse *p, cset *cs); */ static void p_b_term(struct parse *p, cset *cs) { char c; wint_t start, finish; wint_t i; #ifndef LIBREGEX struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; #endif /* classify what we've got */ switch ((MORE()) ? PEEK() : '\0') { case '[': c = (MORE2()) ? PEEK2() : '\0'; break; case '-': SETERROR(REG_ERANGE); return; /* NOTE RETURN */ default: c = '\0'; break; } switch (c) { case ':': /* character class */ NEXT2(); (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE); p_b_cclass(p, cs); (void)REQUIRE(MORE(), REG_EBRACK); (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE); break; case '=': /* equivalence class */ NEXT2(); (void)REQUIRE(MORE(), REG_EBRACK); c = PEEK(); (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE); p_b_eclass(p, cs); (void)REQUIRE(MORE(), REG_EBRACK); (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); break; default: /* symbol, ordinary character, or range */ start = p_b_symbol(p); if (SEE('-') && MORE2() && PEEK2() != ']') { /* range */ NEXT(); if (EAT('-')) finish = '-'; else finish = p_b_symbol(p); } else finish = start; if (start == finish) CHadd(p, cs, start); else { #ifndef LIBREGEX if (table->__collate_load_error || MB_CUR_MAX > 1) { #else if (MB_CUR_MAX > 1) { #endif (void)REQUIRE(start <= finish, REG_ERANGE); CHaddrange(p, cs, start, finish); } else { (void)REQUIRE(p_range_cmp(start, finish) <= 0, REG_ERANGE); for (i = 0; i <= UCHAR_MAX; i++) { if (p_range_cmp(start, i) <= 0 && p_range_cmp(i, finish) <= 0 ) CHadd(p, cs, i); } } } break; } } /* - p_b_pseudoclass - parse a pseudo-class (\w, \W, \s, \S) == static int p_b_pseudoclass(struct parse *p, char c) */ static int p_b_pseudoclass(struct parse *p, char c) { cset *cs; if ((cs = allocset(p)) == NULL) return(0); if (p->g->cflags®_ICASE) cs->icase = 1; switch (c) { case 'W': cs->invert = 1; /* PASSTHROUGH */ case 'w': p_b_cclass_named(p, cs, "alnum"); break; case 'S': cs->invert = 1; /* PASSTHROUGH */ case 's': p_b_cclass_named(p, cs, "space"); break; default: return(0); } EMIT(OANYOF, (int)(cs - p->g->sets)); return(1); } /* - p_b_cclass - parse a character-class name and deal with it == static void p_b_cclass(struct parse *p, cset *cs); */ static void p_b_cclass(struct parse *p, cset *cs) { const char *sp = p->next; size_t len; char clname[16]; while (MORE() && isalpha((uch)PEEK())) NEXT(); len = p->next - sp; if (len >= sizeof(clname) - 1) { SETERROR(REG_ECTYPE); return; } memcpy(clname, sp, len); clname[len] = '\0'; p_b_cclass_named(p, cs, clname); } /* - p_b_cclass_named - deal with a named character class == static void p_b_cclass_named(struct parse *p, cset *cs, const char []); */ static void p_b_cclass_named(struct parse *p, cset *cs, const char clname[]) { wctype_t wct; if ((wct = wctype(clname)) == 0) { SETERROR(REG_ECTYPE); return; } CHaddtype(p, cs, wct); } /* - p_b_eclass - parse an equivalence-class name and deal with it == static void p_b_eclass(struct parse *p, cset *cs); * * This implementation is incomplete. xxx */ static void p_b_eclass(struct parse *p, cset *cs) { wint_t c; c = p_b_coll_elem(p, '='); CHadd(p, cs, c); } /* - p_b_symbol - parse a character or [..]ed multicharacter collating symbol == static wint_t p_b_symbol(struct parse *p); */ static wint_t /* value of symbol */ p_b_symbol(struct parse *p) { wint_t value; (void)REQUIRE(MORE(), REG_EBRACK); if (!EATTWO('[', '.')) return(WGETNEXT()); /* collating symbol */ value = p_b_coll_elem(p, '.'); (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); return(value); } /* - p_b_coll_elem - parse a collating-element name and look it up == static wint_t p_b_coll_elem(struct parse *p, wint_t endc); */ static wint_t /* value of collating element */ p_b_coll_elem(struct parse *p, wint_t endc) /* name ended by endc,']' */ { const char *sp = p->next; struct cname *cp; mbstate_t mbs; wchar_t wc; size_t clen, len; while (MORE() && !SEETWO(endc, ']')) NEXT(); if (!MORE()) { SETERROR(REG_EBRACK); return(0); } len = p->next - sp; for (cp = cnames; cp->name != NULL; cp++) if (strncmp(cp->name, sp, len) == 0 && strlen(cp->name) == len) return(cp->code); /* known name */ memset(&mbs, 0, sizeof(mbs)); if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) return (wc); /* single character */ else if (clen == (size_t)-1 || clen == (size_t)-2) SETERROR(REG_ILLSEQ); else SETERROR(REG_ECOLLATE); /* neither */ return(0); } /* - may_escape - determine whether 'ch' is escape-able in the current context == static int may_escape(struct parse *p, const wint_t ch) */ static bool may_escape(struct parse *p, const wint_t ch) { if ((p->pflags & PFLAG_LEGACY_ESC) != 0) return (true); if (isalpha(ch) || ch == '\'' || ch == '`') return (false); return (true); #ifdef NOTYET /* * Build a whitelist of characters that may be escaped to produce an * ordinary in the current context. This assumes that these have not * been otherwise interpreted as a special character. Escaping an * ordinary character yields undefined results according to * IEEE 1003.1-2008. Some extensions (notably, some GNU extensions) take * advantage of this and use escaped ordinary characters to provide * special meaning, e.g. \b, \B, \w, \W, \s, \S. */ switch(ch) { case '|': case '+': case '?': /* The above characters may not be escaped in BREs */ if (!(p->g->cflags®_EXTENDED)) return (false); /* Fallthrough */ case '(': case ')': case '{': case '}': case '.': case '[': case ']': case '\\': case '*': case '^': case '$': return (true); default: return (false); } #endif } /* - othercase - return the case counterpart of an alphabetic == static wint_t othercase(wint_t ch); */ static wint_t /* if no counterpart, return ch */ othercase(wint_t ch) { assert(iswalpha(ch)); if (iswupper(ch)) return(towlower(ch)); else if (iswlower(ch)) return(towupper(ch)); else /* peculiar, but could happen */ return(ch); } /* - bothcases - emit a dualcase version of a two-case character == static void bothcases(struct parse *p, wint_t ch); * * Boy, is this implementation ever a kludge... */ static void bothcases(struct parse *p, wint_t ch) { const char *oldnext = p->next; const char *oldend = p->end; char bracket[3 + MB_LEN_MAX]; size_t n; mbstate_t mbs; assert(othercase(ch) != ch); /* p_bracket() would recurse */ p->next = bracket; memset(&mbs, 0, sizeof(mbs)); n = wcrtomb(bracket, ch, &mbs); assert(n != (size_t)-1); bracket[n] = ']'; bracket[n + 1] = '\0'; p->end = bracket+n+1; p_bracket(p); assert(p->next == p->end); p->next = oldnext; p->end = oldend; } /* - ordinary - emit an ordinary character == static void ordinary(struct parse *p, wint_t ch); */ static void ordinary(struct parse *p, wint_t ch) { cset *cs; if ((p->g->cflags®_ICASE) && iswalpha(ch) && othercase(ch) != ch) bothcases(p, ch); else if ((ch & OPDMASK) == ch) EMIT(OCHAR, ch); else { /* * Kludge: character is too big to fit into an OCHAR operand. * Emit a singleton set. */ if ((cs = allocset(p)) == NULL) return; CHadd(p, cs, ch); EMIT(OANYOF, (int)(cs - p->g->sets)); } } /* - nonnewline - emit REG_NEWLINE version of OANY == static void nonnewline(struct parse *p); * * Boy, is this implementation ever a kludge... */ static void nonnewline(struct parse *p) { const char *oldnext = p->next; const char *oldend = p->end; char bracket[4]; p->next = bracket; p->end = bracket+3; bracket[0] = '^'; bracket[1] = '\n'; bracket[2] = ']'; bracket[3] = '\0'; p_bracket(p); assert(p->next == bracket+3); p->next = oldnext; p->end = oldend; } /* - repeat - generate code for a bounded repetition, recursively if needed == static void repeat(struct parse *p, sopno start, int from, int to); */ static void repeat(struct parse *p, sopno start, /* operand from here to end of strip */ int from, /* repeated from this number */ int to) /* to this number of times (maybe INFINITY) */ { sopno finish = HERE(); # define N 2 # define INF 3 # define REP(f, t) ((f)*8 + (t)) # define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) sopno copy; if (p->error != 0) /* head off possible runaway recursion */ return; assert(from <= to); switch (REP(MAP(from), MAP(to))) { case REP(0, 0): /* must be user doing this */ DROP(finish-start); /* drop the operand */ break; case REP(0, 1): /* as x{1,1}? */ case REP(0, N): /* as x{1,n}? */ case REP(0, INF): /* as x{1,}? */ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); /* offset is wrong... */ repeat(p, start+1, 1, to); ASTERN(OOR1, start); AHEAD(start); /* ... fix it */ EMIT(OOR2, 0); AHEAD(THERE()); ASTERN(O_CH, THERETHERE()); break; case REP(1, 1): /* trivial case */ /* done */ break; case REP(1, N): /* as x?x{1,n-1} */ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ INSERT(OCH_, start); ASTERN(OOR1, start); AHEAD(start); EMIT(OOR2, 0); /* offset very wrong... */ AHEAD(THERE()); /* ...so fix it */ ASTERN(O_CH, THERETHERE()); copy = dupl(p, start+1, finish+1); assert(copy == finish+4); repeat(p, copy, 1, to-1); break; case REP(1, INF): /* as x+ */ INSERT(OPLUS_, start); ASTERN(O_PLUS, start); break; case REP(N, N): /* as xx{m-1,n-1} */ copy = dupl(p, start, finish); repeat(p, copy, from-1, to-1); break; case REP(N, INF): /* as xx{n-1,INF} */ copy = dupl(p, start, finish); repeat(p, copy, from-1, to); break; default: /* "can't happen" */ SETERROR(REG_ASSERT); /* just in case */ break; } } /* - wgetnext - helper function for WGETNEXT() macro. Gets the next wide - character from the parse struct, signals a REG_ILLSEQ error if the - character can't be converted. Returns the number of bytes consumed. */ static wint_t wgetnext(struct parse *p) { mbstate_t mbs; wchar_t wc; size_t n; memset(&mbs, 0, sizeof(mbs)); n = mbrtowc(&wc, p->next, p->end - p->next, &mbs); if (n == (size_t)-1 || n == (size_t)-2) { SETERROR(REG_ILLSEQ); return (0); } if (n == 0) n = 1; p->next += n; return (wc); } /* - seterr - set an error condition == static int seterr(struct parse *p, int e); */ static int /* useless but makes type checking happy */ seterr(struct parse *p, int e) { if (p->error == 0) /* keep earliest error condition */ p->error = e; p->next = nuls; /* try to bring things to a halt */ p->end = nuls; return(0); /* make the return value well-defined */ } /* - allocset - allocate a set of characters for [] == static cset *allocset(struct parse *p); */ static cset * allocset(struct parse *p) { cset *cs, *ncs; ncs = reallocarray(p->g->sets, p->g->ncsets + 1, sizeof(*ncs)); if (ncs == NULL) { SETERROR(REG_ESPACE); return (NULL); } p->g->sets = ncs; cs = &p->g->sets[p->g->ncsets++]; memset(cs, 0, sizeof(*cs)); return(cs); } /* - freeset - free a now-unused set == static void freeset(struct parse *p, cset *cs); */ static void freeset(struct parse *p, cset *cs) { cset *top = &p->g->sets[p->g->ncsets]; free(cs->wides); free(cs->ranges); free(cs->types); memset(cs, 0, sizeof(*cs)); if (cs == top-1) /* recover only the easy case */ p->g->ncsets--; } /* - singleton - Determine whether a set contains only one character, - returning it if so, otherwise returning OUT. */ static wint_t singleton(cset *cs) { wint_t i, s, n; for (i = n = 0; i < NC; i++) if (CHIN(cs, i)) { n++; s = i; } if (n == 1) return (s); if (cs->nwides == 1 && cs->nranges == 0 && cs->ntypes == 0 && cs->icase == 0) return (cs->wides[0]); /* Don't bother handling the other cases. */ return (OUT); } /* - CHadd - add character to character set. */ static void CHadd(struct parse *p, cset *cs, wint_t ch) { wint_t nch, *newwides; assert(ch >= 0); if (ch < NC) cs->bmp[ch >> 3] |= 1 << (ch & 7); else { newwides = reallocarray(cs->wides, cs->nwides + 1, sizeof(*cs->wides)); if (newwides == NULL) { SETERROR(REG_ESPACE); return; } cs->wides = newwides; cs->wides[cs->nwides++] = ch; } if (cs->icase) { if ((nch = towlower(ch)) < NC) cs->bmp[nch >> 3] |= 1 << (nch & 7); if ((nch = towupper(ch)) < NC) cs->bmp[nch >> 3] |= 1 << (nch & 7); } } /* - CHaddrange - add all characters in the range [min,max] to a character set. */ static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) { crange *newranges; for (; min < NC && min <= max; min++) CHadd(p, cs, min); if (min >= max) return; newranges = reallocarray(cs->ranges, cs->nranges + 1, sizeof(*cs->ranges)); if (newranges == NULL) { SETERROR(REG_ESPACE); return; } cs->ranges = newranges; cs->ranges[cs->nranges].min = min; cs->ranges[cs->nranges].max = max; cs->nranges++; } /* - CHaddtype - add all characters of a certain type to a character set. */ static void CHaddtype(struct parse *p, cset *cs, wctype_t wct) { wint_t i; wctype_t *newtypes; for (i = 0; i < NC; i++) if (iswctype(i, wct)) CHadd(p, cs, i); newtypes = reallocarray(cs->types, cs->ntypes + 1, sizeof(*cs->types)); if (newtypes == NULL) { SETERROR(REG_ESPACE); return; } cs->types = newtypes; cs->types[cs->ntypes++] = wct; } /* - dupl - emit a duplicate of a bunch of sops == static sopno dupl(struct parse *p, sopno start, sopno finish); */ static sopno /* start of duplicate */ dupl(struct parse *p, sopno start, /* from here */ sopno finish) /* to this less one */ { sopno ret = HERE(); sopno len = finish - start; assert(finish >= start); if (len == 0) return(ret); if (!enlarge(p, p->ssize + len)) /* this many unexpected additions */ return(ret); (void) memcpy((char *)(p->strip + p->slen), (char *)(p->strip + start), (size_t)len*sizeof(sop)); p->slen += len; return(ret); } /* - doemit - emit a strip operator == static void doemit(struct parse *p, sop op, size_t opnd); * * It might seem better to implement this as a macro with a function as * hard-case backup, but it's just too big and messy unless there are * some changes to the data structures. Maybe later. */ static void doemit(struct parse *p, sop op, size_t opnd) { /* avoid making error situations worse */ if (p->error != 0) return; /* deal with oversize operands ("can't happen", more or less) */ assert(opnd < 1<slen >= p->ssize) if (!enlarge(p, (p->ssize+1) / 2 * 3)) /* +50% */ return; /* finally, it's all reduced to the easy case */ p->strip[p->slen++] = SOP(op, opnd); } /* - doinsert - insert a sop into the strip == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); */ static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos) { sopno sn; sop s; int i; /* avoid making error situations worse */ if (p->error != 0) return; sn = HERE(); EMIT(op, opnd); /* do checks, ensure space */ assert(HERE() == sn+1); s = p->strip[sn]; /* adjust paren pointers */ assert(pos > 0); for (i = 1; i < NPAREN; i++) { if (p->pbegin[i] >= pos) { p->pbegin[i]++; } if (p->pend[i] >= pos) { p->pend[i]++; } } memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], (HERE()-pos-1)*sizeof(sop)); p->strip[pos] = s; } /* - dofwd - complete a forward reference == static void dofwd(struct parse *p, sopno pos, sop value); */ static void dofwd(struct parse *p, sopno pos, sop value) { /* avoid making error situations worse */ if (p->error != 0) return; assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; } /* - enlarge - enlarge the strip == static int enlarge(struct parse *p, sopno size); */ static int enlarge(struct parse *p, sopno size) { sop *sp; if (p->ssize >= size) return 1; sp = reallocarray(p->strip, size, sizeof(sop)); if (sp == NULL) { SETERROR(REG_ESPACE); return 0; } p->strip = sp; p->ssize = size; return 1; } /* - stripsnug - compact the strip == static void stripsnug(struct parse *p, struct re_guts *g); */ static void stripsnug(struct parse *p, struct re_guts *g) { g->nstates = p->slen; g->strip = reallocarray((char *)p->strip, p->slen, sizeof(sop)); if (g->strip == NULL) { SETERROR(REG_ESPACE); g->strip = p->strip; } } /* - findmust - fill in must and mlen with longest mandatory literal string == static void findmust(struct parse *p, struct re_guts *g); * * This algorithm could do fancy things like analyzing the operands of | * for common subsequences. Someday. This code is simple and finds most * of the interesting cases. * * Note that must and mlen got initialized during setup. */ static void findmust(struct parse *p, struct re_guts *g) { sop *scan; sop *start = NULL; sop *newstart = NULL; sopno newlen; sop s; char *cp; int offset; char buf[MB_LEN_MAX]; size_t clen; mbstate_t mbs; /* avoid making error situations worse */ if (p->error != 0) return; /* * It's not generally safe to do a ``char'' substring search on * multibyte character strings, but it's safe for at least * UTF-8 (see RFC 3629). */ if (MB_CUR_MAX > 1 && strcmp(_CurrentRuneLocale->__encoding, "UTF-8") != 0) return; /* find the longest OCHAR sequence in strip */ newlen = 0; offset = 0; g->moffset = 0; scan = g->strip + 1; do { s = *scan++; switch (OP(s)) { case OCHAR: /* sequence member */ if (newlen == 0) { /* new sequence */ memset(&mbs, 0, sizeof(mbs)); newstart = scan - 1; } clen = wcrtomb(buf, OPND(s), &mbs); if (clen == (size_t)-1) goto toohard; newlen += clen; break; case OPLUS_: /* things that don't break one */ case OLPAREN: case ORPAREN: break; case OQUEST_: /* things that must be skipped */ case OCH_: offset = altoffset(scan, offset); scan--; do { scan += OPND(s); s = *scan; /* assert() interferes w debug printouts */ if (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH && OP(s) != (sop)OOR2) { g->iflags |= BAD; return; } } while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH); /* FALLTHROUGH */ case OBOW: /* things that break a sequence */ case OEOW: case OBOL: case OEOL: case OBOS: case OEOS: case OWBND: case ONWBND: case O_QUEST: case O_CH: case OEND: if (newlen > (sopno)g->mlen) { /* ends one */ start = newstart; g->mlen = newlen; if (offset > -1) { g->moffset += offset; offset = newlen; } else g->moffset = offset; } else { if (offset > -1) offset += newlen; } newlen = 0; break; case OANY: if (newlen > (sopno)g->mlen) { /* ends one */ start = newstart; g->mlen = newlen; if (offset > -1) { g->moffset += offset; offset = newlen; } else g->moffset = offset; } else { if (offset > -1) offset += newlen; } if (offset > -1) offset++; newlen = 0; break; case OANYOF: /* may or may not invalidate offset */ /* First, everything as OANY */ if (newlen > (sopno)g->mlen) { /* ends one */ start = newstart; g->mlen = newlen; if (offset > -1) { g->moffset += offset; offset = newlen; } else g->moffset = offset; } else { if (offset > -1) offset += newlen; } if (offset > -1) offset++; newlen = 0; break; toohard: default: /* Anything here makes it impossible or too hard * to calculate the offset -- so we give up; * save the last known good offset, in case the * must sequence doesn't occur later. */ if (newlen > (sopno)g->mlen) { /* ends one */ start = newstart; g->mlen = newlen; if (offset > -1) g->moffset += offset; else g->moffset = offset; } offset = -1; newlen = 0; break; } } while (OP(s) != OEND); if (g->mlen == 0) { /* there isn't one */ g->moffset = -1; return; } /* turn it into a character string */ g->must = malloc((size_t)g->mlen + 1); if (g->must == NULL) { /* argh; just forget it */ g->mlen = 0; g->moffset = -1; return; } cp = g->must; scan = start; memset(&mbs, 0, sizeof(mbs)); while (cp < g->must + g->mlen) { while (OP(s = *scan++) != OCHAR) continue; clen = wcrtomb(cp, OPND(s), &mbs); assert(clen != (size_t)-1); cp += clen; } assert(cp == g->must + g->mlen); *cp++ = '\0'; /* just on general principles */ } /* - altoffset - choose biggest offset among multiple choices == static int altoffset(sop *scan, int offset); * * Compute, recursively if necessary, the largest offset among multiple * re paths. */ static int altoffset(sop *scan, int offset) { int largest; int try; sop s; /* If we gave up already on offsets, return */ if (offset == -1) return -1; largest = 0; try = 0; s = *scan++; while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH) { switch (OP(s)) { case OOR1: if (try > largest) largest = try; try = 0; break; case OQUEST_: case OCH_: try = altoffset(scan, try); if (try == -1) return -1; scan--; do { scan += OPND(s); s = *scan; if (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH && OP(s) != (sop)OOR2) return -1; } while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH); /* We must skip to the next position, or we'll * leave altoffset() too early. */ scan++; break; case OANYOF: case OCHAR: case OANY: try++; case OBOW: case OEOW: case OWBND: case ONWBND: case OLPAREN: case ORPAREN: case OOR2: break; default: try = -1; break; } if (try == -1) return -1; s = *scan++; } if (try > largest) largest = try; return largest+offset; } /* - computejumps - compute char jumps for BM scan == static void computejumps(struct parse *p, struct re_guts *g); * * This algorithm assumes g->must exists and is has size greater than * zero. It's based on the algorithm found on Computer Algorithms by * Sara Baase. * * A char jump is the number of characters one needs to jump based on * the value of the character from the text that was mismatched. */ static void computejumps(struct parse *p, struct re_guts *g) { int ch; int mindex; /* Avoid making errors worse */ if (p->error != 0) return; g->charjump = (int *)malloc((NC_MAX + 1) * sizeof(int)); if (g->charjump == NULL) /* Not a fatal error */ return; /* Adjust for signed chars, if necessary */ g->charjump = &g->charjump[-(CHAR_MIN)]; /* If the character does not exist in the pattern, the jump * is equal to the number of characters in the pattern. */ for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++) g->charjump[ch] = g->mlen; /* If the character does exist, compute the jump that would * take us to the last character in the pattern equal to it * (notice that we match right to left, so that last character * is the first one that would be matched). */ for (mindex = 0; mindex < g->mlen; mindex++) g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1; } /* - computematchjumps - compute match jumps for BM scan == static void computematchjumps(struct parse *p, struct re_guts *g); * * This algorithm assumes g->must exists and is has size greater than * zero. It's based on the algorithm found on Computer Algorithms by * Sara Baase. * * A match jump is the number of characters one needs to advance based * on the already-matched suffix. * Notice that all values here are minus (g->mlen-1), because of the way * the search algorithm works. */ static void computematchjumps(struct parse *p, struct re_guts *g) { int mindex; /* General "must" iterator */ int suffix; /* Keeps track of matching suffix */ int ssuffix; /* Keeps track of suffixes' suffix */ int* pmatches; /* pmatches[k] points to the next i * such that i+1...mlen is a substring * of k+1...k+mlen-i-1 */ /* Avoid making errors worse */ if (p->error != 0) return; pmatches = (int*) malloc(g->mlen * sizeof(int)); if (pmatches == NULL) { g->matchjump = NULL; return; } g->matchjump = (int*) malloc(g->mlen * sizeof(int)); if (g->matchjump == NULL) { /* Not a fatal error */ free(pmatches); return; } /* Set maximum possible jump for each character in the pattern */ for (mindex = 0; mindex < g->mlen; mindex++) g->matchjump[mindex] = 2*g->mlen - mindex - 1; /* Compute pmatches[] */ for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0; mindex--, suffix--) { pmatches[mindex] = suffix; /* If a mismatch is found, interrupting the substring, * compute the matchjump for that position. If no * mismatch is found, then a text substring mismatched * against the suffix will also mismatch against the * substring. */ while (suffix < g->mlen && g->must[mindex] != g->must[suffix]) { g->matchjump[suffix] = MIN(g->matchjump[suffix], g->mlen - mindex - 1); suffix = pmatches[suffix]; } } /* Compute the matchjump up to the last substring found to jump * to the beginning of the largest must pattern prefix matching * it's own suffix. */ for (mindex = 0; mindex <= suffix; mindex++) g->matchjump[mindex] = MIN(g->matchjump[mindex], g->mlen + suffix - mindex); ssuffix = pmatches[suffix]; while (suffix < g->mlen) { while (suffix <= ssuffix && suffix < g->mlen) { g->matchjump[suffix] = MIN(g->matchjump[suffix], g->mlen + ssuffix - suffix); suffix++; } if (suffix < g->mlen) ssuffix = pmatches[ssuffix]; } free(pmatches); } /* - pluscount - count + nesting == static sopno pluscount(struct parse *p, struct re_guts *g); */ static sopno /* nesting depth */ pluscount(struct parse *p, struct re_guts *g) { sop *scan; sop s; sopno plusnest = 0; sopno maxnest = 0; if (p->error != 0) return(0); /* there may not be an OEND */ scan = g->strip + 1; do { s = *scan++; switch (OP(s)) { case OPLUS_: plusnest++; break; case O_PLUS: if (plusnest > maxnest) maxnest = plusnest; plusnest--; break; } } while (OP(s) != OEND); if (plusnest != 0) g->iflags |= BAD; return(maxnest); } diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index a39e1ee4c21f..123345490c43 100644 --- a/lib/libc/stdio/asprintf.c +++ b/lib/libc/stdio/asprintf.c @@ -1,67 +1,67 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include int asprintf(char ** __restrict s, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vasprintf(s, fmt, ap); va_end(ap); return (ret); } int asprintf_l(char ** __restrict s, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vasprintf_l(s, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c index 63f3e353ef45..949d93f67007 100644 --- a/lib/libc/stdio/fgetwc.c +++ b/lib/libc/stdio/fgetwc.c @@ -1,109 +1,109 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "mblocal.h" #include "xlocale_private.h" /* * MT-safe version. */ wint_t fgetwc_l(FILE *fp, locale_t locale) { wint_t r; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); r = __fgetwc(fp, locale); FUNLOCKFILE_CANCELSAFE(); return (r); } wint_t fgetwc(FILE *fp) { return fgetwc_l(fp, __get_locale()); } /* * Internal (non-MPSAFE) version of fgetwc(). This version takes an * mbstate_t argument specifying the initial conversion state. For * wide streams, this should always be fp->_mbstate. On return, *nread * is set to the number of bytes read. */ wint_t __fgetwc_mbs(FILE *fp, mbstate_t *mbs, int *nread, locale_t locale) { wchar_t wc; size_t nconv; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); *nread = 0; if (fp->_r <= 0 && __srefill(fp)) return (WEOF); do { nconv = l->__mbrtowc(&wc, fp->_p, fp->_r, mbs); if (nconv == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } else if (nconv == (size_t)-2) continue; else if (nconv == 0) { fp->_p++; fp->_r--; (*nread)++; return (L'\0'); } else { fp->_p += nconv; fp->_r -= nconv; *nread += nconv; return (wc); } } while (__srefill(fp) == 0); if (__sfeof(fp)) { fp->_flags |= __SERR; errno = EILSEQ; } return (WEOF); } diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c index 9d564fc4c15e..8d74f9d8f3da 100644 --- a/lib/libc/stdio/fgetwln.c +++ b/lib/libc/stdio/fgetwln.c @@ -1,97 +1,97 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" wchar_t *fgetwln_l(FILE * __restrict, size_t *, locale_t); wchar_t * fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale) { wchar_t *ret; wint_t wc; size_t len; int savserr; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); savserr = fp->_flags & __SERR; fp->_flags &= ~__SERR; len = 0; while ((wc = __fgetwc(fp, locale)) != WEOF) { #define GROW 512 if (len * sizeof(wchar_t) >= fp->_lb._size && __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) { fp->_flags |= __SERR; goto error; } *((wchar_t *)fp->_lb._base + len++) = wc; if (wc == L'\n') break; } /* fgetwc(3) may set both __SEOF and __SERR at once. */ if (__sferror(fp)) goto error; fp->_flags |= savserr; if (len == 0) goto error; *lenp = len; ret = (wchar_t *)fp->_lb._base; end: FUNLOCKFILE_CANCELSAFE(); return (ret); error: *lenp = 0; ret = NULL; goto end; } wchar_t * fgetwln(FILE * __restrict fp, size_t *lenp) { return fgetwln_l(fp, lenp, __get_locale()); } diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c index 6bbf0521050b..1eaeed708ef1 100644 --- a/lib/libc/stdio/fgetws.c +++ b/lib/libc/stdio/fgetws.c @@ -1,130 +1,130 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "mblocal.h" wchar_t * fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t locale) { int sret; wchar_t *wsp, *ret; size_t nconv; const char *src; unsigned char *nl; FIX_LOCALE(locale); struct xlocale_ctype *l = XLOCALE_CTYPE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); if (n <= 0) { fp->_flags |= __SERR; errno = EINVAL; goto error; } wsp = ws; if (n == 1) goto ok; if (fp->_r <= 0 && __srefill(fp)) /* EOF or ferror */ goto error; sret = 0; do { src = fp->_p; nl = memchr(fp->_p, '\n', fp->_r); nconv = l->__mbsnrtowcs(wsp, &src, nl != NULL ? (nl - fp->_p + 1) : fp->_r, n - 1, &fp->_mbstate); if (nconv == (size_t)-1) { /* Conversion error */ fp->_flags |= __SERR; goto error; } if (src == NULL) { /* * We hit a null byte. Increment the character count, * since mbsnrtowcs()'s return value doesn't include * the terminating null, then resume conversion * after the null. */ nconv++; src = memchr(fp->_p, '\0', fp->_r); src++; } fp->_r -= (unsigned char *)src - fp->_p; fp->_p = (unsigned char *)src; n -= nconv; wsp += nconv; } while ((wsp == ws || wsp[-1] != L'\n') && n > 1 && (fp->_r > 0 || (sret = __srefill(fp)) == 0)); if (sret && !__sfeof(fp)) /* ferror */ goto error; if (!l->__mbsinit(&fp->_mbstate)) { /* Incomplete character */ fp->_flags |= __SERR; errno = EILSEQ; goto error; } if (wsp == ws) /* EOF */ goto error; ok: *wsp = L'\0'; ret = ws; end: FUNLOCKFILE_CANCELSAFE(); return (ret); error: ret = NULL; goto end; } wchar_t * fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp) { return fgetws_l(ws, n, fp, __get_locale()); } diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c index ec9a0390b095..c1df55872aa3 100644 --- a/lib/libc/stdio/fprintf.c +++ b/lib/libc/stdio/fprintf.c @@ -1,70 +1,70 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include "xlocale_private.h" int fprintf(FILE * __restrict fp, const char * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf_l(fp, __get_locale(), fmt, ap); va_end(ap); return (ret); } int fprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); ret = vfprintf_l(fp, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c index 83ae7c3ae483..197c57cc374a 100644 --- a/lib/libc/stdio/fputwc.c +++ b/lib/libc/stdio/fputwc.c @@ -1,88 +1,88 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "mblocal.h" /* * Non-MT-safe version. */ wint_t __fputwc(wchar_t wc, FILE *fp, locale_t locale) { char buf[MB_LEN_MAX]; size_t i, len; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } for (i = 0; i < len; i++) if (__sputc((unsigned char)buf[i], fp) == EOF) return (WEOF); return ((wint_t)wc); } /* * MT-safe version. */ wint_t fputwc_l(wchar_t wc, FILE *fp, locale_t locale) { wint_t r; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); r = __fputwc(wc, fp, locale); FUNLOCKFILE_CANCELSAFE(); return (r); } wint_t fputwc(wchar_t wc, FILE *fp) { return fputwc_l(wc, fp, __get_locale()); } diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c index f8b0ca78cfb7..c77393886e72 100644 --- a/lib/libc/stdio/fputws.c +++ b/lib/libc/stdio/fputws.c @@ -1,86 +1,86 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "fvwrite.h" #include "libc_private.h" #include "local.h" #include "mblocal.h" int fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t locale) { size_t nbytes; char buf[BUFSIZ]; struct __suio uio; struct __siov iov; const wchar_t *wsp; FIX_LOCALE(locale); struct xlocale_ctype *l = XLOCALE_CTYPE(locale); int ret; ret = -1; FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); if (prepwrite(fp) != 0) goto end; uio.uio_iov = &iov; uio.uio_iovcnt = 1; iov.iov_base = buf; wsp = ws; do { nbytes = l->__wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf), &fp->_mbstate); if (nbytes == (size_t)-1) goto end; uio.uio_resid = iov.iov_len = nbytes; if (__sfvwrite(fp, &uio) != 0) goto end; } while (wsp != NULL); ret = 0; end: FUNLOCKFILE_CANCELSAFE(); return (ret); } int fputws(const wchar_t * __restrict ws, FILE * __restrict fp) { return fputws_l(ws, fp, __get_locale()); } diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c index b06dd83c7979..f274cb98ef3c 100644 --- a/lib/libc/stdio/fscanf.c +++ b/lib/libc/stdio/fscanf.c @@ -1,78 +1,78 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" int fscanf(FILE * __restrict fp, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); FLOCKFILE_CANCELSAFE(fp); ret = __svfscanf(fp, __get_locale(), fmt, ap); va_end(ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } int fscanf_l(FILE * __restrict fp, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); FLOCKFILE_CANCELSAFE(fp); ret = __svfscanf(fp, locale, fmt, ap); va_end(ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } diff --git a/lib/libc/stdio/fwprintf.c b/lib/libc/stdio/fwprintf.c index 7428d77b7d2f..7550bb8eb69b 100644 --- a/lib/libc/stdio/fwprintf.c +++ b/lib/libc/stdio/fwprintf.c @@ -1,63 +1,63 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int fwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfwprintf(fp, fmt, ap); va_end(ap); return (ret); } int fwprintf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfwprintf_l(fp, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/fwscanf.c b/lib/libc/stdio/fwscanf.c index 198941dde645..b0f2d02e748d 100644 --- a/lib/libc/stdio/fwscanf.c +++ b/lib/libc/stdio/fwscanf.c @@ -1,63 +1,63 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vfwscanf(fp, fmt, ap); va_end(ap); return (r); } int fwscanf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vfwscanf_l(fp, locale, fmt, ap); va_end(ap); return (r); } diff --git a/lib/libc/stdio/getwc.c b/lib/libc/stdio/getwc.c index b7004cc44a73..ccac10db228f 100644 --- a/lib/libc/stdio/getwc.c +++ b/lib/libc/stdio/getwc.c @@ -1,60 +1,60 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #undef getwc /* * Synonym for fgetwc(). The only difference is that getwc(), if it is a * macro, may evaluate `fp' more than once. */ wint_t getwc(FILE *fp) { return (fgetwc(fp)); } wint_t getwc_l(FILE *fp, locale_t locale) { return (fgetwc_l(fp, locale)); } diff --git a/lib/libc/stdio/getwchar.c b/lib/libc/stdio/getwchar.c index 03b47c68893f..9294a952357e 100644 --- a/lib/libc/stdio/getwchar.c +++ b/lib/libc/stdio/getwchar.c @@ -1,57 +1,57 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #undef getwchar /* * Synonym for fgetwc(stdin). */ wint_t getwchar(void) { return (fgetwc(stdin)); } wint_t getwchar_l(locale_t locale) { return (fgetwc_l(stdin, locale)); } diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h index b47555234609..a5c465bcdcba 100644 --- a/lib/libc/stdio/local.h +++ b/lib/libc/stdio/local.h @@ -1,167 +1,167 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. * * @(#)local.h 8.3 (Berkeley) 7/3/94 */ #ifndef _STDIO_LOCAL_H #define _STDIO_LOCAL_H #include /* for off_t */ #include #include #include #include /* * Information local to this implementation of stdio, * in particular, macros and private variables. */ extern int _sread(FILE *, char *, int); extern int _swrite(FILE *, char const *, int); extern fpos_t _sseek(FILE *, fpos_t, int); extern int _ftello(FILE *, fpos_t *); extern int _fseeko(FILE *, off_t, int, int); extern int __fflush(FILE *fp); extern void __fcloseall(void); extern wint_t __fgetwc_mbs(FILE *, mbstate_t *, int *, locale_t); extern wint_t __fputwc(wchar_t, FILE *, locale_t); extern int __sflush(FILE *); extern FILE *__sfp(void); extern int __slbexpand(FILE *, size_t); extern int __srefill(FILE *); extern int __sread(void *, char *, int); extern int __swrite(void *, char const *, int); extern fpos_t __sseek(void *, fpos_t, int); extern int __sclose(void *); extern void __sinit(void); extern void _cleanup(void); extern void __smakebuf(FILE *); extern int __swhatbuf(FILE *, size_t *, int *); extern int _fwalk(int (*)(FILE *)); extern int __svfscanf(FILE *, locale_t, const char *, __va_list); extern int __swsetup(FILE *); extern int __sflags(const char *, int *); extern int __ungetc(int, FILE *); extern wint_t __ungetwc(wint_t, FILE *, locale_t); extern int __vfprintf(FILE *, locale_t, const char *, __va_list); extern int __vfscanf(FILE *, const char *, __va_list); extern int __vfwprintf(FILE *, locale_t, const wchar_t *, __va_list); extern int __vfwscanf(FILE * __restrict, locale_t, const wchar_t * __restrict, __va_list); extern size_t __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp); extern int __sdidinit; static inline wint_t __fgetwc(FILE *fp, locale_t locale) { int nread; return (__fgetwc_mbs(fp, &fp->_mbstate, &nread, locale)); } /* * Prepare the given FILE for writing, and return 0 iff it * can be written now. Otherwise, return EOF and set errno. */ #define prepwrite(fp) \ ((((fp)->_flags & __SWR) == 0 || \ ((fp)->_bf._base == NULL && ((fp)->_flags & __SSTR) == 0)) && \ __swsetup(fp)) /* * Test whether the given stdio file has an active ungetc buffer; * release such a buffer, without restoring ordinary unread data. */ #define HASUB(fp) ((fp)->_ub._base != NULL) #define FREEUB(fp) { \ if ((fp)->_ub._base != (fp)->_ubuf) \ free((char *)(fp)->_ub._base); \ (fp)->_ub._base = NULL; \ } /* * test for an fgetln() buffer. */ #define HASLB(fp) ((fp)->_lb._base != NULL) #define FREELB(fp) { \ free((char *)(fp)->_lb._base); \ (fp)->_lb._base = NULL; \ } /* * Structure initializations for 'fake' FILE objects. */ #define FAKE_FILE { \ ._file = -1, \ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \ } /* * Set the orientation for a stream. If o > 0, the stream has wide- * orientation. If o < 0, the stream has byte-orientation. */ #define ORIENT(fp, o) do { \ if ((fp)->_orientation == 0) \ (fp)->_orientation = (o); \ } while (0) void __stdio_cancel_cleanup(void *); #define FLOCKFILE_CANCELSAFE(fp) \ { \ struct _pthread_cleanup_info __cleanup_info__; \ if (__isthreaded) { \ _FLOCKFILE(fp); \ ___pthread_cleanup_push_imp( \ __stdio_cancel_cleanup, (fp), \ &__cleanup_info__); \ } else { \ ___pthread_cleanup_push_imp( \ __stdio_cancel_cleanup, NULL, \ &__cleanup_info__); \ } \ { #define FUNLOCKFILE_CANCELSAFE() \ (void)0; \ } \ ___pthread_cleanup_pop_imp(1); \ } #endif /* _STDIO_LOCAL_H */ diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c index a801e6dbbc08..20e5b7b0e3cd 100644 --- a/lib/libc/stdio/printf.c +++ b/lib/libc/stdio/printf.c @@ -1,69 +1,69 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include int printf(char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf(stdout, fmt, ap); va_end(ap); return (ret); } int printf_l(locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf_l(stdout, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h index b6c09b7dc0d7..ac5aed0a5fcd 100644 --- a/lib/libc/stdio/printfcommon.h +++ b/lib/libc/stdio/printfcommon.h @@ -1,307 +1,307 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ /* * This file defines common routines used by both printf and wprintf. * You must define CHAR to either char or wchar_t prior to including this. */ #ifndef NO_FLOATING_POINT #define dtoa __dtoa #define freedtoa __freedtoa #include #include #include "floatio.h" #include "gdtoa.h" #define DEFPREC 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 *); #define NIOV 8 struct io_state { FILE *fp; struct __suio uio; /* output information: summary */ struct __siov iov[NIOV];/* ... and individual io vectors */ }; static inline void io_init(struct io_state *iop, FILE *fp) { iop->uio.uio_iov = iop->iov; iop->uio.uio_resid = 0; iop->uio.uio_iovcnt = 0; iop->fp = fp; } /* * WARNING: The buffer passed to io_print() is not copied immediately; it must * remain valid until io_flush() is called. */ static inline int io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, locale_t locale) { iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr; iop->iov[iop->uio.uio_iovcnt].iov_len = len; iop->uio.uio_resid += len; if (++iop->uio.uio_iovcnt >= NIOV) return (__sprint(iop->fp, &iop->uio, locale)); else return (0); } /* * Choose PADSIZE to trade efficiency vs. size. If larger printf * fields occur frequently, increase PADSIZE and make the initialisers * below longer. */ #define PADSIZE 16 /* pad chunk size */ static const CHAR blanks[PADSIZE] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; static const CHAR zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; /* * Pad with blanks or zeroes. 'with' should point to either the blanks array * or the zeroes array. */ static inline int io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with, locale_t locale) { int n; while (howmany > 0) { n = (howmany >= PADSIZE) ? PADSIZE : howmany; if (io_print(iop, with, n, locale)) return (-1); howmany -= n; } return (0); } /* * Print exactly len characters of the string spanning p to ep, truncating * or padding with 'with' as necessary. */ static inline int io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, int len, const CHAR * __restrict with, locale_t locale) { int p_len; p_len = ep - p; if (p_len > len) p_len = len; if (p_len > 0) { if (io_print(iop, p, p_len, locale)) return (-1); } else { p_len = 0; } return (io_pad(iop, len - p_len, with, locale)); } static inline int io_flush(struct io_state *iop, locale_t locale) { return (__sprint(iop->fp, &iop->uio, locale)); } /* * Convert an unsigned long to ASCII for printf purposes, returning * a pointer to the first character of the string representation. * Octal numbers can be forced to have a leading zero; hex numbers * use the given digits. */ static CHAR * __ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs) { CHAR *cp = endp; long sval; /* * Handle the three cases separately, in the hope of getting * better/faster code. */ switch (base) { case 10: if (val < 10) { /* many numbers are 1 digit */ *--cp = to_char(val); return (cp); } /* * On many machines, unsigned arithmetic is harder than * signed arithmetic, so we do at most one unsigned mod and * divide; this is sufficient to reduce the range of * the incoming value to where signed arithmetic works. */ if (val > LONG_MAX) { *--cp = to_char(val % 10); sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: /* oops */ abort(); } return (cp); } /* Identical to __ultoa, but for intmax_t. */ static CHAR * __ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs) { CHAR *cp = endp; intmax_t sval; /* quick test for small values; __ultoa is typically much faster */ /* (perhaps instead we should run until small, then call __ultoa?) */ if (val <= ULONG_MAX) return (__ultoa((u_long)val, endp, base, octzero, xdigs)); switch (base) { case 10: if (val < 10) { *--cp = to_char(val % 10); return (cp); } if (val > INTMAX_MAX) { *--cp = to_char(val % 10); sval = val / 10; } else sval = val; do { *--cp = to_char(sval % 10); sval /= 10; } while (sval != 0); break; case 8: do { *--cp = to_char(val & 7); val >>= 3; } while (val); if (octzero && *cp != '0') *--cp = '0'; break; case 16: do { *--cp = xdigs[val & 15]; val >>= 4; } while (val); break; default: abort(); } return (cp); } #ifndef NO_FLOATING_POINT static int exponent(CHAR *p0, int exp, CHAR fmtch) { CHAR *p, *t; CHAR expbuf[MAXEXPDIG]; p = p0; *p++ = fmtch; if (exp < 0) { exp = -exp; *p++ = '-'; } else *p++ = '+'; t = expbuf + MAXEXPDIG; if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); for (; t < expbuf + MAXEXPDIG; *p++ = *t++); } else { /* * Exponents for decimal floating point conversions * (%[eEgG]) must be at least two characters long, * whereas exponents for hexadecimal conversions can * be only one character long. */ if (fmtch == 'e' || fmtch == 'E') *p++ = '0'; *p++ = to_char(exp); } return (p - p0); } #endif /* !NO_FLOATING_POINT */ diff --git a/lib/libc/stdio/putwc.c b/lib/libc/stdio/putwc.c index 4185f3b8a783..386023924440 100644 --- a/lib/libc/stdio/putwc.c +++ b/lib/libc/stdio/putwc.c @@ -1,59 +1,59 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" #undef putwc /* * Synonym for fputwc(). The only difference is that putwc(), if it is a * macro, may evaluate `fp' more than once. */ wint_t putwc_l(wchar_t wc, FILE *fp, locale_t locale) { FIX_LOCALE(locale); return (fputwc_l(wc, fp, locale)); } wint_t putwc(wchar_t wc, FILE *fp) { return putwc_l(wc, fp, __get_locale()); } diff --git a/lib/libc/stdio/putwchar.c b/lib/libc/stdio/putwchar.c index 0ca9591e4f66..1c5ab256125a 100644 --- a/lib/libc/stdio/putwchar.c +++ b/lib/libc/stdio/putwchar.c @@ -1,58 +1,58 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" #undef putwchar /* * Synonym for fputwc(wc, stdout). */ wint_t putwchar_l(wchar_t wc, locale_t locale) { FIX_LOCALE(locale); return (fputwc_l(wc, stdout, locale)); } wint_t putwchar(wchar_t wc) { return putwchar_l(wc, __get_locale()); } diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c index 9d6e4355c856..1f84f9ab6542 100644 --- a/lib/libc/stdio/scanf.c +++ b/lib/libc/stdio/scanf.c @@ -1,78 +1,78 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" int scanf(char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); FLOCKFILE_CANCELSAFE(stdin); ret = __svfscanf(stdin, __get_locale(), fmt, ap); FUNLOCKFILE_CANCELSAFE(); va_end(ap); return (ret); } int scanf_l(locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); FLOCKFILE_CANCELSAFE(stdin); ret = __svfscanf(stdin, locale, fmt, ap); FUNLOCKFILE_CANCELSAFE(); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c index 4e9379d391bc..45a9e3d7d622 100644 --- a/lib/libc/stdio/snprintf.c +++ b/lib/libc/stdio/snprintf.c @@ -1,105 +1,105 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" #include "local.h" int snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...) { size_t on; int ret; va_list ap; FILE f = FAKE_FILE; on = n; if (n != 0) n--; if (n > INT_MAX) { errno = EOVERFLOW; *str = '\0'; return (EOF); } va_start(ap, fmt); f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; ret = __vfprintf(&f, __get_locale(), fmt, ap); if (on > 0) *f._p = '\0'; va_end(ap); return (ret); } int snprintf_l(char * __restrict str, size_t n, locale_t locale, char const * __restrict fmt, ...) { size_t on; int ret; va_list ap; FILE f = FAKE_FILE; FIX_LOCALE(locale); on = n; if (n != 0) n--; if (n > INT_MAX) { errno = EOVERFLOW; *str = '\0'; return (EOF); } va_start(ap, fmt); f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; ret = __vfprintf(&f, locale, fmt, ap); if (on > 0) *f._p = '\0'; va_end(ap); return (ret); } diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index 94ec7e45cff5..c83efdb3f357 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -1,73 +1,73 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include "local.h" #include "xlocale_private.h" int sprintf(char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsprintf(str, fmt, ap); va_end(ap); return (ret); } int sprintf_l(char * __restrict str, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); ret = vsprintf_l(str, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c index 580316538c63..a06aac85a676 100644 --- a/lib/libc/stdio/sscanf.c +++ b/lib/libc/stdio/sscanf.c @@ -1,72 +1,72 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "local.h" int sscanf(const char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsscanf(str, fmt, ap); va_end(ap); return (ret); } int sscanf_l(const char * __restrict str, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsscanf_l(str, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/swprintf.c b/lib/libc/stdio/swprintf.c index 4113a8b77a1c..4c4db2accb76 100644 --- a/lib/libc/stdio/swprintf.c +++ b/lib/libc/stdio/swprintf.c @@ -1,64 +1,64 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int swprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vswprintf(s, n, fmt, ap); va_end(ap); return (ret); } int swprintf_l(wchar_t * __restrict s, size_t n, locale_t locale, const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vswprintf_l(s, n, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/swscanf.c b/lib/libc/stdio/swscanf.c index 494f4fba1b18..20bf266dc772 100644 --- a/lib/libc/stdio/swscanf.c +++ b/lib/libc/stdio/swscanf.c @@ -1,64 +1,64 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int swscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vswscanf(str, fmt, ap); va_end(ap); return (r); } int swscanf_l(const wchar_t * __restrict str, locale_t locale, const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vswscanf_l(str, locale, fmt, ap); va_end(ap); return (r); } diff --git a/lib/libc/stdio/ungetwc.c b/lib/libc/stdio/ungetwc.c index 2e3607c49ea7..a4c71d012be0 100644 --- a/lib/libc/stdio/ungetwc.c +++ b/lib/libc/stdio/ungetwc.c @@ -1,90 +1,90 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "mblocal.h" #include "xlocale_private.h" /* * Non-MT-safe version. */ wint_t __ungetwc(wint_t wc, FILE *fp, locale_t locale) { char buf[MB_LEN_MAX]; size_t len; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); if (wc == WEOF) return (WEOF); if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } while (len-- != 0) if (__ungetc((unsigned char)buf[len], fp) == EOF) return (WEOF); return (wc); } /* * MT-safe version. */ wint_t ungetwc_l(wint_t wc, FILE *fp, locale_t locale) { wint_t r; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); r = __ungetwc(wc, fp, locale); FUNLOCKFILE_CANCELSAFE(); return (r); } wint_t ungetwc(wint_t wc, FILE *fp) { return ungetwc_l(wc, fp, __get_locale()); } diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c index bb4c79873f92..2e5f8dd4107a 100644 --- a/lib/libc/stdio/vasprintf.c +++ b/lib/libc/stdio/vasprintf.c @@ -1,74 +1,74 @@ /* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $ */ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1997 Todd C. Miller * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. 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 ``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 #include #include #include #include "xlocale_private.h" #include "local.h" int vasprintf_l(char **str, locale_t locale, const char *fmt, __va_list ap) { FILE f = FAKE_FILE; int ret; FIX_LOCALE(locale); f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = malloc(128); if (f._bf._base == NULL) { *str = NULL; errno = ENOMEM; return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ ret = __vfprintf(&f, locale, fmt, ap); if (ret < 0) { free(f._bf._base); *str = NULL; errno = ENOMEM; return (-1); } *f._p = '\0'; *str = (char *)f._bf._base; return (ret); } int vasprintf(char **str, const char *fmt, __va_list ap) { return vasprintf_l(str, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vdprintf.c b/lib/libc/stdio/vdprintf.c index e4225987bcf4..a84efaa14b4d 100644 --- a/lib/libc/stdio/vdprintf.c +++ b/lib/libc/stdio/vdprintf.c @@ -1,70 +1,70 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2009 David Schultz * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "local.h" #include "xlocale_private.h" int vdprintf(int fd, const char * __restrict fmt, va_list ap) { FILE f = FAKE_FILE; unsigned char buf[BUFSIZ]; int ret; if (fd > SHRT_MAX) { errno = EMFILE; return (EOF); } f._p = buf; f._w = sizeof(buf); f._flags = __SWR; f._file = fd; f._cookie = &f; f._write = __swrite; f._bf._base = buf; f._bf._size = sizeof(buf); if ((ret = __vfprintf(&f, __get_locale(), fmt, ap)) < 0) return (ret); return (__fflush(&f) ? EOF : ret); } diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index c4531e87c984..ad655c5d78d4 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -1,1052 +1,1052 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include /* * Actual printf innards. * * This code is large and complicated... */ #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xlocale_private.h" #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "fvwrite.h" #include "printflocal.h" static int __sprint(FILE *, struct __suio *, locale_t); static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0) __noinline; static char *__wcsconv(wchar_t *, int); #define CHAR char #include "printfcommon.h" struct grouping_state { char *thousands_sep; /* locale-specific thousands separator */ int thousep_len; /* length of thousands_sep */ const char *grouping; /* locale-specific numeric grouping rules */ int lead; /* sig figs before decimal or group sep */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ }; /* * Initialize the thousands' grouping state in preparation to print a * number with ndigits digits. This routine returns the total number * of bytes that will be needed. */ static int grouping_init(struct grouping_state *gs, int ndigits, locale_t loc) { struct lconv *locale; locale = localeconv_l(loc); gs->grouping = locale->grouping; gs->thousands_sep = locale->thousands_sep; gs->thousep_len = strlen(gs->thousands_sep); gs->nseps = gs->nrepeats = 0; gs->lead = ndigits; while (*gs->grouping != CHAR_MAX) { if (gs->lead <= *gs->grouping) break; gs->lead -= *gs->grouping; if (*(gs->grouping+1)) { gs->nseps++; gs->grouping++; } else gs->nrepeats++; } return ((gs->nseps + gs->nrepeats) * gs->thousep_len); } /* * Print a number with thousands' separators. */ static int grouping_print(struct grouping_state *gs, struct io_state *iop, const CHAR *cp, const CHAR *ep, locale_t locale) { const CHAR *cp0 = cp; if (io_printandpad(iop, cp, ep, gs->lead, zeroes, locale)) return (-1); cp += gs->lead; while (gs->nseps > 0 || gs->nrepeats > 0) { if (gs->nrepeats > 0) gs->nrepeats--; else { gs->grouping--; gs->nseps--; } if (io_print(iop, gs->thousands_sep, gs->thousep_len, locale)) return (-1); if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, locale)) return (-1); cp += *gs->grouping; } if (cp > ep) cp = ep; return (cp - cp0); } /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ static int __sprint(FILE *fp, struct __suio *uio, locale_t locale) { int err; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; return (0); } err = __sfvwrite(fp, uio); uio->uio_resid = 0; uio->uio_iovcnt = 0; return (err); } /* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, locale_t locale, const char *fmt, va_list ap) { int ret; FILE fake = FAKE_FILE; unsigned char buf[BUFSIZ]; /* XXX This is probably not needed. */ if (prepwrite(fp) != 0) return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; fake._orientation = fp->_orientation; fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfprintf(&fake, locale, fmt, ap); if (ret >= 0 && __fflush(&fake)) ret = EOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); } /* * Convert a wide character string argument for the %ls format to a multibyte * string representation. If not -1, prec specifies the maximum number of * bytes to output, and also means that we can't assume that the wide char. * string ends is null-terminated. */ static char * __wcsconv(wchar_t *wcsarg, int prec) { static const mbstate_t initial; mbstate_t mbs; char buf[MB_LEN_MAX]; wchar_t *p; char *convbuf; size_t clen, nbytes; /* Allocate space for the maximum number of bytes we could output. */ if (prec < 0) { p = wcsarg; mbs = initial; nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); if (nbytes == (size_t)-1) return (NULL); } else { /* * Optimisation: if the output precision is small enough, * just allocate enough memory for the maximum instead of * scanning the string. */ if (prec < 128) nbytes = prec; else { nbytes = 0; p = wcsarg; mbs = initial; for (;;) { clen = wcrtomb(buf, *p++, &mbs); if (clen == 0 || clen == (size_t)-1 || nbytes + clen > prec) break; nbytes += clen; } } } if ((convbuf = malloc(nbytes + 1)) == NULL) return (NULL); /* Fill the output buffer. */ p = wcsarg; mbs = initial; if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p, nbytes, &mbs)) == (size_t)-1) { free(convbuf); return (NULL); } convbuf[nbytes] = '\0'; return (convbuf); } /* * MT-safe version */ int vfprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt0, va_list ap) { int ret; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && fp->_file >= 0) ret = __sbprintf(fp, locale, fmt0, ap); else ret = __vfprintf(fp, locale, fmt0, ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } int vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) { return vfprintf_l(fp, __get_locale(), fmt0, ap); } /* * The size of the buffer we use as scratch space for integer * conversions, among other things. We need enough space to * write a uintmax_t in octal (plus one byte). */ #if UINTMAX_MAX <= UINT64_MAX #define BUF 32 #else #error "BUF must be large enough to format a uintmax_t" #endif /* * Non-MT-safe version */ int __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) { char *fmt; /* format string */ int ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ char *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ int saved_errno; 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: * * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ * A B ---C--- D E F * * A: 'sign' holds this value if present; '\0' otherwise * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal * C: cp points to the string MMMNNN. Leading and trailing * zeros are not in the string and must be added. * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ char *decimal_point; /* locale specific decimal point */ int decpt_len; /* length of decimal_point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; long double ldbl; } fparg; int expt; /* integer value of exponent */ char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ 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 */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for %[xX] conversion */ struct io_state io; /* I/O buffering state */ char buf[BUF]; /* buffer with space for digits of uintmax_t */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ char *convbuf; /* wide to multibyte conversion result */ int savserr; static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) { \ if (io_print(&io, (ptr), (len), locale)) \ goto error; \ } #define PAD(howmany, with) { \ if (io_pad(&io, (howmany), (with), locale)) \ goto error; \ } #define PRINTANDPAD(p, ep, len, with) { \ if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \ goto error; \ } #define FLUSH() { \ if (io_flush(&io, locale)) \ goto error; \ } /* * Get the argument indexed by nextarg. If the argument table is * built, use it to get the argument. If its not, get the next * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ #define SARG() \ (flags&LONGINT ? GETARG(long) : \ flags&SHORTINT ? (long)(short)GETARG(int) : \ flags&CHARINT ? (long)(signed char)GETARG(int) : \ (long)GETARG(int)) #define UARG() \ (flags&LONGINT ? GETARG(u_long) : \ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ (u_long)GETARG(u_int)) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* * Get * arguments, including the form *nn$. Preserve the nextarg * that the argument can be gotten once the type is determined. */ #define GETASTER(val) \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ if (__find_arguments (fmt0, orgap, &argtable)) { \ ret = EOF; \ goto error; \ } \ } \ nextarg = n2; \ val = GETARG (int); \ nextarg = hold; \ fmt = ++cp; \ } else { \ val = GETARG (int); \ } if (__use_xprintf == 0 && getenv("USE_XPRINTF")) __use_xprintf = 1; if (__use_xprintf > 0) return (__xvprintf(fp, fmt0, ap)); /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (prepwrite(fp) != 0) { errno = EBADF; return (EOF); } savserr = fp->_flags & __SERR; fp->_flags &= ~__SERR; saved_errno = errno; convbuf = NULL; fmt = (char *)fmt0; argtable = NULL; nextarg = 1; 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). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; errno = EOVERFLOW; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) goto rflag; width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (prec); goto rflag; } prec = 0; while (is_digit(ch)) { prec = 10 * prec + to_digit(ch); ch = *fmt++; } goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; if (argtable == NULL) { argtable = statargtable; if (__find_arguments (fmt0, orgap, &argtable)) { ret = EOF; goto error; } } goto rflag; } width = n; goto reswitch; #ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; #endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) { static const mbstate_t initial; mbstate_t mbs; size_t mbseqlen; mbs = initial; mbseqlen = wcrtomb(cp = buf, (wchar_t)GETARG(wint_t), &mbs); if (mbseqlen == (size_t)-1) { fp->_flags |= __SERR; goto error; } size = (int)mbseqlen; } else { *(cp = buf) = GETARG(int); size = 1; } sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } } else { ulval = SARG(); if ((long)ulval < 0) { ulval = -ulval; sign = '-'; } } base = 10; goto number; #ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; expchar = 'p'; } else { ox[1] = 'X'; xdigs = xdigs_upper; expchar = 'P'; } if (prec >= 0) prec++; if (dtoaresult != NULL) freedtoa(dtoaresult); if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend); } else { fparg.dbl = GETARG(double); dtoaresult = cp = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } if (prec < 0) prec = dtoaend - cp; if (expt == INT_MAX) ox[1] = '\0'; goto fp_common; case 'e': case 'E': expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; else prec++; goto fp_begin; case 'f': case 'F': expchar = '\0'; goto fp_begin; case 'g': case 'G': expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; fp_begin: if (prec < 0) prec = DEFPREC; if (dtoaresult != NULL) freedtoa(dtoaresult); if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = cp = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); } else { fparg.dbl = GETARG(double); dtoaresult = cp = dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); if (expt == 9999) expt = INT_MAX; } fp_common: if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ if (*cp == 'N') { cp = (ch >= 'a') ? "nan" : "NAN"; sign = '\0'; } else cp = (ch >= 'a') ? "inf" : "INF"; size = 3; flags &= ~ZEROPAD; break; } flags |= FPT; ndig = dtoaend - cp; if (ch == 'g' || ch == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (flags & ALT) prec -= expt; else prec = ndig - expt; if (prec < 0) prec = 0; } else { /* * Make %[gG] smell like %[eE], but * trim trailing zeroes if no # flag. */ if (!(flags & ALT)) prec = ndig; } } if (expchar) { expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) size += decpt_len; } else { /* space for digits before decimal point */ if (expt > 0) size = expt; else /* "0" */ size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + decpt_len; if ((flags & GROUPING) && expt > 0) size += grouping_init(&gs, expt, locale); } break; #endif /* !NO_FLOATING_POINT */ case 'm': cp = strerror(saved_errno); size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp); sign = '\0'; break; case 'n': /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ if (flags & LLONGINT) *GETARG(long long *) = ret; else if (flags & SIZET) *GETARG(ssize_t *) = (ssize_t)ret; else if (flags & PTRDIFFT) *GETARG(ptrdiff_t *) = ret; else if (flags & INTMAXT) *GETARG(intmax_t *) = ret; else if (flags & LONGINT) *GETARG(long *) = ret; else if (flags & SHORTINT) *GETARG(short *) = ret; else if (flags & CHARINT) *GETARG(signed char *) = ret; else *GETARG(int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 8; goto nosign; case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; flags = flags | INTMAXT; ox[1] = 'x'; goto nosign; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) { wchar_t *wcp; if (convbuf != NULL) free(convbuf); if ((wcp = GETARG(wchar_t *)) == NULL) cp = "(null)"; else { convbuf = __wcsconv(wcp, prec); if (convbuf == NULL) { fp->_flags |= __SERR; goto error; } cp = convbuf; } } else if ((cp = GETARG(char *)) == NULL) cp = "(null)"; size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': xdigs = xdigs_upper; goto hex; case 'x': xdigs = xdigs_lower; hex: if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) ox[1] = ch; flags &= ~GROUPING; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /*- * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 * * ``The C Standard is clear enough as is. The call * printf("%#.0o", 0) should print 0.'' * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { if (ujval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, flags & ALT, xdigs); } else { if (ulval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ abort(); if ((flags & GROUPING) && size != 0) size += grouping_init(&gs, size, locale); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; errno = EOVERFLOW; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) PRINT(&sign, 1); if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 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) { if (grouping_print(&gs, &io, cp, buf+BUF, locale) < 0) goto error; } else { PRINT(cp, size); } #ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) PRINT(decimal_point,decpt_len); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { if (gs.grouping) { n = grouping_print(&gs, &io, cp, dtoaend, locale); if (n < 0) goto error; cp += n; } else { PRINTANDPAD(cp, dtoaend, expt, zeroes); cp += expt; } if (prec || flags & ALT) PRINT(decimal_point,decpt_len); } PRINTANDPAD(cp, dtoaend, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { PRINT(cp++, 1); PRINT(decimal_point, decpt_len); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } } #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); error: va_end(orgap); #ifndef NO_FLOATING_POINT if (dtoaresult != NULL) freedtoa(dtoaresult); #endif if (convbuf != NULL) free(convbuf); if (__sferror(fp)) ret = EOF; else fp->_flags |= savserr; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); /* NOTREACHED */ } diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c index 38801af4723b..cc2e1e428321 100644 --- a/lib/libc/stdio/vfscanf.c +++ b/lib/libc/stdio/vfscanf.c @@ -1,1092 +1,1092 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "collate.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" #ifndef NO_FLOATING_POINT #include #endif #define BUF 513 /* Maximum length of numeric string. */ /* * Flags used during conversion. */ #define LONG 0x01 /* l: long or double */ #define LONGDBL 0x02 /* L: long double */ #define SHORT 0x04 /* h: short */ #define SUPPRESS 0x08 /* *: suppress assignment */ #define POINTER 0x10 /* p: void * (as hex) */ #define NOSKIP 0x20 /* [ or c: do not skip blanks */ #define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ #define INTMAXT 0x800 /* j: intmax_t */ #define PTRDIFFT 0x1000 /* t: ptrdiff_t */ #define SIZET 0x2000 /* z: size_t */ #define SHORTSHORT 0x4000 /* hh: char */ #define UNSIGNED 0x8000 /* %[oupxX] conversions */ /* * The following are used in integral conversions only: * SIGNOK, NDIGITS, PFXOK, and NZDIGITS */ #define SIGNOK 0x40 /* +/- is (still) legal */ #define NDIGITS 0x80 /* no digits detected */ #define PFXOK 0x100 /* 0x prefix is (still) legal */ #define NZDIGITS 0x200 /* no zero digits detected */ #define HAVESIGN 0x10000 /* sign detected */ /* * Conversion types. */ #define CT_CHAR 0 /* %c conversion */ #define CT_CCL 1 /* %[...] conversion */ #define CT_STRING 2 /* %s conversion */ #define CT_INT 3 /* %[dioupxX] conversion */ #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); /* * Conversion functions are passed a pointer to this object instead of * a real parameter to indicate that the assignment-suppression (*) * flag was specified. We could use a NULL pointer to indicate this, * but that would mask bugs in applications that call scanf() with a * NULL pointer. */ static const int suppress; #define SUPPRESS_PTR ((void *)&suppress) static const mbstate_t initial_mbs; /* * The following conversion functions return the number of characters consumed, * or -1 on input failure. Character class conversion returns 0 on match * failure. */ static __inline int convert_char(FILE *fp, char * p, int width) { int n; if (p == SUPPRESS_PTR) { size_t sum = 0; for (;;) { if ((n = fp->_r) < width) { sum += n; width -= n; fp->_p += n; if (__srefill(fp)) { if (sum == 0) return (-1); break; } } else { sum += width; fp->_r -= width; fp->_p += width; break; } } return (sum); } else { size_t r = __fread(p, 1, width, fp); if (r == 0) return (-1); return (r); } } static __inline int convert_wchar(FILE *fp, wchar_t *wcp, int width, locale_t locale) { mbstate_t mbs; int n, nread; wint_t wi; mbs = initial_mbs; n = 0; while (width-- != 0 && (wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF) { if (wcp != SUPPRESS_PTR) *wcp++ = (wchar_t)wi; n += nread; } if (n == 0) return (-1); return (n); } static __inline int convert_ccl(FILE *fp, char * p, int width, const char *ccltab) { char *p0; int n; if (p == SUPPRESS_PTR) { n = 0; while (ccltab[*fp->_p]) { n++, fp->_r--, fp->_p++; if (--width == 0) break; if (fp->_r <= 0 && __srefill(fp)) { if (n == 0) return (-1); break; } } } else { p0 = p; while (ccltab[*fp->_p]) { fp->_r--; *p++ = *fp->_p++; if (--width == 0) break; if (fp->_r <= 0 && __srefill(fp)) { if (p == p0) return (-1); break; } } n = p - p0; if (n == 0) return (0); *p = 0; } return (n); } static __inline int convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab, locale_t locale) { mbstate_t mbs; wint_t wi; int n, nread; mbs = initial_mbs; n = 0; if (wcp == SUPPRESS_PTR) { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && ccltab[wctob(wi)]) n += nread; if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); } else { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && ccltab[wctob(wi)]) { *wcp++ = (wchar_t)wi; n += nread; } if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); if (n == 0) return (0); *wcp = 0; } return (n); } static __inline int convert_string(FILE *fp, char * p, int width) { char *p0; int n; if (p == SUPPRESS_PTR) { n = 0; while (!isspace(*fp->_p)) { n++, fp->_r--, fp->_p++; if (--width == 0) break; if (fp->_r <= 0 && __srefill(fp)) break; } } else { p0 = p; while (!isspace(*fp->_p)) { fp->_r--; *p++ = *fp->_p++; if (--width == 0) break; if (fp->_r <= 0 && __srefill(fp)) break; } *p = 0; n = p - p0; } return (n); } static __inline int convert_wstring(FILE *fp, wchar_t *wcp, int width, locale_t locale) { mbstate_t mbs; wint_t wi; int n, nread; mbs = initial_mbs; n = 0; if (wcp == SUPPRESS_PTR) { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && !iswspace(wi)) n += nread; if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); } else { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && !iswspace(wi)) { *wcp++ = (wchar_t)wi; n += nread; } if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); *wcp = '\0'; } return (n); } /* * Read an integer, storing it in buf. The only relevant bit in the * flags argument is PFXOK. * * Return 0 on a match failure, and the number of characters read * otherwise. */ static __inline int parseint(FILE *fp, char * __restrict buf, int width, int base, int flags) { /* `basefix' is used to avoid `if' tests */ static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; char *p; int c; flags |= SIGNOK | NDIGITS | NZDIGITS; for (p = buf; width; width--) { c = *fp->_p; /* * Switch on the character; `goto ok' if we accept it * as a part of number. */ switch (c) { /* * The digit 0 is always legal, but is special. For * %i conversions, if no digits (zero or nonzero) have * been scanned (only signs), we will have base==0. * In that case, we should set it to 8 and enable 0x * prefixing. Also, if we have not scanned zero * digits before this, do not turn off prefixing * (someone else will turn it off if we have scanned * any nonzero digits). */ case '0': if (base == 0) { base = 8; flags |= PFXOK; } if (flags & NZDIGITS) flags &= ~(SIGNOK|NZDIGITS|NDIGITS); else flags &= ~(SIGNOK|PFXOK|NDIGITS); goto ok; /* 1 through 7 always legal */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': base = basefix[base]; flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* digits 8 and 9 ok iff decimal or hex */ case '8': case '9': base = basefix[base]; if (base <= 8) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* letters ok iff hex */ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': /* no need to fix base here */ if (base <= 10) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* sign ok only as first character */ case '+': case '-': if (flags & SIGNOK) { flags &= ~SIGNOK; flags |= HAVESIGN; goto ok; } break; /* * x ok iff flag still set & 2nd char (or 3rd char if * we have a sign). */ case 'x': case 'X': if (flags & PFXOK && p == buf + 1 + !!(flags & HAVESIGN)) { base = 16; /* if %i */ flags &= ~PFXOK; goto ok; } break; } /* * If we got here, c is not a legal character for a * number. Stop accumulating digits. */ break; ok: /* * c is legal: store it and look at the next. */ *p++ = c; if (--fp->_r > 0) fp->_p++; else if (__srefill(fp)) break; /* EOF */ } /* * If we had only a sign, it is no good; push back the sign. * If the number ends in `x', it was [sign] '0' 'x', so push * back the x and treat it as [sign] '0'. */ if (flags & NDIGITS) { if (p > buf) (void) __ungetc(*(u_char *)--p, fp); return (0); } c = ((u_char *)p)[-1]; if (c == 'x' || c == 'X') { --p; (void) __ungetc(c, fp); } return (p - buf); } /* * __vfscanf - MT-safe version */ int __vfscanf(FILE *fp, char const *fmt0, va_list ap) { int ret; FLOCKFILE_CANCELSAFE(fp); ret = __svfscanf(fp, __get_locale(), fmt0, ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } int vfscanf_l(FILE *fp, locale_t locale, char const *fmt0, va_list ap) { int ret; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ret = __svfscanf(fp, locale, fmt0, ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } /* * __svfscanf - non-MT-safe version of __vfscanf */ int __svfscanf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) { #define GETARG(type) ((flags & SUPPRESS) ? SUPPRESS_PTR : va_arg(ap, type)) const u_char *fmt = (const u_char *)fmt0; int c; /* character from format, or conversion */ size_t width; /* field width, or 0 */ int flags; /* flags as defined above */ int nassigned; /* number of fields assigned */ int nconversions; /* number of conversions */ int nr; /* characters read by the current conversion */ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ char ccltab[256]; /* character class table for %[...] */ char buf[BUF]; /* buffer for numeric conversions */ ORIENT(fp, -1); nassigned = 0; nconversions = 0; nread = 0; for (;;) { c = *fmt++; if (c == 0) return (nassigned); if (isspace(c)) { while ((fp->_r > 0 || __srefill(fp) == 0) && isspace(*fp->_p)) nread++, fp->_r--, fp->_p++; continue; } if (c != '%') goto literal; width = 0; flags = 0; /* * switch on the format. continue if done; * break once format type is derived. */ again: c = *fmt++; switch (c) { case '%': literal: if (fp->_r <= 0 && __srefill(fp)) goto input_failure; if (*fp->_p != c) goto match_failure; fp->_r--, fp->_p++; nread++; continue; case '*': flags |= SUPPRESS; goto again; case 'j': flags |= INTMAXT; goto again; case 'l': if (flags & LONG) { flags &= ~LONG; flags |= LONGLONG; } else flags |= LONG; goto again; case 'q': flags |= LONGLONG; /* not quite */ goto again; case 't': flags |= PTRDIFFT; goto again; case 'z': flags |= SIZET; goto again; case 'L': flags |= LONGDBL; goto again; case 'h': if (flags & SHORT) { flags &= ~SHORT; flags |= SHORTSHORT; } else flags |= SHORT; goto again; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': width = width * 10 + c - '0'; goto again; /* * Conversions. */ case 'd': c = CT_INT; base = 10; break; case 'i': c = CT_INT; base = 0; break; case 'o': c = CT_INT; flags |= UNSIGNED; base = 8; break; case 'u': c = CT_INT; flags |= UNSIGNED; base = 10; break; case 'X': case 'x': flags |= PFXOK; /* enable 0x prefixing */ c = CT_INT; flags |= UNSIGNED; 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; /* FALLTHROUGH */ case 's': c = CT_STRING; break; case '[': fmt = __sccl(ccltab, fmt); flags |= NOSKIP; c = CT_CCL; break; case 'C': flags |= LONG; /* FALLTHROUGH */ case 'c': flags |= NOSKIP; c = CT_CHAR; break; case 'p': /* pointer format is like hex */ flags |= POINTER | PFXOK; c = CT_INT; /* assumes sizeof(uintmax_t) */ flags |= UNSIGNED; /* >= sizeof(uintptr_t) */ base = 16; break; case 'n': if (flags & SUPPRESS) /* ??? */ continue; if (flags & SHORTSHORT) *va_arg(ap, char *) = nread; else if (flags & SHORT) *va_arg(ap, short *) = nread; else if (flags & LONG) *va_arg(ap, long *) = nread; else if (flags & LONGLONG) *va_arg(ap, long long *) = nread; else if (flags & INTMAXT) *va_arg(ap, intmax_t *) = nread; else if (flags & SIZET) *va_arg(ap, size_t *) = nread; else if (flags & PTRDIFFT) *va_arg(ap, ptrdiff_t *) = nread; else *va_arg(ap, int *) = nread; continue; default: goto match_failure; /* * Disgusting backwards compatibility hack. XXX */ case '\0': /* compat */ return (EOF); } /* * We have a conversion that requires input. */ if (fp->_r <= 0 && __srefill(fp)) goto input_failure; /* * Consume leading white space, except for formats * that suppress this. */ if ((flags & NOSKIP) == 0) { while (isspace(*fp->_p)) { nread++; if (--fp->_r > 0) fp->_p++; else if (__srefill(fp)) goto input_failure; } /* * Note that there is at least one character in * the buffer, so conversions that do not set NOSKIP * ca no longer result in an input failure. */ } /* * Do the conversion. */ switch (c) { case CT_CHAR: /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; if (flags & LONG) { nr = convert_wchar(fp, GETARG(wchar_t *), width, locale); } else { nr = convert_char(fp, GETARG(char *), width); } if (nr < 0) goto input_failure; break; case CT_CCL: /* scan a (nonempty) character class (sets NOSKIP) */ if (width == 0) width = (size_t)~0; /* `infinity' */ if (flags & LONG) { nr = convert_wccl(fp, GETARG(wchar_t *), width, ccltab, locale); } else { nr = convert_ccl(fp, GETARG(char *), width, ccltab); } if (nr <= 0) { if (nr < 0) goto input_failure; else /* nr == 0 */ goto match_failure; } break; case CT_STRING: /* like CCL, but zero-length string OK, & no NOSKIP */ if (width == 0) width = (size_t)~0; if (flags & LONG) { nr = convert_wstring(fp, GETARG(wchar_t *), width, locale); } else { nr = convert_string(fp, GETARG(char *), width); } if (nr < 0) goto input_failure; break; case CT_INT: /* scan an integer as if by the conversion function */ #ifdef hardway if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1; #else /* size_t is unsigned, hence this optimisation */ if (--width > sizeof(buf) - 2) width = sizeof(buf) - 2; width++; #endif nr = parseint(fp, buf, width, base, flags); if (nr == 0) goto match_failure; if ((flags & SUPPRESS) == 0) { uintmax_t res; buf[nr] = '\0'; if ((flags & UNSIGNED) == 0) res = strtoimax_l(buf, (char **)NULL, base, locale); else res = strtoumax_l(buf, (char **)NULL, base, locale); if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; else if (flags & SHORTSHORT) *va_arg(ap, char *) = res; else if (flags & SHORT) *va_arg(ap, short *) = res; else if (flags & LONG) *va_arg(ap, long *) = res; else if (flags & LONGLONG) *va_arg(ap, long long *) = res; else if (flags & INTMAXT) *va_arg(ap, intmax_t *) = res; else if (flags & PTRDIFFT) *va_arg(ap, ptrdiff_t *) = res; else if (flags & SIZET) *va_arg(ap, size_t *) = res; else *va_arg(ap, int *) = res; } break; #ifndef NO_FLOATING_POINT case CT_FLOAT: /* scan a floating point number as if by strtod */ if (width == 0 || width > sizeof(buf) - 1) width = sizeof(buf) - 1; nr = parsefloat(fp, buf, buf + width, locale); if (nr == 0) goto match_failure; if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { long double res = strtold_l(buf, NULL, locale); *va_arg(ap, long double *) = res; } else if (flags & LONG) { double res = strtod_l(buf, NULL, locale); *va_arg(ap, double *) = res; } else { float res = strtof_l(buf, NULL, locale); *va_arg(ap, float *) = res; } } break; #endif /* !NO_FLOATING_POINT */ } if (!(flags & SUPPRESS)) nassigned++; nread += nr; nconversions++; } input_failure: return (nconversions != 0 ? nassigned : EOF); match_failure: return (nassigned); } /* * Fill in the given table from the scanset at the given format * (just after `['). Return a pointer to the character past the * closing `]'. The table has a 1 wherever characters should be * considered part of the scanset. */ static const u_char * __sccl(char *tab, const u_char *fmt) { int c, n, v, i; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* first `clear' the whole table */ c = *fmt++; /* first char hat => negated scanset */ if (c == '^') { v = 1; /* default => accept */ c = *fmt++; /* get new first char */ } else v = 0; /* default => reject */ /* XXX: Will not work if sizeof(tab*) > sizeof(char) */ (void) memset(tab, v, 256); if (c == 0) return (fmt - 1);/* format ended before closing ] */ /* * Now set the entries corresponding to the actual scanset * to the opposite of the above. * * The first character may be ']' (or '-') without being special; * the last character may be '-'. */ v = 1 - v; for (;;) { tab[c] = v; /* take character c */ doswitch: n = *fmt++; /* and examine the next */ switch (n) { case 0: /* format ended too soon */ return (fmt - 1); case '-': /* * A scanset of the form * [01+-] * is defined as `the digit 0, the digit 1, * the character +, the character -', but * the effect of a scanset such as * [a-zA-Z0-9] * is implementation defined. The V7 Unix * scanf treats `a-z' as `the letters a through * z', but treats `a-a' as `the letter a, the * character -, and the letter a'. * * For compatibility, the `-' is not considered * to define a range if the character following * it is either a close bracket (required by ANSI) * or is not numerically greater than the character * we just stored in the table (c). */ n = *fmt; if (n == ']' || (table->__collate_load_error ? n < c : __collate_range_cmp(n, c) < 0 ) ) { c = '-'; break; /* resume the for(;;) */ } fmt++; /* fill in the range */ if (table->__collate_load_error) { do { tab[++c] = v; } while (c < n); } else { for (i = 0; i < 256; i ++) if (__collate_range_cmp(c, i) <= 0 && __collate_range_cmp(i, n) <= 0 ) tab[i] = v; } #if 1 /* XXX another disgusting compatibility hack */ c = n; /* * Alas, the V7 Unix scanf also treats formats * such as [a-c-e] as `the letters a through e'. * This too is permitted by the standard.... */ goto doswitch; #else c = *fmt++; if (c == 0) return (fmt - 1); if (c == ']') return (fmt); #endif break; case ']': /* end of scanset */ return (fmt); default: /* just another character */ c = n; break; } } /* NOTREACHED */ } #ifndef NO_FLOATING_POINT static int parsefloat(FILE *fp, char *buf, char *end, locale_t locale) { char *commit, *p; int infnanpos = 0, decptpos = 0; enum { S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, S_DIGITS, S_DECPT, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; unsigned char c; const char *decpt = localeconv_l(locale)->decimal_point; _Bool gotmantdig = 0, ishex = 0; /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point * number by itself. At some point, the parse will complete * or fail, and we will ungetc() back to the last commit point. * To ensure that the file offset gets updated properly, it is * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ commit = buf - 1; for (p = buf; p < end; ) { c = *fp->_p; reswitch: switch (state) { case S_START: state = S_GOTSIGN; if (c == '-' || c == '+') break; else goto reswitch; case S_GOTSIGN: switch (c) { case '0': state = S_MAYBEHEX; commit = p; break; case 'I': case 'i': state = S_INF; break; case 'N': case 'n': state = S_NAN; break; default: state = S_DIGITS; goto reswitch; } break; case S_INF: if (infnanpos > 6 || (c != "nfinity"[infnanpos] && c != "NFINITY"[infnanpos])) goto parsedone; if (infnanpos == 1 || infnanpos == 6) commit = p; /* inf or infinity */ infnanpos++; break; case S_NAN: switch (infnanpos) { case 0: if (c != 'A' && c != 'a') goto parsedone; break; case 1: if (c != 'N' && c != 'n') goto parsedone; else commit = p; break; case 2: if (c != '(') goto parsedone; break; default: if (c == ')') { commit = p; state = S_DONE; } else if (!isalnum(c) && c != '_') goto parsedone; break; } infnanpos++; break; case S_DONE: goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { ishex = 1; break; } else { /* we saw a '0', but no 'x' */ gotmantdig = 1; goto reswitch; } case S_DIGITS: if ((ishex && isxdigit(c)) || isdigit(c)) { gotmantdig = 1; commit = p; break; } else { state = S_DECPT; goto reswitch; } case S_DECPT: if (c == decpt[decptpos]) { if (decpt[++decptpos] == '\0') { /* We read the complete decpt seq. */ state = S_FRAC; if (gotmantdig) commit = p; } break; } else if (!decptpos) { /* We didn't read any decpt characters. */ state = S_FRAC; goto reswitch; } else { /* * We read part of a multibyte decimal point, * but the rest is invalid, so bail. */ goto parsedone; } case S_FRAC: if (((c == 'E' || c == 'e') && !ishex) || ((c == 'P' || c == 'p') && ishex)) { if (!gotmantdig) goto parsedone; else state = S_EXP; } else if ((ishex && isxdigit(c)) || isdigit(c)) { commit = p; gotmantdig = 1; } else goto parsedone; break; case S_EXP: state = S_EXPDIGITS; if (c == '-' || c == '+') break; else goto reswitch; case S_EXPDIGITS: if (isdigit(c)) commit = p; else goto parsedone; break; default: abort(); } *p++ = c; if (--fp->_r > 0) fp->_p++; else if (__srefill(fp)) break; /* EOF */ } parsedone: while (commit < --p) __ungetc(*(u_char *)p, fp); *++commit = '\0'; return (commit - buf); } #endif diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index 6f25d3d9c94a..fc681e8d0575 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -1,1109 +1,1109 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include /* * Actual wprintf innards. * * Avoid making gratuitous changes to this source file; it should be kept * as close as possible to vfprintf.c for ease of maintenance. */ #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "fvwrite.h" #include "printflocal.h" #include "xlocale_private.h" static int __sprint(FILE *, struct __suio *, locale_t); static int __sbprintf(FILE *, locale_t, const wchar_t *, va_list) __noinline; static wint_t __xfputwc(wchar_t, FILE *, locale_t); static wchar_t *__mbsconv(char *, int); #define CHAR wchar_t #include "printfcommon.h" struct grouping_state { wchar_t thousands_sep; /* locale-specific thousands separator */ const char *grouping; /* locale-specific numeric grouping rules */ int lead; /* sig figs before decimal or group sep */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ }; static const mbstate_t initial_mbs; static inline wchar_t get_decpt(locale_t locale) { mbstate_t mbs; wchar_t decpt; int nconv; mbs = initial_mbs; nconv = mbrtowc(&decpt, localeconv_l(locale)->decimal_point, MB_CUR_MAX, &mbs); if (nconv == (size_t)-1 || nconv == (size_t)-2) decpt = '.'; /* failsafe */ return (decpt); } static inline wchar_t get_thousep(locale_t locale) { mbstate_t mbs; wchar_t thousep; int nconv; mbs = initial_mbs; nconv = mbrtowc(&thousep, localeconv_l(locale)->thousands_sep, MB_CUR_MAX, &mbs); if (nconv == (size_t)-1 || nconv == (size_t)-2) thousep = '\0'; /* failsafe */ return (thousep); } /* * Initialize the thousands' grouping state in preparation to print a * number with ndigits digits. This routine returns the total number * of wide characters that will be printed. */ static int grouping_init(struct grouping_state *gs, int ndigits, locale_t locale) { gs->grouping = localeconv_l(locale)->grouping; gs->thousands_sep = get_thousep(locale); gs->nseps = gs->nrepeats = 0; gs->lead = ndigits; while (*gs->grouping != CHAR_MAX) { if (gs->lead <= *gs->grouping) break; gs->lead -= *gs->grouping; if (*(gs->grouping+1)) { gs->nseps++; gs->grouping++; } else gs->nrepeats++; } return (gs->nseps + gs->nrepeats); } /* * Print a number with thousands' separators. */ static int grouping_print(struct grouping_state *gs, struct io_state *iop, const CHAR *cp, const CHAR *ep, locale_t locale) { const CHAR *cp0 = cp; if (io_printandpad(iop, cp, ep, gs->lead, zeroes, locale)) return (-1); cp += gs->lead; while (gs->nseps > 0 || gs->nrepeats > 0) { if (gs->nrepeats > 0) gs->nrepeats--; else { gs->grouping--; gs->nseps--; } if (io_print(iop, &gs->thousands_sep, 1, locale)) return (-1); if (io_printandpad(iop, cp, ep, *gs->grouping, zeroes, locale)) return (-1); cp += *gs->grouping; } if (cp > ep) cp = ep; return (cp - cp0); } /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. * * XXX The fact that we do this a character at a time and convert to a * multibyte character sequence even if the destination is a wide * string eclipses the benefits of buffering. */ static int __sprint(FILE *fp, struct __suio *uio, locale_t locale) { struct __siov *iov; wchar_t *p; int i, len; iov = uio->uio_iov; for (; uio->uio_resid != 0; uio->uio_resid -= len, iov++) { p = (wchar_t *)iov->iov_base; len = iov->iov_len; for (i = 0; i < len; i++) { if (__xfputwc(p[i], fp, locale) == WEOF) return (-1); } } uio->uio_iovcnt = 0; return (0); } /* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, locale_t locale, const wchar_t *fmt, va_list ap) { int ret; FILE fake; unsigned char buf[BUFSIZ]; /* XXX This is probably not needed. */ if (prepwrite(fp) != 0) return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; fake._orientation = fp->_orientation; fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfwprintf(&fake, locale, fmt, ap); if (ret >= 0 && __fflush(&fake)) ret = WEOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); } /* * Like __fputwc, but handles fake string (__SSTR) files properly. * File must already be locked. */ static wint_t __xfputwc(wchar_t wc, FILE *fp, locale_t locale) { mbstate_t mbs; char buf[MB_LEN_MAX]; struct __suio uio; struct __siov iov; size_t len; if ((fp->_flags & __SSTR) == 0) return (__fputwc(wc, fp, locale)); mbs = initial_mbs; if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { fp->_flags |= __SERR; return (WEOF); } uio.uio_iov = &iov; uio.uio_resid = len; uio.uio_iovcnt = 1; iov.iov_base = buf; iov.iov_len = len; return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF); } /* * Convert a multibyte character string argument for the %s format to a wide * string representation. ``prec'' specifies the maximum number of bytes * to output. If ``prec'' is greater than or equal to zero, we can't assume * that the multibyte char. string ends in a null character. */ static wchar_t * __mbsconv(char *mbsarg, int prec) { mbstate_t mbs; wchar_t *convbuf, *wcp; const char *p; size_t insize, nchars, nconv; if (mbsarg == NULL) return (NULL); /* * Supplied argument is a multibyte string; convert it to wide * characters first. */ if (prec >= 0) { /* * String is not guaranteed to be NUL-terminated. Find the * number of characters to print. */ p = mbsarg; insize = nchars = nconv = 0; mbs = initial_mbs; while (nchars != (size_t)prec) { nconv = mbrlen(p, MB_CUR_MAX, &mbs); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break; p += nconv; nchars++; insize += nconv; } if (nconv == (size_t)-1 || nconv == (size_t)-2) return (NULL); } else { insize = strlen(mbsarg); nconv = 0; } /* * Allocate buffer for the result and perform the conversion, * converting at most `size' bytes of the input multibyte string to * wide characters for printing. */ convbuf = malloc((insize + 1) * sizeof(*convbuf)); if (convbuf == NULL) return (NULL); wcp = convbuf; p = mbsarg; mbs = initial_mbs; while (insize != 0) { nconv = mbrtowc(wcp, p, insize, &mbs); if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break; wcp++; p += nconv; insize -= nconv; } if (nconv == (size_t)-1 || nconv == (size_t)-2) { free(convbuf); return (NULL); } *wcp = L'\0'; return (convbuf); } /* * MT-safe version */ int vfwprintf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt0, va_list ap) { int ret; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && fp->_file >= 0) ret = __sbprintf(fp, locale, fmt0, ap); else ret = __vfwprintf(fp, locale, fmt0, ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } int vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) { return vfwprintf_l(fp, __get_locale(), fmt0, ap); } /* * The size of the buffer we use as scratch space for integer * conversions, among other things. We need enough space to * write a uintmax_t in octal (plus one byte). */ #if UINTMAX_MAX <= UINT64_MAX #define BUF 32 #else #error "BUF must be large enough to format a uintmax_t" #endif /* * Non-MT-safe version */ int __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ int n, n2; /* handy integer (short term usage) */ wchar_t *cp; /* handy char pointer (short term usage) */ int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ 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: * * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ * A B ---C--- D E F * * A: 'sign' holds this value if present; '\0' otherwise * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal * C: cp points to the string MMMNNN. Leading and trailing * zeros are not in the string and must be added. * D: expchar holds this character; '\0' if no exponent, e.g. %f * F: at least two digits for decimal, at least one digit for hex */ wchar_t decimal_point; /* locale specific decimal point */ int signflag; /* true if float is negative */ union { /* floating point arguments %[aAeEfFgG] */ double dbl; long double ldbl; } fparg; int expt; /* integer value of exponent */ char expchar; /* exponent character: [eEpP\0] */ char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ 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 */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ int prsize; /* max size of printed field */ const char *xdigs; /* digits for [xX] conversion */ struct io_state io; /* I/O buffering state */ wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */ wchar_t ox[2]; /* space for 0x hex-prefix */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ wchar_t *convbuf; /* multibyte to wide conversion result */ int savserr; static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; /* BEWARE, these `goto error' on error. */ #define PRINT(ptr, len) do { \ if (io_print(&io, (ptr), (len), locale)) \ goto error; \ } while (0) #define PAD(howmany, with) { \ if (io_pad(&io, (howmany), (with), locale)) \ goto error; \ } #define PRINTANDPAD(p, ep, len, with) { \ if (io_printandpad(&io, (p), (ep), (len), (with), locale)) \ goto error; \ } #define FLUSH() { \ if (io_flush(&io, locale)) \ goto error; \ } /* * Get the argument indexed by nextarg. If the argument table is * built, use it to get the argument. If its not, get the next * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ #define SARG() \ (flags&LONGINT ? GETARG(long) : \ flags&SHORTINT ? (long)(short)GETARG(int) : \ flags&CHARINT ? (long)(signed char)GETARG(int) : \ (long)GETARG(int)) #define UARG() \ (flags&LONGINT ? GETARG(u_long) : \ flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \ flags&CHARINT ? (u_long)(u_char)GETARG(int) : \ (u_long)GETARG(u_int)) #define INTMAX_SIZE (INTMAXT|SIZET|PTRDIFFT|LLONGINT) #define SJARG() \ (flags&INTMAXT ? GETARG(intmax_t) : \ flags&SIZET ? (intmax_t)GETARG(ssize_t) : \ flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \ (intmax_t)GETARG(long long)) #define UJARG() \ (flags&INTMAXT ? GETARG(uintmax_t) : \ flags&SIZET ? (uintmax_t)GETARG(size_t) : \ flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \ (uintmax_t)GETARG(unsigned long long)) /* * Get * arguments, including the form *nn$. Preserve the nextarg * that the argument can be gotten once the type is determined. */ #define GETASTER(val) \ n2 = 0; \ cp = fmt; \ while (is_digit(*cp)) { \ n2 = 10 * n2 + to_digit(*cp); \ cp++; \ } \ if (*cp == '$') { \ int hold = nextarg; \ if (argtable == NULL) { \ argtable = statargtable; \ if (__find_warguments (fmt0, orgap, &argtable)) { \ ret = EOF; \ goto error; \ } \ } \ nextarg = n2; \ val = GETARG (int); \ nextarg = hold; \ fmt = ++cp; \ } else { \ val = GETARG (int); \ } /* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */ if (prepwrite(fp) != 0) { errno = EBADF; return (EOF); } savserr = fp->_flags & __SERR; fp->_flags &= ~__SERR; convbuf = NULL; fmt = (wchar_t *)fmt0; argtable = NULL; nextarg = 1; 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). */ for (;;) { for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) /* void */; if ((n = fmt - cp) != 0) { if ((unsigned)ret + n > INT_MAX) { ret = EOF; errno = EOVERFLOW; goto error; } PRINT(cp, n); ret += n; } if (ch == '\0') goto done; fmt++; /* skip over '%' */ flags = 0; dprec = 0; width = 0; prec = -1; gs.grouping = NULL; sign = '\0'; ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { case ' ': /*- * ``If the space and + flags both appear, the space * flag will be ignored.'' * -- ANSI X3J11 */ if (!sign) sign = ' '; goto rflag; case '#': flags |= ALT; goto rflag; case '*': /*- * ``A negative field width argument is taken as a * - flag followed by a positive field width.'' * -- ANSI X3J11 * They don't exclude field widths read from args. */ GETASTER (width); if (width >= 0) goto rflag; width = -width; /* FALLTHROUGH */ case '-': flags |= LADJUST; goto rflag; case '+': sign = '+'; goto rflag; case '\'': flags |= GROUPING; goto rflag; case '.': if ((ch = *fmt++) == '*') { GETASTER (prec); goto rflag; } prec = 0; while (is_digit(ch)) { prec = 10 * prec + to_digit(ch); ch = *fmt++; } goto reswitch; case '0': /*- * ``Note that 0 is taken as a flag, not as the * beginning of a field width.'' * -- ANSI X3J11 */ flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + to_digit(ch); ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { nextarg = n; if (argtable == NULL) { argtable = statargtable; if (__find_warguments (fmt0, orgap, &argtable)) { ret = EOF; goto error; } } goto rflag; } width = n; goto reswitch; #ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; #endif case 'h': if (flags & SHORTINT) { flags &= ~SHORTINT; flags |= CHARINT; } else flags |= SHORTINT; goto rflag; case 'j': flags |= INTMAXT; goto rflag; case 'l': if (flags & LONGINT) { flags &= ~LONGINT; flags |= LLONGINT; } else flags |= LONGINT; goto rflag; case 'q': flags |= LLONGINT; /* not necessarily */ goto rflag; case 't': flags |= PTRDIFFT; goto rflag; case 'z': flags |= SIZET; goto rflag; case 'C': flags |= LONGINT; /*FALLTHROUGH*/ case 'c': if (flags & LONGINT) *(cp = buf) = (wchar_t)GETARG(wint_t); else *(cp = buf) = (wchar_t)btowc(GETARG(int)); size = 1; sign = '\0'; break; case 'D': flags |= LONGINT; /*FALLTHROUGH*/ case 'd': case 'i': if (flags & INTMAX_SIZE) { ujval = SJARG(); if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } } else { ulval = SARG(); if ((long)ulval < 0) { ulval = -ulval; sign = '-'; } } base = 10; goto number; #ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { ox[1] = 'x'; xdigs = xdigs_lower; expchar = 'p'; } else { ox[1] = 'X'; xdigs = xdigs_upper; expchar = 'P'; } if (prec >= 0) prec++; if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = __hldtoa(fparg.ldbl, xdigs, prec, &expt, &signflag, &dtoaend); } else { fparg.dbl = GETARG(double); dtoaresult = __hdtoa(fparg.dbl, xdigs, prec, &expt, &signflag, &dtoaend); } if (prec < 0) prec = dtoaend - dtoaresult; if (expt == INT_MAX) ox[1] = '\0'; if (convbuf != NULL) free(convbuf); ndig = dtoaend - dtoaresult; cp = convbuf = __mbsconv(dtoaresult, -1); freedtoa(dtoaresult); goto fp_common; case 'e': case 'E': expchar = ch; if (prec < 0) /* account for digit before decpt */ prec = DEFPREC + 1; else prec++; goto fp_begin; case 'f': case 'F': expchar = '\0'; goto fp_begin; case 'g': case 'G': expchar = ch - ('g' - 'e'); if (prec == 0) prec = 1; fp_begin: if (prec < 0) prec = DEFPREC; if (convbuf != NULL) free(convbuf); if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); } else { fparg.dbl = GETARG(double); dtoaresult = dtoa(fparg.dbl, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); if (expt == 9999) expt = INT_MAX; } ndig = dtoaend - dtoaresult; cp = convbuf = __mbsconv(dtoaresult, -1); freedtoa(dtoaresult); fp_common: if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ if (*cp == 'N') { cp = (ch >= 'a') ? L"nan" : L"NAN"; sign = '\0'; } else cp = (ch >= 'a') ? L"inf" : L"INF"; size = 3; flags &= ~ZEROPAD; break; } flags |= FPT; if (ch == 'g' || ch == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (flags & ALT) prec -= expt; else prec = ndig - expt; if (prec < 0) prec = 0; } else { /* * Make %[gG] smell like %[eE], but * trim trailing zeroes if no # flag. */ if (!(flags & ALT)) prec = ndig; } } if (expchar) { expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || flags & ALT) ++size; } else { /* space for digits before decimal point */ if (expt > 0) size = expt; else /* "0" */ size = 1; /* space for decimal pt and following digits */ if (prec || flags & ALT) size += prec + 1; if ((flags & GROUPING) && expt > 0) size += grouping_init(&gs, expt, locale); } break; #endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the * value overflows or is otherwise unrepresentable. * C99 says to use `signed char' for %hhn conversions. */ if (flags & LLONGINT) *GETARG(long long *) = ret; else if (flags & SIZET) *GETARG(ssize_t *) = (ssize_t)ret; else if (flags & PTRDIFFT) *GETARG(ptrdiff_t *) = ret; else if (flags & INTMAXT) *GETARG(intmax_t *) = ret; else if (flags & LONGINT) *GETARG(long *) = ret; else if (flags & SHORTINT) *GETARG(short *) = ret; else if (flags & CHARINT) *GETARG(signed char *) = ret; else *GETARG(int *) = ret; continue; /* no output */ case 'O': flags |= LONGINT; /*FALLTHROUGH*/ case 'o': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 8; goto nosign; case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; flags = flags | INTMAXT; ox[1] = 'x'; goto nosign; case 'S': flags |= LONGINT; /*FALLTHROUGH*/ case 's': if (flags & LONGINT) { if ((cp = GETARG(wchar_t *)) == NULL) cp = L"(null)"; } else { char *mbp; if (convbuf != NULL) free(convbuf); if ((mbp = GETARG(char *)) == NULL) cp = L"(null)"; else { convbuf = __mbsconv(mbp, prec); if (convbuf == NULL) { fp->_flags |= __SERR; goto error; } cp = convbuf; } } size = (prec >= 0) ? wcsnlen(cp, prec) : wcslen(cp); sign = '\0'; break; case 'U': flags |= LONGINT; /*FALLTHROUGH*/ case 'u': if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 10; goto nosign; case 'X': xdigs = xdigs_upper; goto hex; case 'x': xdigs = xdigs_lower; hex: if (flags & INTMAX_SIZE) ujval = UJARG(); else ulval = UARG(); base = 16; /* leading 0x/X only if non-zero */ if (flags & ALT && (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0)) ox[1] = ch; flags &= ~GROUPING; /* unsigned conversions */ nosign: sign = '\0'; /*- * ``... diouXx conversions ... if a precision is * specified, the 0 flag will be ignored.'' * -- ANSI X3J11 */ number: if ((dprec = prec) >= 0) flags &= ~ZEROPAD; /*- * ``The result of converting a zero value with an * explicit precision of zero is no characters.'' * -- ANSI X3J11 * * ``The C Standard is clear enough as is. The call * printf("%#.0o", 0) should print 0.'' * -- Defect Report #151 */ cp = buf + BUF; if (flags & INTMAX_SIZE) { if (ujval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ujtoa(ujval, cp, base, flags & ALT, xdigs); } else { if (ulval != 0 || prec != 0 || (flags & ALT && base == 8)) cp = __ultoa(ulval, cp, base, flags & ALT, xdigs); } size = buf + BUF - cp; if (size > BUF) /* should never happen */ abort(); if ((flags & GROUPING) && size != 0) size += grouping_init(&gs, size, locale); break; default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; /* pretend it was %c with argument ch */ cp = buf; *cp = ch; size = 1; sign = '\0'; break; } /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) realsz++; if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; if ((unsigned)ret + prsize > INT_MAX) { ret = EOF; errno = EOVERFLOW; goto error; } /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) PAD(width - realsz, blanks); /* prefix */ if (sign) PRINT(&sign, 1); if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } /* right-adjusting zero padding */ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 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) { if (grouping_print(&gs, &io, cp, buf+BUF, locale) < 0) goto error; } else { PRINT(cp, size); } #ifndef NO_FLOATING_POINT } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { PRINT(zeroes, 1); if (prec || flags & ALT) PRINT(&decimal_point, 1); PAD(-expt, zeroes); /* already handled initial 0's */ prec += expt; } else { if (gs.grouping) { n = grouping_print(&gs, &io, cp, convbuf + ndig, locale); if (n < 0) goto error; cp += n; } else { PRINTANDPAD(cp, convbuf + ndig, expt, zeroes); cp += expt; } if (prec || flags & ALT) PRINT(&decimal_point, 1); } PRINTANDPAD(cp, convbuf + ndig, prec, zeroes); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || flags & ALT) { buf[0] = *cp++; buf[1] = decimal_point; PRINT(buf, 2); PRINT(cp, ndig-1); PAD(prec - ndig, zeroes); } else /* XeYYY */ PRINT(cp, 1); PRINT(expstr, expsize); } } #endif /* left-adjusting padding (always blank) */ if (flags & LADJUST) PAD(width - realsz, blanks); /* finally, adjust ret */ ret += prsize; FLUSH(); /* copy out the I/O vectors */ } done: FLUSH(); error: va_end(orgap); if (convbuf != NULL) free(convbuf); if (__sferror(fp)) ret = EOF; else fp->_flags |= savserr; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); /* NOTREACHED */ } diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c index 316493894652..1a28ff665247 100644 --- a/lib/libc/stdio/vfwscanf.c +++ b/lib/libc/stdio/vfwscanf.c @@ -1,946 +1,946 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #endif #include #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" #define BUF 513 /* Maximum length of numeric string. */ /* * Flags used during conversion. */ #define LONG 0x01 /* l: long or double */ #define LONGDBL 0x02 /* L: long double */ #define SHORT 0x04 /* h: short */ #define SUPPRESS 0x08 /* *: suppress assignment */ #define POINTER 0x10 /* p: void * (as hex) */ #define NOSKIP 0x20 /* [ or c: do not skip blanks */ #define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ #define INTMAXT 0x800 /* j: intmax_t */ #define PTRDIFFT 0x1000 /* t: ptrdiff_t */ #define SIZET 0x2000 /* z: size_t */ #define SHORTSHORT 0x4000 /* hh: char */ #define UNSIGNED 0x8000 /* %[oupxX] conversions */ /* * The following are used in integral conversions only: * SIGNOK, NDIGITS, PFXOK, and NZDIGITS */ #define SIGNOK 0x40 /* +/- is (still) legal */ #define NDIGITS 0x80 /* no digits detected */ #define PFXOK 0x100 /* 0x prefix is (still) legal */ #define NZDIGITS 0x200 /* no zero digits detected */ #define HAVESIGN 0x10000 /* sign detected */ /* * Conversion types. */ #define CT_CHAR 0 /* %c conversion */ #define CT_CCL 1 /* %[...] conversion */ #define CT_STRING 2 /* %s conversion */ #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 */ const wchar_t *end; /* character class end */ int compl; /* ccl is complemented? */ }; static __inline int inccl(const struct ccl *ccl, wint_t wi) { if (ccl->compl) { return (wmemchr(ccl->start, wi, ccl->end - ccl->start) == NULL); } else { return (wmemchr(ccl->start, wi, ccl->end - ccl->start) != NULL); } } /* * Conversion functions are passed a pointer to this object instead of * a real parameter to indicate that the assignment-suppression (*) * flag was specified. We could use a NULL pointer to indicate this, * but that would mask bugs in applications that call scanf() with a * NULL pointer. */ static const int suppress; #define SUPPRESS_PTR ((void *)&suppress) static const mbstate_t initial_mbs; /* * The following conversion functions return the number of characters consumed, * or -1 on input failure. Character class conversion returns 0 on match * failure. */ static __inline int convert_char(FILE *fp, char * mbp, int width, locale_t locale) { mbstate_t mbs; size_t nconv; wint_t wi; int n; n = 0; mbs = initial_mbs; while (width-- != 0 && (wi = __fgetwc(fp, locale)) != WEOF) { if (mbp != SUPPRESS_PTR) { nconv = wcrtomb(mbp, wi, &mbs); if (nconv == (size_t)-1) return (-1); mbp += nconv; } n++; } if (n == 0) return (-1); return (n); } static __inline int convert_wchar(FILE *fp, wchar_t *wcp, int width, locale_t locale) { wint_t wi; int n; n = 0; while (width-- != 0 && (wi = __fgetwc(fp, locale)) != WEOF) { if (wcp != SUPPRESS_PTR) *wcp++ = (wchar_t)wi; n++; } if (n == 0) return (-1); return (n); } static __inline int convert_ccl(FILE *fp, char * mbp, int width, const struct ccl *ccl, locale_t locale) { mbstate_t mbs; size_t nconv; wint_t wi; int n; n = 0; mbs = initial_mbs; while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && inccl(ccl, wi)) { if (mbp != SUPPRESS_PTR) { nconv = wcrtomb(mbp, wi, &mbs); if (nconv == (size_t)-1) return (-1); mbp += nconv; } n++; } if (wi != WEOF) __ungetwc(wi, fp, locale); if (mbp != SUPPRESS_PTR) *mbp = 0; return (n); } static __inline int convert_wccl(FILE *fp, wchar_t *wcp, int width, const struct ccl *ccl, locale_t locale) { wchar_t *wcp0; wint_t wi; int n; if (wcp == SUPPRESS_PTR) { n = 0; while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && inccl(ccl, wi)) n++; if (wi != WEOF) __ungetwc(wi, fp, locale); } else { wcp0 = wcp; while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && inccl(ccl, wi)) *wcp++ = (wchar_t)wi; if (wi != WEOF) __ungetwc(wi, fp, locale); n = wcp - wcp0; if (n == 0) return (0); *wcp = 0; } return (n); } static __inline int convert_string(FILE *fp, char * mbp, int width, locale_t locale) { mbstate_t mbs; size_t nconv; wint_t wi; int nread; mbs = initial_mbs; nread = 0; while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && !iswspace(wi)) { if (mbp != SUPPRESS_PTR) { nconv = wcrtomb(mbp, wi, &mbs); if (nconv == (size_t)-1) return (-1); mbp += nconv; } nread++; } if (wi != WEOF) __ungetwc(wi, fp, locale); if (mbp != SUPPRESS_PTR) *mbp = 0; return (nread); } static __inline int convert_wstring(FILE *fp, wchar_t *wcp, int width, locale_t locale) { wint_t wi; int nread; nread = 0; if (wcp == SUPPRESS_PTR) { while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && !iswspace(wi)) nread++; if (wi != WEOF) __ungetwc(wi, fp, locale); } else { while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 && !iswspace(wi)) { *wcp++ = (wchar_t)wi; nread++; } if (wi != WEOF) __ungetwc(wi, fp, locale); *wcp = '\0'; } return (nread); } /* * Read an integer, storing it in buf. The only relevant bit in the * flags argument is PFXOK. * * Return 0 on a match failure, and the number of characters read * otherwise. */ static __inline int parseint(FILE *fp, wchar_t *buf, int width, int base, int flags, locale_t locale) { /* `basefix' is used to avoid `if' tests */ static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; wchar_t *wcp; int c; flags |= SIGNOK | NDIGITS | NZDIGITS; for (wcp = buf; width; width--) { c = __fgetwc(fp, locale); /* * Switch on the character; `goto ok' if we accept it * as a part of number. */ switch (c) { /* * The digit 0 is always legal, but is special. For * %i conversions, if no digits (zero or nonzero) have * been scanned (only signs), we will have base==0. * In that case, we should set it to 8 and enable 0x * prefixing. Also, if we have not scanned zero * digits before this, do not turn off prefixing * (someone else will turn it off if we have scanned * any nonzero digits). */ case '0': if (base == 0) { base = 8; flags |= PFXOK; } if (flags & NZDIGITS) flags &= ~(SIGNOK|NZDIGITS|NDIGITS); else flags &= ~(SIGNOK|PFXOK|NDIGITS); goto ok; /* 1 through 7 always legal */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': base = basefix[base]; flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* digits 8 and 9 ok iff decimal or hex */ case '8': case '9': base = basefix[base]; if (base <= 8) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* letters ok iff hex */ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': /* no need to fix base here */ if (base <= 10) break; /* not legal here */ flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok; /* sign ok only as first character */ case '+': case '-': if (flags & SIGNOK) { flags &= ~SIGNOK; flags |= HAVESIGN; goto ok; } break; /* * x ok iff flag still set & 2nd char (or 3rd char if * we have a sign). */ case 'x': case 'X': if (flags & PFXOK && wcp == buf + 1 + !!(flags & HAVESIGN)) { base = 16; /* if %i */ flags &= ~PFXOK; goto ok; } break; } /* * If we got here, c is not a legal character for a * number. Stop accumulating digits. */ if (c != WEOF) __ungetwc(c, fp, locale); break; ok: /* * c is legal: store it and look at the next. */ *wcp++ = (wchar_t)c; } /* * If we had only a sign, it is no good; push back the sign. * If the number ends in `x', it was [sign] '0' 'x', so push * back the x and treat it as [sign] '0'. */ if (flags & NDIGITS) { if (wcp > buf) __ungetwc(*--wcp, fp, locale); return (0); } c = wcp[-1]; if (c == 'x' || c == 'X') { --wcp; __ungetwc(c, fp, locale); } return (wcp - buf); } /* * MT-safe version. */ int vfwscanf_l(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, va_list ap) { int ret; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(fp); ORIENT(fp, 1); ret = __vfwscanf(fp, locale, fmt, ap); FUNLOCKFILE_CANCELSAFE(); return (ret); } int vfwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, va_list ap) { return vfwscanf_l(fp, __get_locale(), fmt, ap); } /* * Non-MT-safe version. */ int __vfwscanf(FILE * __restrict fp, locale_t locale, const wchar_t * __restrict fmt, va_list ap) { #define GETARG(type) ((flags & SUPPRESS) ? SUPPRESS_PTR : va_arg(ap, type)) wint_t c; /* character from format, or conversion */ size_t width; /* field width, or 0 */ int flags; /* flags as defined above */ int nassigned; /* number of fields assigned */ int nconversions; /* number of conversions */ int nr; /* characters read by the current conversion */ int nread; /* number of characters consumed from fp */ int base; /* base argument to conversion function */ struct ccl ccl; /* character class info */ wchar_t buf[BUF]; /* buffer for numeric conversions */ wint_t wi; /* handy wint_t */ nassigned = 0; nconversions = 0; nread = 0; ccl.start = ccl.end = NULL; for (;;) { c = *fmt++; if (c == 0) return (nassigned); if (iswspace(c)) { while ((c = __fgetwc(fp, locale)) != WEOF && iswspace_l(c, locale)) nread++; if (c != WEOF) __ungetwc(c, fp, locale); continue; } if (c != '%') goto literal; width = 0; flags = 0; /* * switch on the format. continue if done; * break once format type is derived. */ again: c = *fmt++; switch (c) { case '%': literal: if ((wi = __fgetwc(fp, locale)) == WEOF) goto input_failure; if (wi != c) { __ungetwc(wi, fp, locale); goto match_failure; } nread++; continue; case '*': flags |= SUPPRESS; goto again; case 'j': flags |= INTMAXT; goto again; case 'l': if (flags & LONG) { flags &= ~LONG; flags |= LONGLONG; } else flags |= LONG; goto again; case 'q': flags |= LONGLONG; /* not quite */ goto again; case 't': flags |= PTRDIFFT; goto again; case 'z': flags |= SIZET; goto again; case 'L': flags |= LONGDBL; goto again; case 'h': if (flags & SHORT) { flags &= ~SHORT; flags |= SHORTSHORT; } else flags |= SHORT; goto again; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': width = width * 10 + c - '0'; goto again; /* * Conversions. */ case 'd': c = CT_INT; base = 10; break; case 'i': c = CT_INT; base = 0; break; case 'o': c = CT_INT; flags |= UNSIGNED; base = 8; break; case 'u': c = CT_INT; flags |= UNSIGNED; base = 10; break; case 'X': case 'x': flags |= PFXOK; /* enable 0x prefixing */ c = CT_INT; flags |= UNSIGNED; 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; /* FALLTHROUGH */ case 's': c = CT_STRING; break; case '[': ccl.start = fmt; if (*fmt == '^') { ccl.compl = 1; fmt++; } else ccl.compl = 0; if (*fmt == ']') fmt++; while (*fmt != '\0' && *fmt != ']') fmt++; ccl.end = fmt; fmt++; flags |= NOSKIP; c = CT_CCL; break; case 'C': flags |= LONG; /* FALLTHROUGH */ case 'c': flags |= NOSKIP; c = CT_CHAR; break; case 'p': /* pointer format is like hex */ flags |= POINTER | PFXOK; c = CT_INT; /* assumes sizeof(uintmax_t) */ flags |= UNSIGNED; /* >= sizeof(uintptr_t) */ base = 16; break; case 'n': if (flags & SUPPRESS) /* ??? */ continue; if (flags & SHORTSHORT) *va_arg(ap, char *) = nread; else if (flags & SHORT) *va_arg(ap, short *) = nread; else if (flags & LONG) *va_arg(ap, long *) = nread; else if (flags & LONGLONG) *va_arg(ap, long long *) = nread; else if (flags & INTMAXT) *va_arg(ap, intmax_t *) = nread; else if (flags & SIZET) *va_arg(ap, size_t *) = nread; else if (flags & PTRDIFFT) *va_arg(ap, ptrdiff_t *) = nread; else *va_arg(ap, int *) = nread; continue; default: goto match_failure; /* * Disgusting backwards compatibility hack. XXX */ case '\0': /* compat */ return (EOF); } /* * Consume leading white space, except for formats * that suppress this. */ if ((flags & NOSKIP) == 0) { while ((wi = __fgetwc(fp, locale)) != WEOF && iswspace(wi)) nread++; if (wi == WEOF) goto input_failure; __ungetwc(wi, fp, locale); } /* * Do the conversion. */ switch (c) { case CT_CHAR: /* scan arbitrary characters (sets NOSKIP) */ if (width == 0) width = 1; if (flags & LONG) { nr = convert_wchar(fp, GETARG(wchar_t *), width, locale); } else { nr = convert_char(fp, GETARG(char *), width, locale); } if (nr < 0) goto input_failure; break; case CT_CCL: /* scan a (nonempty) character class (sets NOSKIP) */ if (width == 0) width = (size_t)~0; /* `infinity' */ /* take only those things in the class */ if (flags & LONG) { nr = convert_wccl(fp, GETARG(wchar_t *), width, &ccl, locale); } else { nr = convert_ccl(fp, GETARG(char *), width, &ccl, locale); } if (nr <= 0) { if (nr < 0) goto input_failure; else /* nr == 0 */ goto match_failure; } break; case CT_STRING: /* like CCL, but zero-length string OK, & no NOSKIP */ if (width == 0) width = (size_t)~0; if (flags & LONG) { nr = convert_wstring(fp, GETARG(wchar_t *), width, locale); } else { nr = convert_string(fp, GETARG(char *), width, locale); } if (nr < 0) goto input_failure; break; case CT_INT: /* scan an integer as if by the conversion function */ if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1) width = sizeof(buf) / sizeof(*buf) - 1; nr = parseint(fp, buf, width, base, flags, locale); if (nr == 0) goto match_failure; if ((flags & SUPPRESS) == 0) { uintmax_t res; buf[nr] = L'\0'; if ((flags & UNSIGNED) == 0) res = wcstoimax(buf, NULL, base); else res = wcstoumax(buf, NULL, base); if (flags & POINTER) *va_arg(ap, void **) = (void *)(uintptr_t)res; else if (flags & SHORTSHORT) *va_arg(ap, char *) = res; else if (flags & SHORT) *va_arg(ap, short *) = res; else if (flags & LONG) *va_arg(ap, long *) = res; else if (flags & LONGLONG) *va_arg(ap, long long *) = res; else if (flags & INTMAXT) *va_arg(ap, intmax_t *) = res; else if (flags & PTRDIFFT) *va_arg(ap, ptrdiff_t *) = res; else if (flags & SIZET) *va_arg(ap, size_t *) = res; else *va_arg(ap, int *) = res; } break; #ifndef NO_FLOATING_POINT case CT_FLOAT: /* scan a floating point number as if by strtod */ if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1) width = sizeof(buf) / sizeof(*buf) - 1; nr = parsefloat(fp, buf, buf + width, locale); if (nr == 0) goto match_failure; if ((flags & SUPPRESS) == 0) { if (flags & LONGDBL) { long double res = wcstold(buf, NULL); *va_arg(ap, long double *) = res; } else if (flags & LONG) { double res = wcstod(buf, NULL); *va_arg(ap, double *) = res; } else { float res = wcstof(buf, NULL); *va_arg(ap, float *) = res; } } break; #endif /* !NO_FLOATING_POINT */ } if (!(flags & SUPPRESS)) nassigned++; nread += nr; nconversions++; } input_failure: return (nconversions != 0 ? nassigned : EOF); match_failure: return (nassigned); } #ifndef NO_FLOATING_POINT static int parsefloat(FILE *fp, wchar_t *buf, wchar_t *end, locale_t locale) { mbstate_t mbs; size_t nconv; wchar_t *commit, *p; int infnanpos = 0; enum { S_START, S_GOTSIGN, S_INF, S_NAN, S_DONE, S_MAYBEHEX, S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS } state = S_START; wchar_t c; wchar_t decpt; _Bool gotmantdig = 0, ishex = 0; mbs = initial_mbs; nconv = mbrtowc(&decpt, localeconv()->decimal_point, MB_CUR_MAX, &mbs); if (nconv == (size_t)-1 || nconv == (size_t)-2) decpt = '.'; /* failsafe */ /* * We set commit = p whenever the string we have read so far * constitutes a valid representation of a floating point * number by itself. At some point, the parse will complete * or fail, and we will ungetc() back to the last commit point. * To ensure that the file offset gets updated properly, it is * always necessary to read at least one character that doesn't * match; thus, we can't short-circuit "infinity" or "nan(...)". */ commit = buf - 1; c = WEOF; for (p = buf; p < end; ) { if ((c = __fgetwc(fp, locale)) == WEOF) break; reswitch: switch (state) { case S_START: state = S_GOTSIGN; if (c == '-' || c == '+') break; else goto reswitch; case S_GOTSIGN: switch (c) { case '0': state = S_MAYBEHEX; commit = p; break; case 'I': case 'i': state = S_INF; break; case 'N': case 'n': state = S_NAN; break; default: state = S_DIGITS; goto reswitch; } break; case S_INF: if (infnanpos > 6 || (c != "nfinity"[infnanpos] && c != "NFINITY"[infnanpos])) goto parsedone; if (infnanpos == 1 || infnanpos == 6) commit = p; /* inf or infinity */ infnanpos++; break; case S_NAN: switch (infnanpos) { case 0: if (c != 'A' && c != 'a') goto parsedone; break; case 1: if (c != 'N' && c != 'n') goto parsedone; else commit = p; break; case 2: if (c != '(') goto parsedone; break; default: if (c == ')') { commit = p; state = S_DONE; } else if (!iswalnum(c) && c != '_') goto parsedone; break; } infnanpos++; break; case S_DONE: goto parsedone; case S_MAYBEHEX: state = S_DIGITS; if (c == 'X' || c == 'x') { ishex = 1; break; } else { /* we saw a '0', but no 'x' */ gotmantdig = 1; goto reswitch; } case S_DIGITS: if ((ishex && iswxdigit(c)) || iswdigit(c)) gotmantdig = 1; else { state = S_FRAC; if (c != decpt) goto reswitch; } if (gotmantdig) commit = p; break; case S_FRAC: if (((c == 'E' || c == 'e') && !ishex) || ((c == 'P' || c == 'p') && ishex)) { if (!gotmantdig) goto parsedone; else state = S_EXP; } else if ((ishex && iswxdigit(c)) || iswdigit(c)) { commit = p; gotmantdig = 1; } else goto parsedone; break; case S_EXP: state = S_EXPDIGITS; if (c == '-' || c == '+') break; else goto reswitch; case S_EXPDIGITS: if (iswdigit(c)) commit = p; else goto parsedone; break; default: abort(); } *p++ = c; c = WEOF; } parsedone: if (c != WEOF) __ungetwc(c, fp, locale); while (commit < --p) __ungetwc(*p, fp, locale); *++commit = '\0'; return (commit - buf); } #endif diff --git a/lib/libc/stdio/vprintf.c b/lib/libc/stdio/vprintf.c index 8d189dedcac1..604870b93b1e 100644 --- a/lib/libc/stdio/vprintf.c +++ b/lib/libc/stdio/vprintf.c @@ -1,56 +1,56 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include int vprintf(const char * __restrict fmt, __va_list ap) { return (vfprintf(stdout, fmt, ap)); } int vprintf_l(locale_t locale, const char * __restrict fmt, __va_list ap) { return (vfprintf_l(stdout, locale, fmt, ap)); } diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c index 2de4d4e7c8bc..58fd2a455389 100644 --- a/lib/libc/stdio/vscanf.c +++ b/lib/libc/stdio/vscanf.c @@ -1,66 +1,66 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Donn Seeley at UUNET Technologies, Inc. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" int vscanf_l(locale_t locale, const char * __restrict fmt, __va_list ap) { int retval; FIX_LOCALE(locale); FLOCKFILE_CANCELSAFE(stdin); retval = __svfscanf(stdin, locale, fmt, ap); FUNLOCKFILE_CANCELSAFE(); return (retval); } int vscanf(const char * __restrict fmt, __va_list ap) { return vscanf_l(__get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index 3cd5b944d191..8fc7f9fdf725 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -1,88 +1,88 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include "local.h" #include "xlocale_private.h" int vsnprintf_l(char * __restrict str, size_t n, locale_t locale, const char * __restrict fmt, __va_list ap) { size_t on; int ret; char dummy[2]; FILE f = FAKE_FILE; FIX_LOCALE(locale); on = n; if (n != 0) n--; if (n > INT_MAX) { errno = EOVERFLOW; *str = '\0'; return (EOF); } /* Stdio internals do not deal correctly with zero length buffer */ if (n == 0) { if (on > 0) *str = '\0'; str = dummy; n = 1; } f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n; ret = __vfprintf(&f, locale, fmt, ap); if (on > 0) *f._p = '\0'; return (ret); } int vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, __va_list ap) { return vsnprintf_l(str, n, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index 867917737462..68a2f70469f4 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -1,68 +1,68 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include "local.h" #include "xlocale_private.h" int vsprintf_l(char * __restrict str, locale_t locale, const char * __restrict fmt, __va_list ap) { int ret; FILE f = FAKE_FILE; FIX_LOCALE(locale); f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; ret = __vfprintf(&f, locale, fmt, ap); *f._p = 0; return (ret); } int vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap) { return vsprintf_l(str, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index c4414815f21b..0751f0e95b0b 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -1,78 +1,78 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * This code is derived from software contributed to Berkeley by * Donn Seeley at UUNET Technologies, Inc. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include "local.h" #include "xlocale_private.h" static int eofread(void *, char *, int); /* ARGSUSED */ static int eofread(void *cookie, char *buf, int len) { return (0); } int vsscanf_l(const char * __restrict str, locale_t locale, const char * __restrict fmt, __va_list ap) { FILE f = FAKE_FILE; FIX_LOCALE(locale); f._flags = __SRD; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._r = strlen(str); f._read = eofread; return (__svfscanf(&f, locale, fmt, ap)); } int vsscanf(const char * __restrict str, const char * __restrict fmt, __va_list ap) { return vsscanf_l(str, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vswprintf.c b/lib/libc/stdio/vswprintf.c index c327dc35f1a4..db1b5d30d09d 100644 --- a/lib/libc/stdio/vswprintf.c +++ b/lib/libc/stdio/vswprintf.c @@ -1,114 +1,114 @@ /* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $ */ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1997 Todd C. Miller * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. 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 ``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 #if 0 __FBSDID("FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.16 2002/08/21 16:19:57 mike Exp "); #endif #include #include #include #include #include #include "local.h" #include "xlocale_private.h" int vswprintf_l(wchar_t * __restrict s, size_t n, locale_t locale, const wchar_t * __restrict fmt, __va_list ap) { static const mbstate_t initial; mbstate_t mbs; FILE f = FAKE_FILE; char *mbp; int ret, sverrno; size_t nwc; FIX_LOCALE(locale); if (n == 0) { errno = EINVAL; return (-1); } if (n - 1 > INT_MAX) { errno = EOVERFLOW; *s = L'\0'; return (-1); } f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); if (f._bf._base == NULL) { errno = ENOMEM; *s = L'\0'; return (-1); } f._bf._size = f._w = 127; /* Leave room for the NUL */ ret = __vfwprintf(&f, locale, fmt, ap); if (ret < 0) { sverrno = errno; free(f._bf._base); errno = sverrno; *s = L'\0'; return (-1); } *f._p = '\0'; mbp = f._bf._base; /* * XXX Undo the conversion from wide characters to multibyte that * fputwc() did in __vfwprintf(). */ mbs = initial; nwc = mbsrtowcs_l(s, (const char **)&mbp, n, &mbs, locale); free(f._bf._base); if (nwc == (size_t)-1) { errno = EILSEQ; *s = L'\0'; return (-1); } if (nwc == n) { s[n - 1] = L'\0'; errno = EOVERFLOW; return (-1); } return (ret); } int vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt, __va_list ap) { return vswprintf_l(s, n, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vswscanf.c b/lib/libc/stdio/vswscanf.c index 642b0bde675c..ecdafbefdc75 100644 --- a/lib/libc/stdio/vswscanf.c +++ b/lib/libc/stdio/vswscanf.c @@ -1,104 +1,104 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Donn Seeley at UUNET Technologies, Inc. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ __FBSDID("FreeBSD: src/lib/libc/stdio/vsscanf.c,v 1.11 2002/08/21 16:19:57 mike Exp "); #endif #include #include #include #include #include #include #include "local.h" #include "xlocale_private.h" static int eofread(void *, char *, int); static int eofread(void *cookie, char *buf, int len) { return (0); } int vswscanf_l(const wchar_t * __restrict str, locale_t locale, const wchar_t * __restrict fmt, va_list ap) { static const mbstate_t initial; mbstate_t mbs; FILE f = FAKE_FILE; char *mbstr; size_t mlen; int r; const wchar_t *strp; FIX_LOCALE(locale); /* * XXX Convert the wide character string to multibyte, which * __vfwscanf() will convert back to wide characters. */ if ((mbstr = malloc(wcslen(str) * MB_CUR_MAX + 1)) == NULL) return (EOF); mbs = initial; strp = str; if ((mlen = wcsrtombs_l(mbstr, &strp, SIZE_T_MAX, &mbs, locale)) == (size_t)-1) { free(mbstr); return (EOF); } f._flags = __SRD; f._bf._base = f._p = (unsigned char *)mbstr; f._bf._size = f._r = mlen; f._read = eofread; r = __vfwscanf(&f, locale, fmt, ap); free(mbstr); return (r); } int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt, va_list ap) { return vswscanf_l(str, __get_locale(), fmt, ap); } diff --git a/lib/libc/stdio/vwprintf.c b/lib/libc/stdio/vwprintf.c index 01b57926ae2e..b0e9ac26d3c6 100644 --- a/lib/libc/stdio/vwprintf.c +++ b/lib/libc/stdio/vwprintf.c @@ -1,49 +1,49 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int vwprintf(const wchar_t * __restrict fmt, va_list ap) { return (vfwprintf(stdout, fmt, ap)); } int vwprintf_l(locale_t locale, const wchar_t * __restrict fmt, va_list ap) { return (vfwprintf_l(stdout, locale, fmt, ap)); } diff --git a/lib/libc/stdio/vwscanf.c b/lib/libc/stdio/vwscanf.c index 8da57531d22b..e2e16ac91e53 100644 --- a/lib/libc/stdio/vwscanf.c +++ b/lib/libc/stdio/vwscanf.c @@ -1,49 +1,49 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int vwscanf(const wchar_t * __restrict fmt, va_list ap) { return (vfwscanf(stdin, fmt, ap)); } int vwscanf_l(locale_t locale, const wchar_t * __restrict fmt, va_list ap) { return (vfwscanf_l(stdin, locale, fmt, ap)); } diff --git a/lib/libc/stdio/wprintf.c b/lib/libc/stdio/wprintf.c index ea05fb8c5328..c45640021927 100644 --- a/lib/libc/stdio/wprintf.c +++ b/lib/libc/stdio/wprintf.c @@ -1,63 +1,63 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int wprintf(const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfwprintf(stdout, fmt, ap); va_end(ap); return (ret); } int wprintf_l(locale_t locale, const wchar_t * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfwprintf_l(stdout, locale, fmt, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdio/wscanf.c b/lib/libc/stdio/wscanf.c index f639597d5df5..9527fcd27767 100644 --- a/lib/libc/stdio/wscanf.c +++ b/lib/libc/stdio/wscanf.c @@ -1,63 +1,63 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include int wscanf(const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vfwscanf(stdin, fmt, ap); va_end(ap); return (r); } int wscanf_l(locale_t locale, const wchar_t * __restrict fmt, ...) { va_list ap; int r; va_start(ap, fmt); r = vfwscanf_l(stdin, locale, fmt, ap); va_end(ap); return (r); } diff --git a/lib/libc/stdlib/atof.c b/lib/libc/stdlib/atof.c index 3d7e895a2cbb..b058f10deb87 100644 --- a/lib/libc/stdlib/atof.c +++ b/lib/libc/stdlib/atof.c @@ -1,54 +1,54 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)atof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include double atof(const char *ascii) { return strtod(ascii, (char **)NULL); } double atof_l(const char *ascii, locale_t locale) { return strtod_l(ascii, (char **)NULL, locale); } diff --git a/lib/libc/stdlib/atoi.c b/lib/libc/stdlib/atoi.c index 2a8d52fc708b..dfaf659458f5 100644 --- a/lib/libc/stdlib/atoi.c +++ b/lib/libc/stdlib/atoi.c @@ -1,54 +1,54 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)atoi.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include int atoi(const char *str) { return (int)strtol(str, NULL, 10); } int atoi_l(const char *str, locale_t locale) { return (int)strtol_l(str, NULL, 10, locale); } diff --git a/lib/libc/stdlib/atol.c b/lib/libc/stdlib/atol.c index bc38894a2170..a36633f04d8c 100644 --- a/lib/libc/stdlib/atol.c +++ b/lib/libc/stdlib/atol.c @@ -1,54 +1,54 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)atol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include long atol(const char *str) { return strtol(str, (char **)NULL, 10); } long atol_l(const char *str, locale_t locale) { return strtol_l(str, (char **)NULL, 10, locale); } diff --git a/lib/libc/stdlib/atoll.c b/lib/libc/stdlib/atoll.c index bd3a17dc5498..95efac77eb82 100644 --- a/lib/libc/stdlib/atoll.c +++ b/lib/libc/stdlib/atoll.c @@ -1,51 +1,51 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include long long atoll(const char *str) { return strtoll(str, (char **)NULL, 10); } long long atoll_l(const char *str, locale_t locale) { return strtoll_l(str, (char **)NULL, 10, locale); } diff --git a/lib/libc/stdlib/cxa_thread_atexit.c b/lib/libc/stdlib/cxa_thread_atexit.c index 4f27b8e855b7..c6eb1278fcd2 100644 --- a/lib/libc/stdlib/cxa_thread_atexit.c +++ b/lib/libc/stdlib/cxa_thread_atexit.c @@ -1,38 +1,37 @@ /*- * Copyright (c) 2017 The FreeBSD Foundation - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include "libc_private.h" int __cxa_thread_atexit(void (*dtor_func)(void *), void *obj, void *dso_symbol) { return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); } diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c index 307d1159356b..0e36eb0babe5 100644 --- a/lib/libc/stdlib/strfmon.c +++ b/lib/libc/stdlib/strfmon.c @@ -1,668 +1,668 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2001 Alexey Zelkin * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include #include #include #include #include #include "xlocale_private.h" /* internal flags */ #define NEED_GROUPING 0x01 /* print digits grouped (default) */ #define SIGN_POSN_USED 0x02 /* '+' or '(' usage flag */ #define LOCALE_POSN 0x04 /* use locale defined +/- (default) */ #define PARENTH_POSN 0x08 /* enclose negative amount in () */ #define SUPPRESS_CURR_SYMBOL 0x10 /* suppress the currency from output */ #define LEFT_JUSTIFY 0x20 /* left justify */ #define USE_INTL_CURRENCY 0x40 /* use international currency symbol */ #define IS_NEGATIVE 0x80 /* is argument value negative ? */ /* internal macros */ #define PRINT(CH) do { \ if (dst >= s + maxsize) \ goto e2big_error; \ *dst++ = CH; \ } while (0) #define PRINTS(STR) do { \ char *tmps = STR; \ while (*tmps != '\0') \ PRINT(*tmps++); \ } while (0) #define GET_NUMBER(VAR, LOC) do { \ VAR = 0; \ while (isdigit_l((unsigned char)*fmt, LOC)) { \ if (VAR > INT_MAX / 10) \ goto e2big_error; \ VAR *= 10; \ VAR += *fmt - '0'; \ if (VAR < 0) \ goto e2big_error; \ fmt++; \ } \ } while (0) #define GRPCPY(howmany) do { \ int i = howmany; \ while (i-- > 0) { \ avalue_size--; \ *--bufend = *(avalue + avalue_size + padded); \ } \ } while (0) #define GRPSEP do { \ bufend -= thousands_sep_size; \ memcpy(bufend, thousands_sep, thousands_sep_size); \ groups++; \ } while (0) static void __setup_vars(int, char *, char *, char *, char **, struct lconv *); static int __calc_left_pad(int, char *, struct lconv *); static char *__format_grouped_double(double, int *, int, int, int, struct lconv *, locale_t); static ssize_t vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc, const char * __restrict format, va_list ap) { char *dst; /* output destination pointer */ const char *fmt; /* current format poistion pointer */ struct lconv *lc; /* pointer to lconv structure */ char *asciivalue; /* formatted double pointer */ int flags; /* formatting options */ int pad_char; /* padding character */ int pad_size; /* pad size */ int width; /* field width */ int left_prec; /* left precision */ int right_prec; /* right precision */ double value; /* just value */ char space_char = ' '; /* space after currency */ char cs_precedes, /* values gathered from struct lconv */ sep_by_space, sign_posn, *signstr, *currency_symbol; char *tmpptr; /* temporary vars */ int sverrno; FIX_LOCALE(loc); lc = localeconv_l(loc); dst = s; fmt = format; asciivalue = NULL; currency_symbol = NULL; while (*fmt) { /* pass nonformating characters AS IS */ if (*fmt != '%') goto literal; /* '%' found ! */ /* "%%" mean just '%' */ if (*(fmt + 1) == '%') { fmt++; literal: PRINT(*fmt++); continue; } /* set up initial values */ flags = (NEED_GROUPING|LOCALE_POSN); pad_char = ' '; /* padding character is "space" */ pad_size = 0; /* no padding initially */ left_prec = -1; /* no left precision specified */ right_prec = -1; /* no right precision specified */ width = -1; /* no width specified */ value = 0; /* we have no value to print now */ /* Flags */ while (1) { switch (*++fmt) { case '=': /* fill character */ pad_char = *++fmt; if (pad_char == '\0') goto format_error; continue; case '^': /* not group currency */ flags &= ~(NEED_GROUPING); continue; case '+': /* use locale defined signs */ if (flags & SIGN_POSN_USED) goto format_error; flags |= (SIGN_POSN_USED|LOCALE_POSN); continue; case '(': /* enclose negatives with () */ if (flags & SIGN_POSN_USED) goto format_error; flags |= (SIGN_POSN_USED|PARENTH_POSN); continue; case '!': /* suppress currency symbol */ flags |= SUPPRESS_CURR_SYMBOL; continue; case '-': /* alignment (left) */ flags |= LEFT_JUSTIFY; continue; default: break; } break; } /* field Width */ if (isdigit_l((unsigned char)*fmt, loc)) { GET_NUMBER(width, loc); /* Do we have enough space to put number with * required width ? */ if ((unsigned int)width >= maxsize - (dst - s)) goto e2big_error; } /* Left precision */ if (*fmt == '#') { if (!isdigit_l((unsigned char)*++fmt, loc)) goto format_error; GET_NUMBER(left_prec, loc); if ((unsigned int)left_prec >= maxsize - (dst - s)) goto e2big_error; } /* Right precision */ if (*fmt == '.') { if (!isdigit_l((unsigned char)*++fmt, loc)) goto format_error; GET_NUMBER(right_prec, loc); if ((unsigned int)right_prec >= maxsize - (dst - s) - left_prec) goto e2big_error; } /* Conversion Characters */ switch (*fmt++) { case 'i': /* use international currency format */ flags |= USE_INTL_CURRENCY; break; case 'n': /* use national currency format */ flags &= ~(USE_INTL_CURRENCY); break; default: /* required character is missing or premature EOS */ goto format_error; } if (currency_symbol != NULL) free(currency_symbol); if (flags & USE_INTL_CURRENCY) { currency_symbol = strdup(lc->int_curr_symbol); if (currency_symbol != NULL && strlen(currency_symbol) > 3) { space_char = currency_symbol[3]; currency_symbol[3] = '\0'; } } else currency_symbol = strdup(lc->currency_symbol); if (currency_symbol == NULL) goto end_error; /* ENOMEM. */ /* value itself */ value = va_arg(ap, double); /* detect sign */ if (value < 0) { flags |= IS_NEGATIVE; value = -value; } /* fill left_prec with amount of padding chars */ if (left_prec >= 0) { pad_size = __calc_left_pad((flags ^ IS_NEGATIVE), currency_symbol, lc) - __calc_left_pad(flags, currency_symbol, lc); if (pad_size < 0) pad_size = 0; } if (asciivalue != NULL) free(asciivalue); asciivalue = __format_grouped_double(value, &flags, left_prec, right_prec, pad_char, lc, loc); if (asciivalue == NULL) goto end_error; /* errno already set */ /* to ENOMEM by malloc() */ /* set some variables for later use */ __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr, lc); /* * Description of some LC_MONETARY's values: * * p_cs_precedes & n_cs_precedes * * = 1 - $currency_symbol precedes the value * for a monetary quantity with a non-negative value * = 0 - symbol succeeds the value * * p_sep_by_space & n_sep_by_space * * = 0 - no space separates $currency_symbol * from the value for a monetary quantity with a * non-negative value * = 1 - space separates the symbol from the value * = 2 - space separates the symbol and the sign string, * if adjacent; otherwise, a space separates * the sign string from the value * * p_sign_posn & n_sign_posn * * = 0 - parentheses enclose the quantity and the * $currency_symbol * = 1 - the sign string precedes the quantity and the * $currency_symbol * = 2 - the sign string succeeds the quantity and the * $currency_symbol * = 3 - the sign string precedes the $currency_symbol * = 4 - the sign string succeeds the $currency_symbol * */ tmpptr = dst; while (pad_size-- > 0) PRINT(' '); if (sign_posn == 0 && (flags & IS_NEGATIVE)) PRINT('('); if (cs_precedes == 1) { if (sign_posn == 1 || sign_posn == 3) { PRINTS(signstr); if (sep_by_space == 2) PRINT(' '); } if (!(flags & SUPPRESS_CURR_SYMBOL)) { PRINTS(currency_symbol); if (sign_posn == 4) { if (sep_by_space == 2) PRINT(space_char); PRINTS(signstr); if (sep_by_space == 1) PRINT(' '); } else if (sep_by_space == 1) PRINT(space_char); } } else if (sign_posn == 1) { PRINTS(signstr); if (sep_by_space == 2) PRINT(' '); } PRINTS(asciivalue); if (cs_precedes == 0) { if (sign_posn == 3) { if (sep_by_space == 1) PRINT(' '); PRINTS(signstr); } if (!(flags & SUPPRESS_CURR_SYMBOL)) { if ((sign_posn == 3 && sep_by_space == 2) || (sep_by_space == 1 && (sign_posn == 0 || sign_posn == 1 || sign_posn == 2 || sign_posn == 4))) PRINT(space_char); PRINTS(currency_symbol); if (sign_posn == 4) { if (sep_by_space == 2) PRINT(' '); PRINTS(signstr); } } } if (sign_posn == 2) { if (sep_by_space == 2) PRINT(' '); PRINTS(signstr); } if (sign_posn == 0) { if (flags & IS_NEGATIVE) PRINT(')'); else if (left_prec >= 0) PRINT(' '); } if (dst - tmpptr < width) { if (flags & LEFT_JUSTIFY) { while (dst - tmpptr < width) PRINT(' '); } else { pad_size = dst - tmpptr; memmove(tmpptr + width - pad_size, tmpptr, pad_size); memset(tmpptr, ' ', width - pad_size); dst += width - pad_size; } } } PRINT('\0'); free(asciivalue); free(currency_symbol); return (dst - s - 1); /* return size of put data except trailing '\0' */ e2big_error: errno = E2BIG; goto end_error; format_error: errno = EINVAL; end_error: sverrno = errno; if (asciivalue != NULL) free(asciivalue); if (currency_symbol != NULL) free(currency_symbol); errno = sverrno; return (-1); } static void __setup_vars(int flags, char *cs_precedes, char *sep_by_space, char *sign_posn, char **signstr, struct lconv *lc) { if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) { *cs_precedes = lc->int_n_cs_precedes; *sep_by_space = lc->int_n_sep_by_space; *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn; *signstr = (lc->negative_sign[0] == '\0') ? "-" : lc->negative_sign; } else if (flags & USE_INTL_CURRENCY) { *cs_precedes = lc->int_p_cs_precedes; *sep_by_space = lc->int_p_sep_by_space; *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_p_sign_posn; *signstr = lc->positive_sign; } else if (flags & IS_NEGATIVE) { *cs_precedes = lc->n_cs_precedes; *sep_by_space = lc->n_sep_by_space; *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn; *signstr = (lc->negative_sign[0] == '\0') ? "-" : lc->negative_sign; } else { *cs_precedes = lc->p_cs_precedes; *sep_by_space = lc->p_sep_by_space; *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->p_sign_posn; *signstr = lc->positive_sign; } /* Set default values for unspecified information. */ if (*cs_precedes != 0) *cs_precedes = 1; if (*sep_by_space == CHAR_MAX) *sep_by_space = 0; if (*sign_posn == CHAR_MAX) *sign_posn = 0; } static int __calc_left_pad(int flags, char *cur_symb, struct lconv *lc) { char cs_precedes, sep_by_space, sign_posn, *signstr; int left_chars = 0; __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr, lc); if (cs_precedes != 0) { left_chars += strlen(cur_symb); if (sep_by_space != 0) left_chars++; } switch (sign_posn) { case 0: if (flags & IS_NEGATIVE) left_chars++; break; case 1: left_chars += strlen(signstr); break; case 3: case 4: if (cs_precedes != 0) left_chars += strlen(signstr); } return (left_chars); } static int get_groups(int size, char *grouping) { int chars = 0; if (*grouping == CHAR_MAX || *grouping <= 0) /* no grouping ? */ return (0); while (size > (int)*grouping) { chars++; size -= (int)*grouping++; /* no more grouping ? */ if (*grouping == CHAR_MAX) break; /* rest grouping with same value ? */ if (*grouping == 0) { chars += (size - 1) / *(grouping - 1); break; } } return (chars); } /* convert double to locale-encoded string */ static char * __format_grouped_double(double value, int *flags, int left_prec, int right_prec, int pad_char, struct lconv *lc, locale_t loc) { char *rslt; char *avalue; int avalue_size; size_t bufsize; char *bufend; int padded; char *grouping; const char *decimal_point; const char *thousands_sep; size_t decimal_point_size; size_t thousands_sep_size; int groups = 0; grouping = lc->mon_grouping; decimal_point = lc->mon_decimal_point; if (*decimal_point == '\0') decimal_point = lc->decimal_point; thousands_sep = lc->mon_thousands_sep; if (*thousands_sep == '\0') thousands_sep = lc->thousands_sep; decimal_point_size = strlen(decimal_point); thousands_sep_size = strlen(thousands_sep); /* fill left_prec with default value */ if (left_prec == -1) left_prec = 0; /* fill right_prec with default value */ if (right_prec == -1) { if (*flags & USE_INTL_CURRENCY) right_prec = lc->int_frac_digits; else right_prec = lc->frac_digits; if (right_prec == CHAR_MAX) /* POSIX locale ? */ right_prec = 2; } if (*flags & NEED_GROUPING) left_prec += get_groups(left_prec, grouping); /* convert to string */ avalue_size = asprintf_l(&avalue, loc, "%*.*f", left_prec + right_prec + 1, right_prec, value); if (avalue_size < 0) return (NULL); /* make sure that we've enough space for result string */ bufsize = avalue_size * (1 + thousands_sep_size) + decimal_point_size + 1; rslt = calloc(1, bufsize); if (rslt == NULL) { free(avalue); return (NULL); } bufend = rslt + bufsize - 1; /* reserve space for trailing '\0' */ /* skip spaces at beginning */ padded = 0; while (avalue[padded] == ' ') { padded++; avalue_size--; } if (right_prec > 0) { bufend -= right_prec; memcpy(bufend, avalue + avalue_size + padded - right_prec, right_prec); bufend -= decimal_point_size; memcpy(bufend, decimal_point, decimal_point_size); avalue_size -= (right_prec + 1); } if ((*flags & NEED_GROUPING) && thousands_sep_size > 0 && *grouping != CHAR_MAX && *grouping > 0) { while (avalue_size > (int)*grouping) { GRPCPY(*grouping); GRPSEP; grouping++; /* no more grouping ? */ if (*grouping == CHAR_MAX) break; /* rest grouping with same value ? */ if (*grouping == 0) { grouping--; while (avalue_size > *grouping) { GRPCPY(*grouping); GRPSEP; } } } if (avalue_size != 0) GRPCPY(avalue_size); padded -= groups; } else { bufend -= avalue_size; memcpy(bufend, avalue + padded, avalue_size); /* decrease assumed $decimal_point */ if (right_prec == 0) padded -= decimal_point_size; } /* do padding with pad_char */ if (padded > 0) { bufend -= padded; memset(bufend, pad_char, padded); } bufsize = rslt + bufsize - bufend; memmove(rslt, bufend, bufsize); free(avalue); return (rslt); } ssize_t strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, ...) { ssize_t ret; va_list ap; va_start(ap, format); ret = vstrfmon_l(s, maxsize, __get_locale(), format, ap); va_end(ap); return (ret); } ssize_t strfmon_l(char * __restrict s, size_t maxsize, locale_t loc, const char * __restrict format, ...) { ssize_t ret; va_list ap; va_start(ap, format); ret = vstrfmon_l(s, maxsize, loc, format, ap); va_end(ap); return (ret); } diff --git a/lib/libc/stdlib/strtoimax.c b/lib/libc/stdlib/strtoimax.c index 14926fedd9e3..894d801940fd 100644 --- a/lib/libc/stdlib/strtoimax.c +++ b/lib/libc/stdlib/strtoimax.c @@ -1,153 +1,153 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to an intmax_t integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ intmax_t strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; uintmax_t acc; char c; uintmax_t cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for intmax_t is * [-9223372036854775808..9223372036854775807] and the input base * is 10, cutoff will be set to 922337203685477580 and cutlim to * either 7 (neg==0) or 8 (neg==1), meaning that if we have * accumulated a value > 922337203685477580, or equal but the * next digit is > 7 (or 8), the number is too big, and we will * return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX : INTMAX_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? INTMAX_MIN : INTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } intmax_t strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtoimax_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index 7b7200356131..360bb7efc8be 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -1,152 +1,152 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to a long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long strtol_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; unsigned long acc; char c; unsigned long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for longs is * [-2147483648..2147483647] and the input base is 10, * cutoff will be set to 214748364 and cutlim to either * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated * a value > 214748364, or equal but the next digit is > 7 (or 8), * the number is too big, and we will return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LONG_MIN : LONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } long strtol(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtol_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdlib/strtold.c b/lib/libc/stdlib/strtold.c index 17ba939db6a6..2f7cabbdd88b 100644 --- a/lib/libc/stdlib/strtold.c +++ b/lib/libc/stdlib/strtold.c @@ -1,41 +1,40 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (C) 2011 The FreeBSD Foundation - * All rights reserved. * * This software was developed by David Chisnall under sponsorship from the * FreeBSD Foundation. * * 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 #include #include "xlocale_private.h" long double strtold(const char * __restrict nptr, char ** __restrict endptr) { return strtold_l(nptr, endptr, __get_locale()); } diff --git a/lib/libc/stdlib/strtoll.c b/lib/libc/stdlib/strtoll.c index a5aeb57179de..51a523e51fb8 100644 --- a/lib/libc/stdlib/strtoll.c +++ b/lib/libc/stdlib/strtoll.c @@ -1,153 +1,153 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to a long long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ long long strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; unsigned long long acc; char c; unsigned long long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * Skip white space and pick up leading +/- sign if any. * If base is 0, allow 0x for hex and 0 for octal, else * assume decimal; if base is already 16, allow 0x. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; /* * Compute the cutoff value between legal numbers and illegal * numbers. That is the largest legal value, divided by the * base. An input number that is greater than this value, if * followed by a legal input character, is too big. One that * is equal to this value may be valid or not; the limit * between valid and invalid numbers is then based on the last * digit. For instance, if the range for quads is * [-9223372036854775808..9223372036854775807] and the input base * is 10, cutoff will be set to 922337203685477580 and cutlim to * either 7 (neg==0) or 8 (neg==1), meaning that if we have * accumulated a value > 922337203685477580, or equal but the * next digit is > 7 (or 8), the number is too big, and we will * return a range error. * * Set 'any' if any `digits' consumed; make it negative to indicate * overflow. */ cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; cutlim = cutoff % base; cutoff /= base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = neg ? LLONG_MIN : LLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } long long strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtoll_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index c9966d9a05ec..133d4c9b4695 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -1,130 +1,130 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to an unsigned long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long strtoul_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; unsigned long acc; char c; unsigned long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtol for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULONG_MAX / base; cutlim = ULONG_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } unsigned long strtoul(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtoul_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c index 871c458ef51b..464c37d49ef3 100644 --- a/lib/libc/stdlib/strtoull.c +++ b/lib/libc/stdlib/strtoull.c @@ -1,131 +1,131 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to an unsigned long long integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long long strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; unsigned long long acc; char c; unsigned long long cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoq for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = ULLONG_MAX / base; cutlim = ULLONG_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULLONG_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } unsigned long long strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtoull_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdlib/strtoumax.c b/lib/libc/stdlib/strtoumax.c index 92d464b081f0..af02b30254d6 100644 --- a/lib/libc/stdlib/strtoumax.c +++ b/lib/libc/stdlib/strtoumax.c @@ -1,131 +1,131 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "xlocale_private.h" /* * Convert a string to a uintmax_t integer. * * Assumes that the upper and lower case * alphabets and digits are each contiguous. */ uintmax_t strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base, locale_t locale) { const char *s; uintmax_t acc; char c; uintmax_t cutoff; int neg, any, cutlim; FIX_LOCALE(locale); /* * See strtoimax for comments as to the logic used. */ s = nptr; do { c = *s++; } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; } else { neg = 0; if (c == '+') c = *s++; } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; acc = any = 0; if (base < 2 || base > 36) goto noconv; cutoff = UINTMAX_MAX / base; cutlim = UINTMAX_MAX % base; for ( ; ; c = *s++) { if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = UINTMAX_MAX; errno = ERANGE; } else if (!any) { noconv: errno = EINVAL; } else if (neg) acc = -acc; if (endptr != NULL) *endptr = (char *)(any ? s - 1 : nptr); return (acc); } uintmax_t strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base) { return strtoumax_l(nptr, endptr, base, __get_locale()); } diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c index 69d2bb02ceee..674aaa0bb302 100644 --- a/lib/libc/stdtime/strftime.c +++ b/lib/libc/stdtime/strftime.c @@ -1,641 +1,641 @@ /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint #ifndef NOID static const char elsieid[] = "@(#)strftime.3 8.3"; /* * Based on the UCB version with the ID appearing below. * This is ANSIish only when "multibyte character == plain character". */ #endif /* !defined NOID */ #endif /* !defined lint */ #include "namespace.h" #include "private.h" #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; #endif /* LIBC_SCCS and not lint */ #include #include "tzfile.h" #include #include #include #include "un-namespace.h" #include "timelocal.h" static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *, locale_t); static char * _fmt(const char *, const struct tm *, char *, const char *, int *, locale_t); static char * _yconv(int, int, int, int, char *, const char *, locale_t); extern char * tzname[]; #ifndef YEAR_2000_NAME #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" #endif /* !defined YEAR_2000_NAME */ #define IN_NONE 0 #define IN_SOME 1 #define IN_THIS 2 #define IN_ALL 3 #define PAD_DEFAULT 0 #define PAD_LESS 1 #define PAD_SPACE 2 #define PAD_ZERO 3 static const char fmt_padding[][4][5] = { /* DEFAULT, LESS, SPACE, ZERO */ #define PAD_FMT_MONTHDAY 0 #define PAD_FMT_HMS 0 #define PAD_FMT_CENTURY 0 #define PAD_FMT_SHORTYEAR 0 #define PAD_FMT_MONTH 0 #define PAD_FMT_WEEKOFYEAR 0 #define PAD_FMT_DAYOFMONTH 0 { "%02d", "%d", "%2d", "%02d" }, #define PAD_FMT_SDAYOFMONTH 1 #define PAD_FMT_SHMS 1 { "%2d", "%d", "%2d", "%02d" }, #define PAD_FMT_DAYOFYEAR 2 { "%03d", "%d", "%3d", "%03d" }, #define PAD_FMT_YEAR 3 { "%04d", "%d", "%4d", "%04d" } }; size_t strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict t, locale_t loc) { char * p; int warn; FIX_LOCALE(loc); tzset(); warn = IN_NONE; p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, loc); #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { (void) fprintf_l(stderr, loc, "\n"); if (format == NULL) (void) fputs("NULL strftime format ", stderr); else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", format); (void) fputs("yields only two digits of years in ", stderr); if (warn == IN_SOME) (void) fputs("some locales", stderr); else if (warn == IN_THIS) (void) fputs("the current locale", stderr); else (void) fputs("all locales", stderr); (void) fputs("\n", stderr); } #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ if (p == s + maxsize) return (0); *p = '\0'; return p - s; } size_t strftime(char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict t) { return strftime_l(s, maxsize, format, t, __get_locale()); } static char * _fmt(const char *format, const struct tm * const t, char *pt, const char * const ptlim, int *warnp, locale_t loc) { int Ealternative, Oalternative, PadIndex; struct lc_time_T *tptr = __get_current_time_locale(loc); for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; PadIndex = PAD_DEFAULT; label: switch (*++format) { case '\0': --format; break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : tptr->weekday[t->tm_wday], pt, ptlim); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : tptr->wday[t->tm_wday], pt, ptlim); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : (Oalternative ? tptr->alt_month : tptr->month)[t->tm_mon], pt, ptlim); continue; case 'b': case 'h': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : tptr->mon[t->tm_mon], pt, ptlim); continue; case 'C': /* * %C used to do a... * _fmt("%a %b %e %X %Y", t); * ...whereas now POSIX 1003.2 calls for * something completely different. * (ado, 1993-05-24) */ pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, pt, ptlim, loc); continue; case 'c': { int warn2 = IN_SOME; pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) *warnp = warn2; } continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, loc); continue; case 'd': pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], pt, ptlim, loc); continue; case 'E': if (Ealternative || Oalternative) break; Ealternative++; goto label; case 'O': /* * C99 locale modifiers. * The sequences * %Ec %EC %Ex %EX %Ey %EY * %Od %oe %OH %OI %Om %OM * %OS %Ou %OU %OV %Ow %OW %Oy * are supposed to provide alternate * representations. * * FreeBSD extension * %OB */ if (Ealternative || Oalternative) break; Oalternative++; goto label; case 'e': pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim, loc); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, loc); continue; case 'H': pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 'j': pt = _conv(t->tm_yday + 1, fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'k': /* * This used to be... * _conv(t->tm_hour % 12 ? * t->tm_hour % 12 : 12, 2, ' '); * ...and has been changed to the below to * match SunOS 4.1.1 and Arnold Robbins' * strftime version 3.0. That is, "%k" and * "%l" have been swapped. * (ado, 1993-05-24) */ pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim, loc); continue; #ifdef KITCHEN_SINK case 'K': /* ** After all this time, still unclaimed! */ pt = _add("kitchen sink", pt, ptlim); continue; #endif /* defined KITCHEN_SINK */ case 'l': /* * This used to be... * _conv(t->tm_hour, 2, ' '); * ...and has been changed to the below to * match SunOS 4.1.1 and Arnold Robbin's * strftime version 3.0. That is, "%k" and * "%l" have been swapped. * (ado, 1993-05-24) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim, loc); continue; case 'M': pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 'm': pt = _conv(t->tm_mon + 1, fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim, loc); continue; case 'n': pt = _add("\n", pt, ptlim); continue; case 'p': pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? tptr->pm : tptr->am, pt, ptlim); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim, warnp, loc); continue; case 'r': pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, warnp, loc); continue; case 'S': pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); continue; case 's': { struct tm tm; char buf[INT_STRLEN_MAXIMUM( time_t) + 1]; time_t mkt; tm = *t; mkt = mktime(&tm); if (TYPE_SIGNED(time_t)) (void) sprintf_l(buf, loc, "%ld", (long) mkt); else (void) sprintf_l(buf, loc, "%lu", (unsigned long) mkt); pt = _add(buf, pt, ptlim); } continue; case 'T': pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, loc); continue; case 't': pt = _add("\t", pt, ptlim); continue; case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'u': /* * From Arnold Robbins' strftime version 3.0: * "ISO 8601: Weekday as a decimal number * [1 (Monday) - 7]" * (ado, 1993-05-24) */ pt = _conv((t->tm_wday == 0) ? DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim, loc); continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* * From Arnold Robbins' strftime version 3.0: "the week number of the * year (the first Monday as the first day of week 1) as a decimal number * (01-53)." * (ado, 1993-05-24) * * From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: * "Week 01 of a year is per definition the first week which has the * Thursday in this year, which is equivalent to the week which contains * the fourth day of January. In other words, the first week of a new year * is the week which has the majority of its days in the new year. Week 01 * might also contain days from the previous year and the week before week * 01 of a year is the last week (52 or 53) of the previous year even if * it contains days from the new year. A week starts with Monday (day 1) * and ends with Sunday (day 7). For example, the first week of the year * 1997 lasts from 1996-12-30 to 1997-01-05..." * (ado, 1996-01-02) */ { int year; int base; int yday; int wday; int w; year = t->tm_year; base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { int len; int bot; int top; len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* * What yday (-3 ... 3) does * the ISO year begin on? */ bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; /* * What yday does the NEXT * ISO year begin on? */ top = bot - (len % DAYSPERWEEK); if (top < -3) top += DAYSPERWEEK; top += len; if (yday >= top) { ++base; w = 1; break; } if (yday >= bot) { w = 1 + ((yday - bot) / DAYSPERWEEK); break; } --base; yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 if ((w == 52 && t->tm_mon == TM_JANUARY) || (w == 1 && t->tm_mon == TM_DECEMBER)) w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); else if (*format == 'g') { *warnp = IN_ALL; pt = _yconv(year, base, 0, 1, pt, ptlim, loc); } else pt = _yconv(year, base, 1, 1, pt, ptlim, loc); } continue; case 'v': /* * From Arnold Robbins' strftime version 3.0: * "date as dd-bbb-YYYY" * (ado, 1993-05-24) */ pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, loc); continue; case 'W': pt = _conv((t->tm_yday + DAYSPERWEEK - (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); continue; case 'X': pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, loc); continue; case 'x': { int warn2 = IN_SOME; pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) *warnp = warn2; } continue; case 'y': *warnp = IN_ALL; pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, pt, ptlim, loc); continue; case 'Y': pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim, loc); continue; case 'Z': #ifdef TM_ZONE if (t->TM_ZONE != NULL) pt = _add(t->TM_ZONE, pt, ptlim); else #endif /* defined TM_ZONE */ if (t->tm_isdst >= 0) pt = _add(tzname[t->tm_isdst != 0], pt, ptlim); /* * C99 says that %Z must be replaced by the * empty string if the time zone is not * determinable. */ continue; case 'z': { int diff; char const * sign; if (t->tm_isdst < 0) continue; #ifdef TM_GMTOFF diff = t->TM_GMTOFF; #else /* !defined TM_GMTOFF */ /* * C99 says that the UTC offset must * be computed by looking only at * tm_isdst. This requirement is * incorrect, since it means the code * must rely on magic (in this case * altzone and timezone), and the * magic might not have the correct * offset. Doing things correctly is * tricky and requires disobeying C99; * see GNU C strftime for details. * For now, punt and conform to the * standard, even though it's incorrect. * * C99 says that %z must be replaced by the * empty string if the time zone is not * determinable, so output nothing if the * appropriate variables are not available. */ if (t->tm_isdst == 0) #ifdef USG_COMPAT diff = -timezone; #else /* !defined USG_COMPAT */ continue; #endif /* !defined USG_COMPAT */ else #ifdef ALTZONE diff = -altzone; #else /* !defined ALTZONE */ continue; #endif /* !defined ALTZONE */ #endif /* !defined TM_GMTOFF */ if (diff < 0) { sign = "-"; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); diff /= SECSPERMIN; diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); pt = _conv(diff, fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim, loc); } continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim, warnp, loc); continue; case '-': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_LESS; goto label; case '_': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_SPACE; goto label; case '0': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_ZERO; goto label; case '%': /* * X311J/88-090 (4.12.3.5): if conversion char is * undefined, behavior is undefined. Print out the * character itself as printf(3) also does. */ default: break; } } if (pt == ptlim) break; *pt++ = *format; } return (pt); } static char * _conv(const int n, const char * const format, char * const pt, const char * const ptlim, locale_t loc) { char buf[INT_STRLEN_MAXIMUM(int) + 1]; (void) sprintf_l(buf, loc, format, n); return _add(buf, pt, ptlim); } static char * _add(const char *str, char *pt, const char * const ptlim) { while (pt < ptlim && (*pt = *str++) != '\0') ++pt; return (pt); } /* * POSIX and the C Standard are unclear or inconsistent about * what %C and %y do if the year is negative or exceeds 9999. * Use the convention that %C concatenated with %y yields the * same output as %Y, and that %Y contains at least 4 bytes, * with more only if necessary. */ static char * _yconv(const int a, const int b, const int convert_top, const int convert_yy, char *pt, const char * const ptlim, locale_t loc) { register int lead; register int trail; #define DIVISOR 100 trail = a % DIVISOR + b % DIVISOR; lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; trail %= DIVISOR; if (trail < 0 && lead > 0) { trail += DIVISOR; --lead; } else if (lead < 0 && trail > 0) { trail -= DIVISOR; ++lead; } if (convert_top) { if (lead == 0 && trail < 0) pt = _add("-0", pt, ptlim); else pt = _conv(lead, "%02d", pt, ptlim, loc); } if (convert_yy) pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim, loc); return (pt); } diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c index 9842d02e220d..848b94545dd2 100644 --- a/lib/libc/stdtime/strptime.c +++ b/lib/libc/stdtime/strptime.c @@ -1,723 +1,723 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2014 Gary Mills * Copyright 2011, Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1994 Powerdog Industries. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 POWERDOG INDUSTRIES ``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 POWERDOG INDUSTRIES 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. * * The views and conclusions contained in the software and documentation * are those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of Powerdog Industries. */ #include #ifndef lint #ifndef NOID static char copyright[] __unused = "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ #include "namespace.h" #include #include #include #include #include #include #include "private.h" #include "un-namespace.h" #include "libc_private.h" #include "timelocal.h" #include "tzfile.h" static char * _strptime(const char *, const char *, struct tm *, int *, locale_t); #define asizeof(a) (sizeof(a) / sizeof((a)[0])) #define FLAG_NONE (1 << 0) #define FLAG_YEAR (1 << 1) #define FLAG_MONTH (1 << 2) #define FLAG_YDAY (1 << 3) #define FLAG_MDAY (1 << 4) #define FLAG_WDAY (1 << 5) /* * Calculate the week day of the first day of a year. Valid for * the Gregorian calendar, which began Sept 14, 1752 in the UK * and its colonies. Ref: * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week */ static int first_wday_of(int year) { return (((2 * (3 - (year / 100) % 4)) + (year % 100) + ((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7); } static char * _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, locale_t locale) { char c; const char *ptr; int day_offset = -1, wday_offset; int week_offset; int i, len; int flags; int Ealternative, Oalternative; int century, year; const struct lc_time_T *tptr = __get_current_time_locale(locale); static int start_of_month[2][13] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} }; flags = FLAG_NONE; century = -1; year = -1; ptr = fmt; while (*ptr != 0) { c = *ptr++; if (c != '%') { if (isspace_l((unsigned char)c, locale)) while (*buf != 0 && isspace_l((unsigned char)*buf, locale)) buf++; else if (c != *buf++) return (NULL); continue; } Ealternative = 0; Oalternative = 0; label: c = *ptr++; switch (c) { case '%': if (*buf++ != '%') return (NULL); break; case '+': buf = _strptime(buf, tptr->date_fmt, tm, GMTp, locale); if (buf == NULL) return (NULL); flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'C': if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); /* XXX This will break for 3-digit centuries. */ len = 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } century = i; flags |= FLAG_YEAR; break; case 'c': buf = _strptime(buf, tptr->c_fmt, tm, GMTp, locale); if (buf == NULL) return (NULL); flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'D': buf = _strptime(buf, "%m/%d/%y", tm, GMTp, locale); if (buf == NULL) return (NULL); flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'E': if (Ealternative || Oalternative) break; Ealternative++; goto label; case 'O': if (Ealternative || Oalternative) break; Oalternative++; goto label; case 'F': buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, locale); if (buf == NULL) return (NULL); flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'R': buf = _strptime(buf, "%H:%M", tm, GMTp, locale); if (buf == NULL) return (NULL); break; case 'r': buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, locale); if (buf == NULL) return (NULL); break; case 'T': buf = _strptime(buf, "%H:%M:%S", tm, GMTp, locale); if (buf == NULL) return (NULL); break; case 'X': buf = _strptime(buf, tptr->X_fmt, tm, GMTp, locale); if (buf == NULL) return (NULL); break; case 'x': buf = _strptime(buf, tptr->x_fmt, tm, GMTp, locale); if (buf == NULL) return (NULL); flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'j': if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = 3; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 366) return (NULL); tm->tm_yday = i - 1; flags |= FLAG_YDAY; break; case 'M': case 'S': if (*buf == 0 || isspace_l((unsigned char)*buf, locale)) break; if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; } if (c == 'M') { if (i > 59) return (NULL); tm->tm_min = i; } else { if (i > 60) return (NULL); tm->tm_sec = i; } break; case 'H': case 'I': case 'k': case 'l': /* * %k and %l specifiers are documented as being * blank-padded. However, there is no harm in * allowing zero-padding. * * XXX %k and %l specifiers may gobble one too many * digits if used incorrectly. */ len = 2; if ((c == 'k' || c == 'l') && isblank_l((unsigned char)*buf, locale)) { buf++; len = 1; } if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'H' || c == 'k') { if (i > 23) return (NULL); } else if (i == 0 || i > 12) return (NULL); tm->tm_hour = i; break; case 'p': /* * XXX This is bogus if parsed before hour-related * specifiers. */ if (tm->tm_hour > 12) return (NULL); len = strlen(tptr->am); if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { if (tm->tm_hour == 12) tm->tm_hour = 0; buf += len; break; } len = strlen(tptr->pm); if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { if (tm->tm_hour != 12) tm->tm_hour += 12; buf += len; break; } return (NULL); case 'A': case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); if (strncasecmp_l(buf, tptr->weekday[i], len, locale) == 0) break; len = strlen(tptr->wday[i]); if (strncasecmp_l(buf, tptr->wday[i], len, locale) == 0) break; } if (i == asizeof(tptr->weekday)) return (NULL); buf += len; tm->tm_wday = i; flags |= FLAG_WDAY; break; case 'U': case 'W': /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i > 53) return (NULL); if (c == 'U') day_offset = TM_SUNDAY; else day_offset = TM_MONDAY; week_offset = i; break; case 'u': case 'w': if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); i = *buf++ - '0'; if (i < 0 || i > 7 || (c == 'u' && i < 1) || (c == 'w' && i > 6)) return (NULL); tm->tm_wday = i % 7; flags |= FLAG_WDAY; break; case 'e': /* * With %e format, our strftime(3) adds a blank space * before single digits. */ if (*buf != 0 && isspace_l((unsigned char)*buf, locale)) buf++; /* FALLTHROUGH */ case 'd': /* * The %e specifier was once explicitly documented as * not being zero-padded but was later changed to * equivalent to %d. There is no harm in allowing * such padding. * * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i == 0 || i > 31) return (NULL); tm->tm_mday = i; flags |= FLAG_MDAY; break; case 'B': case 'b': case 'h': for (i = 0; i < asizeof(tptr->month); i++) { if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); if (strncasecmp_l(buf, tptr->alt_month[i], len, locale) == 0) break; } } else { len = strlen(tptr->month[i]); if (strncasecmp_l(buf, tptr->month[i], len, locale) == 0) break; } } /* * Try the abbreviated month name if the full name * wasn't found and Oalternative was not requested. */ if (i == asizeof(tptr->month) && !Oalternative) { for (i = 0; i < asizeof(tptr->month); i++) { len = strlen(tptr->mon[i]); if (strncasecmp_l(buf, tptr->mon[i], len, locale) == 0) break; } } if (i == asizeof(tptr->month)) return (NULL); tm->tm_mon = i; buf += len; flags |= FLAG_MONTH; break; case 'm': if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 12) return (NULL); tm->tm_mon = i - 1; flags |= FLAG_MONTH; break; case 's': { char *cp; int sverrno; long n; time_t t; sverrno = errno; errno = 0; n = strtol_l(buf, &cp, 10, locale); if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; return (NULL); } errno = sverrno; buf = cp; if (gmtime_r(&t, tm) == NULL) return (NULL); *GMTp = 1; flags |= FLAG_YDAY | FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; } break; case 'Y': case 'y': if (*buf == 0 || isspace_l((unsigned char)*buf, locale)) break; if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); len = (c == 'Y') ? 4 : 2; for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'Y') century = i / 100; year = i % 100; flags |= FLAG_YEAR; break; case 'Z': { const char *cp; char *zonestr; for (cp = buf; *cp && isupper_l((unsigned char)*cp, locale); ++cp) { /*empty*/} if (cp - buf) { zonestr = alloca(cp - buf + 1); strncpy(zonestr, buf, cp - buf); zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT") || 0 == strcmp(zonestr, "UTC")) { *GMTp = 1; } else if (0 == strcmp(zonestr, tzname[0])) { tm->tm_isdst = 0; } else if (0 == strcmp(zonestr, tzname[1])) { tm->tm_isdst = 1; } else { return (NULL); } buf += cp - buf; } } break; case 'z': { int sign = 1; if (*buf != '+') { if (*buf == '-') sign = -1; else return (NULL); } buf++; i = 0; for (len = 4; len > 0; len--) { if (isdigit_l((unsigned char)*buf, locale)) { i *= 10; i += *buf - '0'; buf++; } else if (len == 2) { i *= 100; break; } else return (NULL); } if (i > 1400 || (sign == -1 && i > 1200) || (i % 100) >= 60) return (NULL); tm->tm_hour -= sign * (i / 100); tm->tm_min -= sign * (i % 100); *GMTp = 1; } break; case 'n': case 't': while (isspace_l((unsigned char)*buf, locale)) buf++; break; default: return (NULL); } } if (century != -1 || year != -1) { if (year == -1) year = 0; if (century == -1) { if (year < 69) year += 100; } else year += century * 100 - TM_YEAR_BASE; tm->tm_year = year; } if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) { if ((flags & (FLAG_MONTH | FLAG_MDAY)) == (FLAG_MONTH | FLAG_MDAY)) { tm->tm_yday = start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); flags |= FLAG_YDAY; } else if (day_offset != -1) { int tmpwday, tmpyday, fwo; fwo = first_wday_of(tm->tm_year + TM_YEAR_BASE); /* No incomplete week (week 0). */ if (week_offset == 0 && fwo == day_offset) return (NULL); /* Set the date to the first Sunday (or Monday) * of the specified week of the year. */ tmpwday = (flags & FLAG_WDAY) ? tm->tm_wday : day_offset; tmpyday = (7 - fwo + day_offset) % 7 + (week_offset - 1) * 7 + (tmpwday - day_offset + 7) % 7; /* Impossible yday for incomplete week (week 0). */ if (tmpyday < 0) { if (flags & FLAG_WDAY) return (NULL); tmpyday = 0; } tm->tm_yday = tmpyday; flags |= FLAG_YDAY; } } if ((flags & (FLAG_YEAR | FLAG_YDAY)) == (FLAG_YEAR | FLAG_YDAY)) { if (!(flags & FLAG_MONTH)) { i = 0; while (tm->tm_yday >= start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)][i]) i++; if (i > 12) { i = 1; tm->tm_yday -= start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)][12]; tm->tm_year++; } tm->tm_mon = i - 1; flags |= FLAG_MONTH; } if (!(flags & FLAG_MDAY)) { tm->tm_mday = tm->tm_yday - start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)] [tm->tm_mon] + 1; flags |= FLAG_MDAY; } if (!(flags & FLAG_WDAY)) { i = 0; wday_offset = first_wday_of(tm->tm_year); while (i++ <= tm->tm_yday) { if (wday_offset++ >= 6) wday_offset = 0; } tm->tm_wday = wday_offset; flags |= FLAG_WDAY; } } return ((char *)buf); } char * strptime_l(const char * __restrict buf, const char * __restrict fmt, struct tm * __restrict tm, locale_t loc) { char *ret; int gmt; FIX_LOCALE(loc); gmt = 0; ret = _strptime(buf, fmt, tm, &gmt, loc); if (ret && gmt) { time_t t = timegm(tm); localtime_r(&t, tm); } return (ret); } char * strptime(const char * __restrict buf, const char * __restrict fmt, struct tm * __restrict tm) { return strptime_l(buf, fmt, tm, __get_locale()); } diff --git a/lib/libc/stdtime/timelocal.c b/lib/libc/stdtime/timelocal.c index 1ad2950e0118..93b9868d0319 100644 --- a/lib/libc/stdtime/timelocal.c +++ b/lib/libc/stdtime/timelocal.c @@ -1,154 +1,154 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2001 Alexey Zelkin * Copyright (c) 1997 FreeBSD Inc. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include "ldpart.h" #include "timelocal.h" struct xlocale_time { struct xlocale_component header; char *buffer; struct lc_time_T locale; }; struct xlocale_time __xlocale_global_time; #define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) static const struct lc_time_T _C_time_locale = { { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }, /* X_fmt */ "%H:%M:%S", /* * x_fmt * Since the C language standard calls for * "date, using locale's date format," anything goes. * Using just numbers (as here) makes Quakers happier; * it's also compatible with SVR4. */ "%m/%d/%y", /* * c_fmt */ "%a %b %e %H:%M:%S %Y", /* am */ "AM", /* pm */ "PM", /* date_fmt */ "%a %b %e %H:%M:%S %Z %Y", /* alt_month * Standalone months forms for %OB */ { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }, /* md_order * Month / day order in dates */ "md", /* ampm_fmt * To determine 12-hour clock format time (empty, if N/A) */ "%I:%M:%S %p" }; static void destruct_time(void *v) { struct xlocale_time *l = v; if (l->buffer) free(l->buffer); free(l); } #include struct lc_time_T * __get_current_time_locale(locale_t loc) { return (loc->using_time_locale ? &((struct xlocale_time *)loc->components[XLC_TIME])->locale : (struct lc_time_T *)&_C_time_locale); } static int time_load_locale(struct xlocale_time *l, int *using_locale, const char *name) { struct lc_time_T *time_locale = &l->locale; return (__part_load_locale(name, using_locale, &l->buffer, "LC_TIME", LCTIME_SIZE, LCTIME_SIZE, (const char **)time_locale)); } int __time_load_locale(const char *name) { return time_load_locale(&__xlocale_global_time, &__xlocale_global_locale.using_time_locale, name); } void* __time_load(const char* name, locale_t loc) { struct xlocale_time *new = calloc(sizeof(struct xlocale_time), 1); new->header.header.destructor = destruct_time; if (time_load_locale(new, &loc->using_time_locale, name) == _LDP_ERROR) { xlocale_release(new); return NULL; } return new; } diff --git a/lib/libc/stdtime/timelocal.h b/lib/libc/stdtime/timelocal.h index f6a0a6e38f52..7fe62b41ebfd 100644 --- a/lib/libc/stdtime/timelocal.h +++ b/lib/libc/stdtime/timelocal.h @@ -1,61 +1,61 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 1997-2002 FreeBSD Project. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #ifndef _TIMELOCAL_H_ #define _TIMELOCAL_H_ #include "xlocale_private.h" /* * Private header file for the strftime and strptime localization * stuff. */ struct lc_time_T { const char *mon[12]; const char *month[12]; const char *wday[7]; const char *weekday[7]; const char *X_fmt; const char *x_fmt; const char *c_fmt; const char *am; const char *pm; const char *date_fmt; const char *alt_month[12]; const char *md_order; const char *ampm_fmt; }; struct lc_time_T *__get_current_time_locale(locale_t); int __time_load_locale(const char *); #endif /* !_TIMELOCAL_H_ */ diff --git a/lib/libc/string/mempcpy.c b/lib/libc/string/mempcpy.c index 17697c2569aa..2c645da97627 100644 --- a/lib/libc/string/mempcpy.c +++ b/lib/libc/string/mempcpy.c @@ -1,39 +1,38 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include void * mempcpy(void *__restrict dst, const void *__restrict src, size_t len) { return ((char *)memcpy(dst, src, len) + len); } diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c index f90943d48e50..c959869ad9f0 100644 --- a/lib/libc/string/strcasecmp.c +++ b/lib/libc/string/strcasecmp.c @@ -1,87 +1,87 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include "xlocale_private.h" int strcasecmp_l(const char *s1, const char *s2, locale_t locale) { const u_char *us1 = (const u_char *)s1, *us2 = (const u_char *)s2; FIX_LOCALE(locale); while (tolower_l(*us1, locale) == tolower_l(*us2++, locale)) if (*us1++ == '\0') return (0); return (tolower_l(*us1, locale) - tolower_l(*--us2, locale)); } int strcasecmp(const char *s1, const char *s2) { return strcasecmp_l(s1, s2, __get_locale()); } int strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t locale) { FIX_LOCALE(locale); if (n != 0) { const u_char *us1 = (const u_char *)s1, *us2 = (const u_char *)s2; do { if (tolower_l(*us1, locale) != tolower_l(*us2++, locale)) return (tolower_l(*us1, locale) - tolower_l(*--us2, locale)); if (*us1++ == '\0') break; } while (--n != 0); } return (0); } int strncasecmp(const char *s1, const char *s2, size_t n) { return strncasecmp_l(s1, s2, n, __get_locale()); } diff --git a/lib/libc/string/strcasestr.c b/lib/libc/string/strcasestr.c index cac3d5385acd..591a2d95304b 100644 --- a/lib/libc/string/strcasestr.c +++ b/lib/libc/string/strcasestr.c @@ -1,72 +1,72 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include #include "xlocale_private.h" /* * Find the first occurrence of find in s, ignore case. */ char * strcasestr_l(const char *s, const char *find, locale_t locale) { char c, sc; size_t len; FIX_LOCALE(locale); if ((c = *find++) != 0) { c = tolower_l((unsigned char)c, locale); len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while ((char)tolower_l((unsigned char)sc, locale) != c); } while (strncasecmp_l(s, find, len, locale) != 0); s--; } return ((char *)s); } char * strcasestr(const char *s, const char *find) { return strcasestr_l(s, find, __get_locale()); } diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c index c62c85052290..a682f352320f 100644 --- a/lib/libc/string/strcoll.c +++ b/lib/libc/string/strcoll.c @@ -1,118 +1,118 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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 #include #include #include #include #include "collate.h" /* * In order to properly handle multibyte locales, its easiest to just * convert to wide characters and then use wcscoll. However if an * error occurs, we gracefully fall back to simple strcmp. Caller * should check errno. */ int strcoll_l(const char *s, const char *s2, locale_t locale) { int ret; wchar_t *t1 = NULL, *t2 = NULL; wchar_t *w1 = NULL, *w2 = NULL; const char *cs1, *cs2; mbstate_t mbs1; mbstate_t mbs2; size_t sz1, sz2; memset(&mbs1, 0, sizeof (mbstate_t)); memset(&mbs2, 0, sizeof (mbstate_t)); /* * The mbsrtowcs_l function can set the src pointer to null upon * failure, so it should act on a copy to avoid: * - sending null pointer to strcmp * - having strcoll/strcoll_l change *s or *s2 to null */ cs1 = s; cs2 = s2; FIX_LOCALE(locale); struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; if (table->__collate_load_error) goto error; sz1 = strlen(s) + 1; sz2 = strlen(s2) + 1; /* * Simple assumption: conversion to wide format is strictly * reducing, i.e. a single byte (or multibyte character) * cannot result in multiple wide characters. */ if ((t1 = malloc(sz1 * sizeof (wchar_t))) == NULL) goto error; w1 = t1; if ((t2 = malloc(sz2 * sizeof (wchar_t))) == NULL) goto error; w2 = t2; if ((mbsrtowcs_l(w1, &cs1, sz1, &mbs1, locale)) == (size_t)-1) goto error; if ((mbsrtowcs_l(w2, &cs2, sz2, &mbs2, locale)) == (size_t)-1) goto error; ret = wcscoll_l(w1, w2, locale); free(t1); free(t2); return (ret); error: free(t1); free(t2); return (strcmp(s, s2)); } int strcoll(const char *s, const char *s2) { return strcoll_l(s, s2, __get_locale()); } diff --git a/lib/libc/string/strxfrm.c b/lib/libc/string/strxfrm.c index 22a0bc187577..d9f3d0a7b6d5 100644 --- a/lib/libc/string/strxfrm.c +++ b/lib/libc/string/strxfrm.c @@ -1,103 +1,103 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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 #include #include #include #include #include "collate.h" size_t strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t loc); size_t strxfrm(char * __restrict dest, const char * __restrict src, size_t len) { return strxfrm_l(dest, src, len, __get_locale()); } size_t strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len, locale_t locale) { size_t slen; size_t xlen; wchar_t *wcs = NULL; FIX_LOCALE(locale); struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; if (!*src) { if (len > 0) *dest = '\0'; return (0); } /* * The conversion from multibyte to wide character strings is * strictly reducing (one byte of an mbs cannot expand to more * than one wide character.) */ slen = strlen(src); if (table->__collate_load_error) goto error; if ((wcs = malloc((slen + 1) * sizeof (wchar_t))) == NULL) goto error; if (mbstowcs_l(wcs, src, slen + 1, locale) == (size_t)-1) goto error; if ((xlen = _collate_sxfrm(table, wcs, dest, len)) == (size_t)-1) goto error; free(wcs); if (len > xlen) { dest[xlen] = 0; } else if (len) { dest[len-1] = 0; } return (xlen); error: /* errno should be set to ENOMEM if malloc failed */ free(wcs); strlcpy(dest, src, len); return (slen); } diff --git a/lib/libc/string/wcscoll.c b/lib/libc/string/wcscoll.c index 24d8df1faaed..b7720c4069d1 100644 --- a/lib/libc/string/wcscoll.c +++ b/lib/libc/string/wcscoll.c @@ -1,227 +1,227 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2017 Nexenta Systems, Inc. * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include "collate.h" int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t locale) { int len1, len2, pri1, pri2; wchar_t *tr1 = NULL, *tr2 = NULL; int direc, pass; int ret = wcscmp(ws1, ws2); FIX_LOCALE(locale); struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; if (table->__collate_load_error || ret == 0) return (ret); if (*ws1 == 0 && *ws2 != 0) return (-1); if (*ws1 != 0 && *ws2 == 0) return (1); /* * Once upon a time we had code to try to optimize this, but * it turns out that you really can't make many assumptions * safely. You absolutely have to run this pass by pass, * because some passes will be ignored for a given character, * while others will not. Simpler locales will benefit from * having fewer passes, and most comparisons should resolve * during the primary pass anyway. * * Note that we do one final extra pass at the end to pick * up UNDEFINED elements. There is special handling for them. */ for (pass = 0; pass <= table->info->directive_count; pass++) { const int32_t *st1 = NULL; const int32_t *st2 = NULL; const wchar_t *w1 = ws1; const wchar_t *w2 = ws2; /* special pass for UNDEFINED */ if (pass == table->info->directive_count) { direc = DIRECTIVE_FORWARD; } else { direc = table->info->directive[pass]; } if (direc & DIRECTIVE_BACKWARD) { wchar_t *bp, *fp, c; free(tr1); if ((tr1 = wcsdup(w1)) == NULL) goto end; bp = tr1; fp = tr1 + wcslen(tr1) - 1; while (bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } free(tr2); if ((tr2 = wcsdup(w2)) == NULL) goto end; bp = tr2; fp = tr2 + wcslen(tr2) - 1; while (bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } w1 = tr1; w2 = tr2; } if (direc & DIRECTIVE_POSITION) { int check1, check2; while (*w1 && *w2) { pri1 = pri2 = 0; check1 = check2 = 1; while ((pri1 == pri2) && (check1 || check2)) { if (check1) { _collate_lookup(table, w1, &len1, &pri1, pass, &st1); if (pri1 < 0) { errno = EINVAL; goto end; } if (!pri1) { pri1 = COLLATE_MAX_PRIORITY; st1 = NULL; } check1 = (st1 != NULL); } if (check2) { _collate_lookup(table, w2, &len2, &pri2, pass, &st2); if (pri2 < 0) { errno = EINVAL; goto end; } if (!pri2) { pri2 = COLLATE_MAX_PRIORITY; st2 = NULL; } check2 = (st2 != NULL); } } if (pri1 != pri2) { ret = pri1 - pri2; goto end; } w1 += len1; w2 += len2; } if (!*w1) { if (*w2) { ret = -(int)*w2; goto end; } } else { ret = *w1; goto end; } } else { int vpri1 = 0, vpri2 = 0; while (*w1 || *w2 || st1 || st2) { pri1 = 1; while (*w1 || st1) { _collate_lookup(table, w1, &len1, &pri1, pass, &st1); w1 += len1; if (pri1 > 0) { vpri1++; break; } if (pri1 < 0) { errno = EINVAL; goto end; } st1 = NULL; } pri2 = 1; while (*w2 || st2) { _collate_lookup(table, w2, &len2, &pri2, pass, &st2); w2 += len2; if (pri2 > 0) { vpri2++; break; } if (pri2 < 0) { errno = EINVAL; goto end; } st2 = NULL; } if ((!pri1 || !pri2) && (vpri1 == vpri2)) break; if (pri1 != pri2) { ret = pri1 - pri2; goto end; } } if (vpri1 && !vpri2) { ret = 1; goto end; } if (!vpri1 && vpri2) { ret = -1; goto end; } } } ret = 0; end: free(tr1); free(tr2); return (ret); } int wcscoll(const wchar_t *ws1, const wchar_t *ws2) { return wcscoll_l(ws1, ws2, __get_locale()); } diff --git a/lib/libc/string/wcswidth.c b/lib/libc/string/wcswidth.c index 25d86ab0bbc4..84e9af602801 100644 --- a/lib/libc/string/wcswidth.c +++ b/lib/libc/string/wcswidth.c @@ -1,69 +1,69 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include #include "xlocale_private.h" int wcswidth_l(const wchar_t *pwcs, size_t n, locale_t locale) { wchar_t wc; int len, l; FIX_LOCALE(locale); len = 0; while (n-- > 0 && (wc = *pwcs++) != L'\0') { if ((l = wcwidth_l(wc, locale)) < 0) return (-1); len += l; } return (len); } int wcswidth(const wchar_t *pwcs, size_t n) { return wcswidth_l(pwcs, n, __get_locale()); } diff --git a/lib/libc/string/wcsxfrm.c b/lib/libc/string/wcsxfrm.c index be64d23b79f4..6e4d7534828b 100644 --- a/lib/libc/string/wcsxfrm.c +++ b/lib/libc/string/wcsxfrm.c @@ -1,85 +1,85 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. * * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. + * * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * 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 ``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 #include #include #include #include "collate.h" size_t wcsxfrm_l(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len, locale_t locale) { size_t slen; FIX_LOCALE(locale); struct xlocale_collate *table = (struct xlocale_collate*)locale->components[XLC_COLLATE]; if (*src == L'\0') { if (len != 0) *dest = L'\0'; return (0); } if ((table->__collate_load_error) || ((slen = _collate_wxfrm(table, src, dest, len)) == (size_t)-1)) { goto error; } /* Add null termination at the correct location. */ if (len > slen) { dest[slen] = 0; } else if (len) { dest[len-1] = 0; } return (slen); error: slen = wcslen(src); if (slen < len) (void) wcscpy(dest, src); else if (len > 0) { (void) wcsncpy(dest, src, len - 1); dest[len - 1] = L'\0'; } return (slen); } size_t wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len) { return wcsxfrm_l(dest, src, len, __get_locale()); } diff --git a/lib/libc/string/wmempcpy.c b/lib/libc/string/wmempcpy.c index 451e41e97ecb..a21621de3977 100644 --- a/lib/libc/string/wmempcpy.c +++ b/lib/libc/string/wmempcpy.c @@ -1,40 +1,39 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include #include wchar_t * wmempcpy(wchar_t *__restrict dst, const wchar_t *__restrict src, size_t len) { return (wmemcpy(dst, src, len) + len); } diff --git a/lib/libc/sys/POSIX2x_Fork.c b/lib/libc/sys/POSIX2x_Fork.c index 0af88ae9b49b..4745f1be42b5 100644 --- a/lib/libc/sys/POSIX2x_Fork.c +++ b/lib/libc/sys/POSIX2x_Fork.c @@ -1,43 +1,42 @@ /* * Copyright (c) 2021 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" #pragma weak _Fork pid_t _Fork(void) { return (__sys_fork()); } diff --git a/lib/libc/sys/_umtx_op.2 b/lib/libc/sys/_umtx_op.2 index 8230b96b46c4..9c0f1f425e47 100644 --- a/lib/libc/sys/_umtx_op.2 +++ b/lib/libc/sys/_umtx_op.2 @@ -1,1540 +1,1539 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 23, 2020 .Dt _UMTX_OP 2 .Os .Sh NAME .Nm _umtx_op .Nd interface for implementation of userspace threading synchronization primitives .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/types.h .In sys/umtx.h .Ft int .Fn _umtx_op "void *obj" "int op" "u_long val" "void *uaddr" "void *uaddr2" .Sh DESCRIPTION The .Fn _umtx_op system call provides kernel support for userspace implementation of the threading synchronization primitives. The .Lb libthr uses the syscall to implement .St -p1003.1-2001 pthread locks, like mutexes, condition variables and so on. .Ss STRUCTURES The operations, performed by the .Fn _umtx_op syscall, operate on userspace objects which are described by the following structures. Reserved fields and paddings are omitted. All objects require ABI-mandated alignment, but this is not currently enforced consistently on all architectures. .Pp The following flags are defined for flag fields of all structures: .Bl -tag -width indent .It Dv USYNC_PROCESS_SHARED Allow selection of the process-shared sleep queue for the thread sleep container, when the lock ownership cannot be granted immediately, and the operation must sleep. The process-shared or process-private sleep queue is selected based on the attributes of the memory mapping which contains the first byte of the structure, see .Xr mmap 2 . Otherwise, if the flag is not specified, the process-private sleep queue is selected regardless of the memory mapping attributes, as an optimization. .Pp See the .Sx SLEEP QUEUES subsection below for more details on sleep queues. .El .Bl -hang -offset indent .It Sy Mutex .Bd -literal struct umutex { volatile lwpid_t m_owner; uint32_t m_flags; uint32_t m_ceilings[2]; uintptr_t m_rb_lnk; }; .Ed .Pp The .Dv m_owner field is the actual lock. It contains either the thread identifier of the lock owner in the locked state, or zero when the lock is unowned. The highest bit set indicates that there is contention on the lock. The constants are defined for special values: .Bl -tag -width indent .It Dv UMUTEX_UNOWNED Zero, the value stored in the unowned lock. .It Dv UMUTEX_CONTESTED The contention indicator. .It Dv UMUTEX_RB_OWNERDEAD A thread owning the robust mutex terminated. The mutex is in unlocked state. .It Dv UMUTEX_RB_NOTRECOV The robust mutex is in a non-recoverable state. It cannot be locked until reinitialized. .El .Pp The .Dv m_flags field may contain the following umutex-specific flags, in addition to the common flags: .Bl -tag -width indent .It Dv UMUTEX_PRIO_INHERIT Mutex implements .Em Priority Inheritance protocol. .It Dv UMUTEX_PRIO_PROTECT Mutex implements .Em Priority Protection protocol. .It Dv UMUTEX_ROBUST Mutex is robust, as described in the .Sx ROBUST UMUTEXES section below. .It Dv UMUTEX_NONCONSISTENT Robust mutex is in a transient non-consistent state. Not used by kernel. .El .Pp In the manual page, mutexes not having .Dv UMUTEX_PRIO_INHERIT and .Dv UMUTEX_PRIO_PROTECT flags set, are called normal mutexes. Each type of mutex .Pq normal, priority-inherited, and priority-protected has a separate sleep queue associated with the given key. .Pp For priority protected mutexes, the .Dv m_ceilings array contains priority ceiling values. The .Dv m_ceilings[0] is the ceiling value for the mutex, as specified by .St -p1003.1-2008 for the .Em Priority Protected mutex protocol. The .Dv m_ceilings[1] is used only for the unlock of a priority protected mutex, when unlock is done in an order other than the reversed lock order. In this case, .Dv m_ceilings[1] must contain the ceiling value for the last locked priority protected mutex, for proper priority reassignment. If, instead, the unlocking mutex was the last priority propagated mutex locked by the thread, .Dv m_ceilings[1] should contain \-1. This is required because kernel does not maintain the ordered lock list. .It Sy Condition variable .Bd -literal struct ucond { volatile uint32_t c_has_waiters; uint32_t c_flags; uint32_t c_clockid; }; .Ed .Pp A non-zero .Dv c_has_waiters value indicates that there are in-kernel waiters for the condition, executing the .Dv UMTX_OP_CV_WAIT request. .Pp The .Dv c_flags field contains flags. Only the common flags .Pq Dv USYNC_PROCESS_SHARED are defined for ucond. .Pp The .Dv c_clockid member provides the clock identifier to use for timeout, when the .Dv UMTX_OP_CV_WAIT request has both the .Dv CVWAIT_CLOCKID flag and the timeout specified. Valid clock identifiers are a subset of those for .Xr clock_gettime 2 : .Bl -bullet -compact .It .Dv CLOCK_MONOTONIC .It .Dv CLOCK_MONOTONIC_FAST .It .Dv CLOCK_MONOTONIC_PRECISE .It .Dv CLOCK_PROF .It .Dv CLOCK_REALTIME .It .Dv CLOCK_REALTIME_FAST .It .Dv CLOCK_REALTIME_PRECISE .It .Dv CLOCK_SECOND .It .Dv CLOCK_UPTIME .It .Dv CLOCK_UPTIME_FAST .It .Dv CLOCK_UPTIME_PRECISE .It .Dv CLOCK_VIRTUAL .El .It Sy Reader/writer lock .Bd -literal struct urwlock { volatile int32_t rw_state; uint32_t rw_flags; uint32_t rw_blocked_readers; uint32_t rw_blocked_writers; }; .Ed .Pp The .Dv rw_state field is the actual lock. It contains both the flags and counter of the read locks which were granted. Names of the .Dv rw_state bits are following: .Bl -tag -width indent .It Dv URWLOCK_WRITE_OWNER Write lock was granted. .It Dv URWLOCK_WRITE_WAITERS There are write lock waiters. .It Dv URWLOCK_READ_WAITERS There are read lock waiters. .It Dv URWLOCK_READER_COUNT(c) Returns the count of currently granted read locks. .El .Pp At any given time there may be only one thread to which the writer lock is granted on the .Vt struct rwlock , and no threads are granted read lock. Or, at the given time, up to .Dv URWLOCK_MAX_READERS threads may be granted the read lock simultaneously, but write lock is not granted to any thread. .Pp The following flags for the .Dv rw_flags member of .Vt struct urwlock are defined, in addition to the common flags: .Bl -tag -width indent .It Dv URWLOCK_PREFER_READER If specified, immediately grant read lock requests when .Dv urwlock is already read-locked, even in presence of unsatisfied write lock requests. By default, if there is a write lock waiter, further read requests are not granted, to prevent unfair write lock waiter starvation. .El .Pp The .Dv rw_blocked_readers and .Dv rw_blocked_writers members contain the count of threads which are sleeping in kernel, waiting for the associated request type to be granted. The fields are used by kernel to update the .Dv URWLOCK_READ_WAITERS and .Dv URWLOCK_WRITE_WAITERS flags of the .Dv rw_state lock after requesting thread was woken up. .It Sy Semaphore .Bd -literal struct _usem2 { volatile uint32_t _count; uint32_t _flags; }; .Ed .Pp The .Dv _count word represents a counting semaphore. A non-zero value indicates an unlocked (posted) semaphore, while zero represents the locked state. The maximal supported semaphore count is .Dv USEM_MAX_COUNT . .Pp The .Dv _count word, besides the counter of posts (unlocks), also contains the .Dv USEM_HAS_WAITERS bit, which indicates that locked semaphore has waiting threads. .Pp The .Dv USEM_COUNT() macro, applied to the .Dv _count word, returns the current semaphore counter, which is the number of posts issued on the semaphore. .Pp The following bits for the .Dv _flags member of .Vt struct _usem2 are defined, in addition to the common flags: .Bl -tag -width indent .It Dv USEM_NAMED Flag is ignored by kernel. .El .It Sy Timeout parameter .Bd -literal struct _umtx_time { struct timespec _timeout; uint32_t _flags; uint32_t _clockid; }; .Ed .Pp Several .Fn _umtx_op operations allow the blocking time to be limited, failing the request if it cannot be satisfied in the specified time period. The timeout is specified by passing either the address of .Vt struct timespec , or its extended variant, .Vt struct _umtx_time , as the .Fa uaddr2 argument of .Fn _umtx_op . They are distinguished by the .Fa uaddr value, which must be equal to the size of the structure pointed to by .Fa uaddr2 , casted to .Vt uintptr_t . .Pp The .Dv _timeout member specifies the time when the timeout should occur. Legal values for clock identifier .Dv _clockid are shared with the .Fa clock_id argument to the .Xr clock_gettime 2 function, and use the same underlying clocks. The specified clock is used to obtain the current time value. Interval counting is always performed by the monotonic wall clock. .Pp The .Dv _flags argument allows the following flags to further define the timeout behaviour: .Bl -tag -width indent .It Dv UMTX_ABSTIME The .Dv _timeout value is the absolute time. The thread will be unblocked and the request failed when specified clock value is equal or exceeds the .Dv _timeout. .Pp If the flag is absent, the timeout value is relative, that is the amount of time, measured by the monotonic wall clock from the moment of the request start. .El .El .Ss SLEEP QUEUES When a locking request cannot be immediately satisfied, the thread is typically put to .Em sleep , which is a non-runnable state terminated by the .Em wake operation. Lock operations include a .Em try variant which returns an error rather than sleeping if the lock cannot be obtained. Also, .Fn _umtx_op provides requests which explicitly put the thread to sleep. .Pp Wakes need to know which threads to make runnable, so sleeping threads are grouped into containers called .Em sleep queues . A sleep queue is identified by a key, which for .Fn _umtx_op is defined as the physical address of some variable. Note that the .Em physical address is used, which means that same variable mapped multiple times will give one key value. This mechanism enables the construction of .Em process-shared locks. .Pp A related attribute of the key is shareability. Some requests always interpret keys as private for the current process, creating sleep queues with the scope of the current process even if the memory is shared. Others either select the shareability automatically from the mapping attributes, or take additional input as the .Dv USYNC_PROCESS_SHARED common flag. This is done as optimization, allowing the lock scope to be limited regardless of the kind of backing memory. .Pp Only the address of the start byte of the variable specified as key is important for determining corresponding sleep queue. The size of the variable does not matter, so, for example, sleep on the same address interpeted as .Vt uint32_t and .Vt long on a little-endian 64-bit platform would collide. .Pp The last attribute of the key is the object type. The sleep queue to which a sleeping thread is assigned is an individual one for simple wait requests, mutexes, rwlocks, condvars and other primitives, even when the physical address of the key is same. .Pp When waking up a limited number of threads from a given sleep queue, the highest priority threads that have been blocked for the longest on the queue are selected. .Ss ROBUST UMUTEXES The .Em robust umutexes are provided as a substrate for a userspace library to implement .Tn POSIX robust mutexes. A robust umutex must have the .Dv UMUTEX_ROBUST flag set. .Pp On thread termination, the kernel walks two lists of mutexes. The two lists head addresses must be provided by a prior call to .Dv UMTX_OP_ROBUST_LISTS request. The lists are singly-linked. The link to next element is provided by the .Dv m_rb_lnk member of the .Vt struct umutex . .Pp Robust list processing is aborted if the kernel finds a mutex with any of the following conditions: .Bl -dash -offset indent -compact .It the .Dv UMUTEX_ROBUST flag is not set .It not owned by the current thread, except when the mutex is pointed to by the .Dv robust_inactive member of the .Vt struct umtx_robust_lists_params , registered for the current thread .It the combination of mutex flags is invalid .It read of the umutex memory faults .It the list length limit described in .Xr libthr 3 is reached. .El .Pp Every mutex in both lists is unlocked as if the .Dv UMTX_OP_MUTEX_UNLOCK request is performed on it, but instead of the .Dv UMUTEX_UNOWNED value, the .Dv m_owner field is written with the .Dv UMUTEX_RB_OWNERDEAD value. When a mutex in the .Dv UMUTEX_RB_OWNERDEAD state is locked by kernel due to the .Dv UMTX_OP_MUTEX_TRYLOCK and .Dv UMTX_OP_MUTEX_LOCK requests, the lock is granted and .Er EOWNERDEAD error is returned. .Pp Also, the kernel handles the .Dv UMUTEX_RB_NOTRECOV value of .Dv the m_owner field specially, always returning the .Er ENOTRECOVERABLE error for lock attempts, without granting the lock. .Ss OPERATIONS The following operations, requested by the .Fa op argument to the function, are implemented: .Bl -tag -width indent .It Dv UMTX_OP_WAIT Wait. The arguments for the request are: .Bl -tag -width "obj" .It Fa obj Pointer to a variable of type .Vt long . .It Fa val Current value of the .Dv *obj . .El .Pp The current value of the variable pointed to by the .Fa obj argument is compared with the .Fa val . If they are equal, the requesting thread is put to interruptible sleep until woken up or the optionally specified timeout expires. .Pp The comparison and sleep are atomic. In other words, if another thread writes a new value to .Dv *obj and then issues .Dv UMTX_OP_WAKE , the request is guaranteed to not miss the wakeup, which might otherwise happen between comparison and blocking. .Pp The physical address of memory where the .Fa *obj variable is located, is used as a key to index sleeping threads. .Pp The read of the current value of the .Dv *obj variable is not guarded by barriers. In particular, it is the user's duty to ensure the lock acquire and release memory semantics, if the .Dv UMTX_OP_WAIT and .Dv UMTX_OP_WAKE requests are used as a substrate for implementing a simple lock. .Pp The request is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. .Pp Optionally, a timeout for the request may be specified. .It Dv UMTX_OP_WAKE Wake the threads possibly sleeping due to .Dv UMTX_OP_WAIT . The arguments for the request are: .Bl -tag -width "obj" .It Fa obj Pointer to a variable, used as a key to find sleeping threads. .It Fa val Up to .Fa val threads are woken up by this request. Specify .Dv INT_MAX to wake up all waiters. .El .It Dv UMTX_OP_MUTEX_TRYLOCK Try to lock umutex. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the umutex. .El .Pp Operates same as the .Dv UMTX_OP_MUTEX_LOCK request, but returns .Er EBUSY instead of sleeping if the lock cannot be obtained immediately. .It Dv UMTX_OP_MUTEX_LOCK Lock umutex. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the umutex. .El .Pp Locking is performed by writing the current thread id into the .Dv m_owner word of the .Vt struct umutex . The write is atomic, preserves the .Dv UMUTEX_CONTESTED contention indicator, and provides the acquire barrier for lock entrance semantic. .Pp If the lock cannot be obtained immediately because another thread owns the lock, the current thread is put to sleep, with .Dv UMUTEX_CONTESTED bit set before. Upon wake up, the lock conditions are re-tested. .Pp The request adheres to the priority protection or inheritance protocol of the mutex, specified by the .Dv UMUTEX_PRIO_PROTECT or .Dv UMUTEX_PRIO_INHERIT flag, respectively. .Pp Optionally, a timeout for the request may be specified. .Pp A request with a timeout specified is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. A request without timeout specified is always restarted after return from a signal handler. .It Dv UMTX_OP_MUTEX_UNLOCK Unlock umutex. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the umutex. .El .Pp Unlocks the mutex, by writing .Dv UMUTEX_UNOWNED (zero) value into .Dv m_owner word of the .Vt struct umutex . The write is done with a release barrier, to provide lock leave semantic. .Pp If there are threads sleeping in the sleep queue associated with the umutex, one thread is woken up. If more than one thread sleeps in the sleep queue, the .Dv UMUTEX_CONTESTED bit is set together with the write of the .Dv UMUTEX_UNOWNED value into .Dv m_owner . .Pp The request adheres to the priority protection or inheritance protocol of the mutex, specified by the .Dv UMUTEX_PRIO_PROTECT or .Dv UMUTEX_PRIO_INHERIT flag, respectively. See description of the .Dv m_ceilings member of the .Vt struct umutex structure for additional details of the request operation on the priority protected protocol mutex. .It Dv UMTX_OP_SET_CEILING Set ceiling for the priority protected umutex. The arguments to the request are: .Bl -tag -width "uaddr" .It Fa obj Pointer to the umutex. .It Fa val New ceiling value. .It Fa uaddr Address of a variable of type .Vt uint32_t . If not .Dv NULL and the update was successful, the previous ceiling value is written to the location pointed to by .Fa uaddr . .El .Pp The request locks the umutex pointed to by the .Fa obj parameter, waiting for the lock if not immediately available. After the lock is obtained, the new ceiling value .Fa val is written to the .Dv m_ceilings[0] member of the .Vt struct umutex, after which the umutex is unlocked. .Pp The locking does not adhere to the priority protect protocol, to conform to the .Tn POSIX requirements for the .Xr pthread_mutex_setprioceiling 3 interface. .It Dv UMTX_OP_CV_WAIT Wait for a condition. The arguments to the request are: .Bl -tag -width "uaddr2" .It Fa obj Pointer to the .Vt struct ucond . .It Fa val Request flags, see below. .It Fa uaddr Pointer to the umutex. .It Fa uaddr2 Optional pointer to a .Vt struct timespec for timeout specification. .El .Pp The request must be issued by the thread owning the mutex pointed to by the .Fa uaddr argument. The .Dv c_hash_waiters member of the .Vt struct ucond , pointed to by the .Fa obj argument, is set to an arbitrary non-zero value, after which the .Fa uaddr mutex is unlocked (following the appropriate protocol), and the current thread is put to sleep on the sleep queue keyed by the .Fa obj argument. The operations are performed atomically. It is guaranteed to not miss a wakeup from .Dv UMTX_OP_CV_SIGNAL or .Dv UMTX_OP_CV_BROADCAST sent between mutex unlock and putting the current thread on the sleep queue. .Pp Upon wakeup, if the timeout expired and no other threads are sleeping in the same sleep queue, the .Dv c_hash_waiters member is cleared. After wakeup, the .Fa uaddr umutex is not relocked. .Pp The following flags are defined: .Bl -tag -width "CVWAIT_CLOCKID" .It Dv CVWAIT_ABSTIME Timeout is absolute. .It Dv CVWAIT_CLOCKID Clockid is provided. .El .Pp Optionally, a timeout for the request may be specified. Unlike other requests, the timeout value is specified directly by a .Vt struct timespec , pointed to by the .Fa uaddr2 argument. If the .Dv CVWAIT_CLOCKID flag is provided, the timeout uses the clock from the .Dv c_clockid member of the .Vt struct ucond , pointed to by .Fa obj argument. Otherwise, .Dv CLOCK_REALTIME is used, regardless of the clock identifier possibly specified in the .Vt struct _umtx_time . If the .Dv CVWAIT_ABSTIME flag is supplied, the timeout specifies absolute time value, otherwise it denotes a relative time interval. .Pp The request is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. .It Dv UMTX_OP_CV_SIGNAL Wake up one condition waiter. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to .Vt struct ucond . .El .Pp The request wakes up at most one thread sleeping on the sleep queue keyed by the .Fa obj argument. If the woken up thread was the last on the sleep queue, the .Dv c_has_waiters member of the .Vt struct ucond is cleared. .It Dv UMTX_OP_CV_BROADCAST Wake up all condition waiters. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to .Vt struct ucond . .El .Pp The request wakes up all threads sleeping on the sleep queue keyed by the .Fa obj argument. The .Dv c_has_waiters member of the .Vt struct ucond is cleared. .It Dv UMTX_OP_WAIT_UINT Same as .Dv UMTX_OP_WAIT , but the type of the variable pointed to by .Fa obj is .Vt u_int .Pq a 32-bit integer . .It Dv UMTX_OP_RW_RDLOCK Read-lock a .Vt struct rwlock lock. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the lock (of type .Vt struct rwlock ) to be read-locked. .It Fa val Additional flags to augment locking behaviour. The valid flags in the .Fa val argument are: .Bl -tag -width indent .It Dv URWLOCK_PREFER_READER .El .El .Pp The request obtains the read lock on the specified .Vt struct rwlock by incrementing the count of readers in the .Dv rw_state word of the structure. If the .Dv URWLOCK_WRITE_OWNER bit is set in the word .Dv rw_state , the lock was granted to a writer which has not yet relinquished its ownership. In this case the current thread is put to sleep until it makes sense to retry. .Pp If the .Dv URWLOCK_PREFER_READER flag is set either in the .Dv rw_flags word of the structure, or in the .Fa val argument of the request, the presence of the threads trying to obtain the write lock on the same structure does not prevent the current thread from trying to obtain the read lock. Otherwise, if the flag is not set, and the .Dv URWLOCK_WRITE_WAITERS flag is set in .Dv rw_state , the current thread does not attempt to obtain read-lock. Instead it sets the .Dv URWLOCK_READ_WAITERS in the .Dv rw_state word and puts itself to sleep on corresponding sleep queue. Upon wakeup, the locking conditions are re-evaluated. .Pp Optionally, a timeout for the request may be specified. .Pp The request is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. .It Dv UMTX_OP_RW_WRLOCK Write-lock a .Vt struct rwlock lock. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the lock (of type .Vt struct rwlock ) to be write-locked. .El .Pp The request obtains a write lock on the specified .Vt struct rwlock , by setting the .Dv URWLOCK_WRITE_OWNER bit in the .Dv rw_state word of the structure. If there is already a write lock owner, as indicated by the .Dv URWLOCK_WRITE_OWNER bit being set, or there are read lock owners, as indicated by the read-lock counter, the current thread does not attempt to obtain the write-lock. Instead it sets the .Dv URWLOCK_WRITE_WAITERS in the .Dv rw_state word and puts itself to sleep on corresponding sleep queue. Upon wakeup, the locking conditions are re-evaluated. .Pp Optionally, a timeout for the request may be specified. .Pp The request is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. .It Dv UMTX_OP_RW_UNLOCK Unlock rwlock. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the lock (of type .Vt struct rwlock ) to be unlocked. .El .Pp The unlock type (read or write) is determined by the current lock state. Note that the .Vt struct rwlock does not save information about the identity of the thread which acquired the lock. .Pp If there are pending writers after the unlock, and the .Dv URWLOCK_PREFER_READER flag is not set in the .Dv rw_flags member of the .Fa *obj structure, one writer is woken up, selected as described in the .Sx SLEEP QUEUES subsection. If the .Dv URWLOCK_PREFER_READER flag is set, a pending writer is woken up only if there is no pending readers. .Pp If there are no pending writers, or, in the case that the .Dv URWLOCK_PREFER_READER flag is set, then all pending readers are woken up by unlock. .It Dv UMTX_OP_WAIT_UINT_PRIVATE Same as .Dv UMTX_OP_WAIT_UINT , but unconditionally select the process-private sleep queue. .It Dv UMTX_OP_WAKE_PRIVATE Same as .Dv UMTX_OP_WAKE , but unconditionally select the process-private sleep queue. .It Dv UMTX_OP_MUTEX_WAIT Wait for mutex availability. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Address of the mutex. .El .Pp Similarly to the .Dv UMTX_OP_MUTEX_LOCK , put the requesting thread to sleep if the mutex lock cannot be obtained immediately. The .Dv UMUTEX_CONTESTED bit is set in the .Dv m_owner word of the mutex to indicate that there is a waiter, before the thread is added to the sleep queue. Unlike the .Dv UMTX_OP_MUTEX_LOCK request, the lock is not obtained. .Pp The operation is not implemented for priority protected and priority inherited protocol mutexes. .Pp Optionally, a timeout for the request may be specified. .Pp A request with a timeout specified is not restartable. An unblocked signal delivered during the wait always results in sleep interruption and .Er EINTR error. A request without a timeout automatically restarts if the signal disposition requested restart via the .Dv SA_RESTART flag in .Vt struct sigaction member .Dv sa_flags . .It Dv UMTX_OP_NWAKE_PRIVATE Wake up a batch of sleeping threads. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the array of pointers. .It Fa val Number of elements in the array pointed to by .Fa obj . .El .Pp For each element in the array pointed to by .Fa obj , wakes up all threads waiting on the .Em private sleep queue with the key being the byte addressed by the array element. .It Dv UMTX_OP_MUTEX_WAKE Check if a normal umutex is unlocked and wake up a waiter. The arguments for the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the umutex. .El .Pp If the .Dv m_owner word of the mutex pointed to by the .Fa obj argument indicates unowned mutex, which has its contention indicator bit .Dv UMUTEX_CONTESTED set, clear the bit and wake up one waiter in the sleep queue associated with the byte addressed by the .Fa obj , if any. Only normal mutexes are supported by the request. The sleep queue is always one for a normal mutex type. .Pp This request is deprecated in favor of .Dv UMTX_OP_MUTEX_WAKE2 since mutexes using it cannot synchronize their own destruction. That is, the .Dv m_owner word has already been set to .Dv UMUTEX_UNOWNED when this request is made, so that another thread can lock, unlock and destroy the mutex (if no other thread uses the mutex afterwards). Clearing the .Dv UMUTEX_CONTESTED bit may then modify freed memory. .It Dv UMTX_OP_MUTEX_WAKE2 Check if a umutex is unlocked and wake up a waiter. The arguments for the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the umutex. .It Fa val The umutex flags. .El .Pp The request does not read the .Dv m_flags member of the .Vt struct umutex ; instead, the .Fa val argument supplies flag information, in particular, to determine the sleep queue where the waiters are found for wake up. .Pp If the mutex is unowned, one waiter is woken up. .Pp If the mutex memory cannot be accessed, all waiters are woken up. .Pp If there is more than one waiter on the sleep queue, or there is only one waiter but the mutex is owned by a thread, the .Dv UMUTEX_CONTESTED bit is set in the .Dv m_owner word of the .Vt struct umutex . .It Dv UMTX_OP_SEM2_WAIT Wait until semaphore is available. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the semaphore (of type .Vt struct _usem2 ) . .It Fa uaddr Size of the memory passed in via the .Fa uaddr2 argument. .It Fa uaddr2 Optional pointer to a structure of type .Vt struct _umtx_time , which may be followed by a structure of type .Vt struct timespec . .El .Pp Put the requesting thread onto a sleep queue if the semaphore counter is zero. If the thread is put to sleep, the .Dv USEM_HAS_WAITERS bit is set in the .Dv _count word to indicate waiters. The function returns either due to .Dv _count indicating the semaphore is available (non-zero count due to post), or due to a wakeup. The return does not guarantee that the semaphore is available, nor does it consume the semaphore lock on successful return. .Pp Optionally, a timeout for the request may be specified. .Pp A request with non-absolute timeout value is not restartable. An unblocked signal delivered during such wait results in sleep interruption and .Er EINTR error. .Pp If .Dv UMTX_ABSTIME was not set, and the operation was interrupted and the caller passed in a .Fa uaddr2 large enough to hold a .Vt struct timespec following the initial .Vt struct _umtx_time , then the .Vt struct timespec is updated to contain the unslept amount. .It Dv UMTX_OP_SEM2_WAKE Wake up waiters on semaphore lock. The arguments to the request are: .Bl -tag -width "obj" .It Fa obj Pointer to the semaphore (of type .Vt struct _usem2 ) . .El .Pp The request wakes up one waiter for the semaphore lock. The function does not increment the semaphore lock count. If the .Dv USEM_HAS_WAITERS bit was set in the .Dv _count word, and the last sleeping thread was woken up, the bit is cleared. .It Dv UMTX_OP_SHM Manage anonymous .Tn POSIX shared memory objects (see .Xr shm_open 2 ) , which can be attached to a byte of physical memory, mapped into the process address space. The objects are used to implement process-shared locks in .Dv libthr . .Pp The .Fa val argument specifies the sub-request of the .Dv UMTX_OP_SHM request: .Bl -tag -width indent .It Dv UMTX_SHM_CREAT Creates the anonymous shared memory object, which can be looked up with the specified key .Fa uaddr . If the object associated with the .Fa uaddr key already exists, it is returned instead of creating a new object. The object's size is one page. On success, the file descriptor referencing the object is returned. The descriptor can be used for mapping the object using .Xr mmap 2 , or for other shared memory operations. .It Dv UMTX_SHM_LOOKUP Same as .Dv UMTX_SHM_CREATE request, but if there is no shared memory object associated with the specified key .Fa uaddr , an error is returned, and no new object is created. .It Dv UMTX_SHM_DESTROY De-associate the shared object with the specified key .Fa uaddr . The object is destroyed after the last open file descriptor is closed and the last mapping for it is destroyed. .It Dv UMTX_SHM_ALIVE Checks whether there is a live shared object associated with the supplied key .Fa uaddr . Returns zero if there is, and an error otherwise. This request is an optimization of the .Dv UMTX_SHM_LOOKUP request. It is cheaper when only the liveness of the associated object is asked for, since no file descriptor is installed in the process fd table on success. .El .Pp The .Fa uaddr argument specifies the virtual address, which backing physical memory byte identity is used as a key for the anonymous shared object creation or lookup. .It Dv UMTX_OP_ROBUST_LISTS Register the list heads for the current thread's robust mutex lists. The arguments to the request are: .Bl -tag -width "uaddr" .It Fa val Size of the structure passed in the .Fa uaddr argument. .It Fa uaddr Pointer to the structure of type .Vt struct umtx_robust_lists_params . .El .Pp The structure is defined as .Bd -literal struct umtx_robust_lists_params { uintptr_t robust_list_offset; uintptr_t robust_priv_list_offset; uintptr_t robust_inact_offset; }; .Ed .Pp The .Dv robust_list_offset member contains address of the first element in the list of locked robust shared mutexes. The .Dv robust_priv_list_offset member contains address of the first element in the list of locked robust private mutexes. The private and shared robust locked lists are split to allow fast termination of the shared list on fork, in the child. .Pp The .Dv robust_inact_offset contains a pointer to the mutex which might be locked in nearby future, or might have been just unlocked. It is typically set by the lock or unlock mutex implementation code around the whole operation, since lists can be only changed race-free when the thread owns the mutex. The kernel inspects the .Dv robust_inact_offset in addition to walking the shared and private lists. Also, the mutex pointed to by .Dv robust_inact_offset is handled more loosely at the thread termination time, than other mutexes on the list. That mutex is allowed to be not owned by the current thread, in which case list processing is continued. See .Sx ROBUST UMUTEXES subsection for details. .It Dv UMTX_OP_GET_MIN_TIMEOUT Writes out the current value of minimal umtx operations timeout, in nanoseconds, into the long integer variable pointed to by .Fa uaddr1 . .It Dv UMTX_OP_SET_MIN_TIMEOUT Set the minimal amount of time, in nanoseconds, the thread is required to sleep for umtx operations specifying a timeout using absolute clocks. The value is taken from the .Fa val argument of the call. Zero means no minimum. .El .Pp The .Fa op argument may be a bitwise OR of a single command from above with one or more of the following flags: .Bl -tag -width indent .It Dv UMTX_OP__I386 Request i386 ABI compatibility from the native .Nm system call. Specifically, this implies that: .Bl -hang -offset indent .It .Fa obj arguments that point to a word, point to a 32-bit integer. .It The .Dv UMTX_OP_NWAKE_PRIVATE .Fa obj argument is a pointer to an array of 32-bit pointers. .It The .Dv m_rb_lnk member of .Vt struct umutex is a 32-bit pointer. .It .Vt struct timespec uses a 32-bit time_t. .El .Pp .Dv UMTX_OP__32BIT has no effect if this flag is set. This flag is valid for all architectures, but it is ignored on i386. .It Dv UMTX_OP__32BIT Request non-i386, 32-bit ABI compatibility from the native .Nm system call. Specifically, this implies that: .Bl -hang -offset indent .It .Fa obj arguments that point to a word, point to a 32-bit integer. .It The .Dv UMTX_OP_NWAKE_PRIVATE .Fa obj argument is a pointer to an array of 32-bit pointers. .It The .Dv m_rb_lnk member of .Vt struct umutex is a 32-bit pointer. .It .Vt struct timespec uses a 64-bit time_t. .El .Pp This flag has no effect if .Dv UMTX_OP__I386 is set. This flag is valid for all architectures. .El .Pp Note that if any 32-bit ABI compatibility is being requested, then care must be taken with robust lists. A single thread may not mix 32-bit compatible robust lists with native robust lists. The first .Dv UMTX_OP_ROBUST_LISTS call in a given thread determines which ABI that thread will use for robust lists going forward. .Sh RETURN VALUES If successful, all requests, except .Dv UMTX_SHM_CREAT and .Dv UMTX_SHM_LOOKUP sub-requests of the .Dv UMTX_OP_SHM request, will return zero. The .Dv UMTX_SHM_CREAT and .Dv UMTX_SHM_LOOKUP return a shared memory file descriptor on success. On error \-1 is returned, and the .Va errno variable is set to indicate the error. .Sh ERRORS The .Fn _umtx_op operations can fail with the following errors: .Bl -tag -width "[ETIMEDOUT]" .It Bq Er EFAULT One of the arguments point to invalid memory. .It Bq Er EINVAL The clock identifier, specified for the .Vt struct _umtx_time timeout parameter, or in the .Dv c_clockid member of .Vt struct ucond, is invalid. .It Bq Er EINVAL The type of the mutex, encoded by the .Dv m_flags member of .Vt struct umutex , is invalid. .It Bq Er EINVAL The .Dv m_owner member of the .Vt struct umutex has changed the lock owner thread identifier during unlock. .It Bq Er EINVAL The .Dv timeout.tv_sec or .Dv timeout.tv_nsec member of .Vt struct _umtx_time is less than zero, or .Dv timeout.tv_nsec is greater than 1000000000. .It Bq Er EINVAL The .Fa op argument specifies invalid operation. .It Bq Er EINVAL The .Fa uaddr argument for the .Dv UMTX_OP_SHM request specifies invalid operation. .It Bq Er EINVAL The .Dv UMTX_OP_SET_CEILING request specifies non priority protected mutex. .It Bq Er EINVAL The new ceiling value for the .Dv UMTX_OP_SET_CEILING request, or one or more of the values read from the .Dv m_ceilings array during lock or unlock operations, is greater than .Dv RTP_PRIO_MAX . .It Bq Er EPERM Unlock attempted on an object not owned by the current thread. .It Bq Er EOWNERDEAD The lock was requested on an umutex where the .Dv m_owner field was set to the .Dv UMUTEX_RB_OWNERDEAD value, indicating terminated robust mutex. The lock was granted to the caller, so this error in fact indicates success with additional conditions. .It Bq Er ENOTRECOVERABLE The lock was requested on an umutex which .Dv m_owner field is equal to the .Dv UMUTEX_RB_NOTRECOV value, indicating abandoned robust mutex after termination. The lock was not granted to the caller. .It Bq Er ENOTTY The shared memory object, associated with the address passed to the .Dv UMTX_SHM_ALIVE sub-request of .Dv UMTX_OP_SHM request, was destroyed. .It Bq Er ESRCH For the .Dv UMTX_SHM_LOOKUP , .Dv UMTX_SHM_DESTROY , and .Dv UMTX_SHM_ALIVE sub-requests of the .Dv UMTX_OP_SHM request, there is no shared memory object associated with the provided key. .It Bq Er ENOMEM The .Dv UMTX_SHM_CREAT sub-request of the .Dv UMTX_OP_SHM request cannot be satisfied, because allocation of the shared memory object would exceed the .Dv RLIMIT_UMTXP resource limit, see .Xr setrlimit 2 . .It Bq Er EAGAIN The maximum number of readers .Dv ( URWLOCK_MAX_READERS ) were already granted ownership of the given .Vt struct rwlock for read. .It Bq Er EBUSY A try mutex lock operation was not able to obtain the lock. .It Bq Er ETIMEDOUT The request specified a timeout in the .Fa uaddr and .Fa uaddr2 arguments, and timed out before obtaining the lock or being woken up. .It Bq Er EINTR A signal was delivered during wait, for a non-restartable operation. Operations with timeouts are typically non-restartable, but timeouts specified in absolute time may be restartable. .It Bq Er ERESTART A signal was delivered during wait, for a restartable operation. Mutex lock requests without timeout specified are restartable. The error is not returned to userspace code since restart is handled by usual adjustment of the instruction counter. .El .Sh SEE ALSO .Xr clock_gettime 2 , .Xr mmap 2 , .Xr setrlimit 2 , .Xr shm_open 2 , .Xr sigaction 2 , .Xr thr_exit 2 , .Xr thr_kill 2 , .Xr thr_kill2 2 , .Xr thr_new 2 , .Xr thr_self 2 , .Xr thr_set_name 2 , .Xr signal 3 .Sh STANDARDS The .Fn _umtx_op system call is non-standard and is used by the .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh BUGS A window between a unlocking robust mutex and resetting the pointer in the .Dv robust_inact_offset member of the registered .Vt struct umtx_robust_lists_params allows another thread to destroy the mutex, thus making the kernel inspect freed or reused memory. The .Li libthr implementation is only vulnerable to this race when operating on a shared mutex. A possible fix for the current implementation is to strengthen the checks for shared mutexes before terminating them, in particular, verifying that the mutex memory is mapped from a shared memory object allocated by the .Dv UMTX_OP_SHM request. This is not done because it is believed that the race is adequately covered by other consistency checks, while adding the check would prevent alternative implementations of .Li libpthread . diff --git a/lib/libc/sys/accept.c b/lib/libc/sys/accept.c index d7dcd29d85f1..417fb344a91e 100644 --- a/lib/libc/sys/accept.c +++ b/lib/libc/sys/accept.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_accept, __accept); #pragma weak accept int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { return (((int (*)(int, struct sockaddr *, socklen_t *)) __libc_interposing[INTERPOS_accept])(s, addr, addrlen)); } diff --git a/lib/libc/sys/accept4.c b/lib/libc/sys/accept4.c index 0cba423096ef..56cc06efdfe6 100644 --- a/lib/libc/sys/accept4.c +++ b/lib/libc/sys/accept4.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_accept4, __accept4); #pragma weak accept4 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) { return (((int (*)(int, struct sockaddr *, socklen_t *, int)) __libc_interposing[INTERPOS_accept4])(s, addr, addrlen, flags)); } diff --git a/lib/libc/sys/aio_suspend.c b/lib/libc/sys/aio_suspend.c index 595be6183083..fc9a0d906c92 100644 --- a/lib/libc/sys/aio_suspend.c +++ b/lib/libc/sys/aio_suspend.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_aio_suspend, __aio_suspend); #pragma weak aio_suspend int aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct timespec *timeout) { return (((int (*)(const struct aiocb * const[], int, const struct timespec *)) __libc_interposing[INTERPOS_aio_suspend])(iocbs, niocb, timeout)); } diff --git a/lib/libc/sys/bindat.2 b/lib/libc/sys/bindat.2 index ecfd7275b43a..a31ef2715db9 100644 --- a/lib/libc/sys/bindat.2 +++ b/lib/libc/sys/bindat.2 @@ -1,106 +1,105 @@ .\" Copyright (c) 2013 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 February 13, 2013 .Dt BINDAT 2 .Os .Sh NAME .Nm bindat .Nd assign a local protocol address to a socket .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/types.h .In sys/socket.h .Pp .In fcntl.h .Ft int .Fn bindat "int fd" "int s" "const struct sockaddr *addr" "socklen_t addrlen" .Sh DESCRIPTION The .Fn bindat system call assigns the local protocol address to a socket. When passed the special value .Dv AT_FDCWD in the .Fa fd parameter, the behavior is identical to a call to .Xr bind 2 . Otherwise, .Fn bindat works like the .Xr bind 2 system call with two exceptions: .Pp .Bl -enum -offset indent -compact .It It is limited to sockets in the PF_LOCAL domain. .Pp .It If the file path stored in the .Fa sun_path field of the sockaddr_un structure is a relative path, it is located relative to the directory associated with the file descriptor .Fa fd . .El .Sh RETURN VALUES .Rv -std bindat .Sh ERRORS The .Fn bindat system call may fail with the same errors as the .Xr bind 2 system call or with the following errors: .Bl -tag -width Er .It Bq Er EBADF The .Fa sun_path field does not specify an absolute path and the .Fa fd argument is neither .Dv AT_FDCWD nor a valid file descriptor. .It Bq Er ENOTDIR The .Fa sun_path field is not an absolute path and .Fa fd is neither .Dv AT_FDCWD nor a file descriptor associated with a directory. .El .Sh SEE ALSO .Xr bind 2 , .Xr connectat 2 , .Xr socket 2 , .Xr unix 4 .Sh AUTHORS The .Nm was developed by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship from the FreeBSD Foundation. diff --git a/lib/libc/sys/cap_fcntls_limit.2 b/lib/libc/sys/cap_fcntls_limit.2 index 3a7244639ee6..299594e9be66 100644 --- a/lib/libc/sys/cap_fcntls_limit.2 +++ b/lib/libc/sys/cap_fcntls_limit.2 @@ -1,133 +1,132 @@ .\" .\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship .\" the FreeBSD Foundation. .\" .\" 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 March 9, 2023 .Dt CAP_FCNTLS_LIMIT 2 .Os .Sh NAME .Nm cap_fcntls_limit , .Nm cap_fcntls_get .Nd manage allowed fcntl commands .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/capsicum.h .Ft int .Fn cap_fcntls_limit "int fd" "uint32_t fcntlrights" .Ft int .Fn cap_fcntls_get "int fd" "uint32_t *fcntlrightsp" .Sh DESCRIPTION If a file descriptor is granted the .Dv CAP_FCNTL capability right, the list of allowed .Xr fcntl 2 commands can be selectively reduced (but never expanded) with the .Fn cap_fcntls_limit system call. .Pp A bitmask of allowed fcntls commands for a given file descriptor can be obtained with the .Fn cap_fcntls_get system call. .Sh FLAGS The following flags may be specified in the .Fa fcntlrights argument or returned in the .Fa fcntlrightsp argument: .Bl -tag -width CAP_FCNTL_GETOWN .It Dv CAP_FCNTL_GETFL Permit .Dv F_GETFL command. .It Dv CAP_FCNTL_SETFL Permit .Dv F_SETFL command. .It Dv CAP_FCNTL_GETOWN Permit .Dv F_GETOWN command. .It Dv CAP_FCNTL_SETOWN Permit .Dv F_SETOWN command. .El .Sh RETURN VALUES .Rv -std .Sh ERRORS .Fn cap_fcntls_limit succeeds unless: .Bl -tag -width Er .It Bq Er EBADF The .Fa fd argument is not a valid descriptor. .It Bq Er EINVAL An invalid flag has been passed in .Fa fcntlrights . .It Bq Er ENOTCAPABLE .Fa fcntlrights would expand the list of allowed .Xr fcntl 2 commands. .El .Pp .Fn cap_fcntls_get succeeds unless: .Bl -tag -width Er .It Bq Er EBADF The .Fa fd argument is not a valid descriptor. .It Bq Er EFAULT The .Fa fcntlrightsp argument points at an invalid address. .It Bq Er ENOSYS The running kernel was compiled without .Cd "options CAPABILITY_MODE" . .El .Sh SEE ALSO .Xr cap_ioctls_limit 2 , .Xr cap_rights_limit 2 , .Xr fcntl 2 .Sh HISTORY The .Fn cap_fcntls_get and .Fn cap_fcntls_limit system calls first appeared in .Fx 8.3 . Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD Project. .Sh AUTHORS This function was created by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/sys/cap_ioctls_limit.2 b/lib/libc/sys/cap_ioctls_limit.2 index 738a13fe42b5..c9d468ba8fac 100644 --- a/lib/libc/sys/cap_ioctls_limit.2 +++ b/lib/libc/sys/cap_ioctls_limit.2 @@ -1,162 +1,161 @@ .\" .\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship .\" the FreeBSD Foundation. .\" .\" 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 March 9, 2023 .Dt CAP_IOCTLS_LIMIT 2 .Os .Sh NAME .Nm cap_ioctls_limit , .Nm cap_ioctls_get .Nd manage allowed ioctl commands .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/capsicum.h .Ft int .Fn cap_ioctls_limit "int fd" "const unsigned long *cmds" "size_t ncmds" .Ft ssize_t .Fn cap_ioctls_get "int fd" "unsigned long *cmds" "size_t maxcmds" .Sh DESCRIPTION If a file descriptor is granted the .Dv CAP_IOCTL capability right, the list of allowed .Xr ioctl 2 commands can be selectively reduced (but never expanded) with the .Fn cap_ioctls_limit system call. The .Fa cmds argument is an array of .Xr ioctl 2 commands and the .Fa ncmds argument specifies the number of elements in the array. There can be up to .Va 256 elements in the array. Including an element that has been previously revoked will generate an error. After a successful call only those listed in the array may be used. .Pp The list of allowed ioctl commands for a given file descriptor can be obtained with the .Fn cap_ioctls_get system call. The .Fa cmds argument points at memory that can hold up to .Fa maxcmds values. The function populates the provided buffer with up to .Fa maxcmds elements, but always returns the total number of ioctl commands allowed for the given file descriptor. The total number of ioctls commands for the given file descriptor can be obtained by passing .Dv NULL as the .Fa cmds argument and .Va 0 as the .Fa maxcmds argument. If all ioctl commands are allowed .Dv ( CAP_IOCTL capability right is assigned to the file descriptor and the .Fn cap_ioctls_limit system call was never called for this file descriptor), the .Fn cap_ioctls_get system call will return .Dv CAP_IOCTLS_ALL and will not modify the buffer pointed to by the .Fa cmds argument. .Sh RETURN VALUES .Rv -std cap_ioctls_limit .Pp The .Fn cap_ioctls_get function, if successful, returns the total number of allowed ioctl commands or the value .Dv CAP_IOCTLS_ALL if all ioctls commands are allowed. On failure the value .Va -1 is returned and the global variable errno is set to indicate the error. .Sh ERRORS The .Fn cap_ioctls_limit and .Fn cap_ioctls_get system calls will fail if: .Bl -tag -width Er .It Bq Er EBADF The .Fa fd argument is not a valid descriptor. .It Bq Er EFAULT The .Fa cmds argument points at an invalid address. .It Bq Er ENOSYS The running kernel was compiled without .Cd "options CAPABILITY_MODE" . .El .Pp The .Fn cap_ioctls_limit system call may also return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The .Fa ncmds argument is greater than .Va 256 . .It Bq Er ENOTCAPABLE .Fa cmds would expand the list of allowed .Xr ioctl 2 commands. .El .Sh SEE ALSO .Xr cap_fcntls_limit 2 , .Xr cap_rights_limit 2 , .Xr ioctl 2 .Sh HISTORY The .Fn cap_ioctls_get and .Fn cap_ioctls_limit system calls first appeared in .Fx 8.3 . Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD Project. .Sh AUTHORS This function was created by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/sys/close.c b/lib/libc/sys/close.c index 373fb36f81d0..0fb319b77102 100644 --- a/lib/libc/sys/close.c +++ b/lib/libc/sys/close.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_close, __close); #pragma weak close int close(int fd) { return (((int (*)(int))__libc_interposing[INTERPOS_close])(fd)); } diff --git a/lib/libc/sys/connect.c b/lib/libc/sys/connect.c index 89d3ae0b8688..10277dfadc64 100644 --- a/lib/libc/sys/connect.c +++ b/lib/libc/sys/connect.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_connect, __connect); #pragma weak connect int connect(int s, const struct sockaddr *addr, socklen_t addrlen) { return (((int (*)(int, const struct sockaddr *, socklen_t)) __libc_interposing[INTERPOS_connect])(s, addr, addrlen)); } diff --git a/lib/libc/sys/connectat.2 b/lib/libc/sys/connectat.2 index 6d5ed90243eb..64fd805549b7 100644 --- a/lib/libc/sys/connectat.2 +++ b/lib/libc/sys/connectat.2 @@ -1,107 +1,106 @@ .\" Copyright (c) 2013 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Pawel Jakub Dawidek under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 February 13, 2013 .Dt CONNECTAT 2 .Os .Sh NAME .Nm connectat .Nd initiate a connection on a socket .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/types.h .In sys/socket.h .Pp .In fcntl.h .Ft int .Fn connectat "int fd" "int s" "const struct sockaddr *name" "socklen_t namelen" .Sh DESCRIPTION The .Fn connectat system call initiates a connection on the socket .Fa s . When passed the special value .Dv AT_FDCWD in the .Fa fd parameter, the behavior is identical to a call to .Xr connect 2 . Otherwise, .Fn connectat works like the .Xr connect 2 system call with two exceptions: .Pp .Bl -enum -offset indent -compact .It It is limited to sockets in the PF_LOCAL domain. .Pp .It If the file path stored in the .Fa sun_path field of the sockaddr_un structure is a relative path, it is located relative to the directory associated with the file descriptor .Fa fd . .El .Sh RETURN VALUES .Rv -std connectat .Sh ERRORS The .Fn connectat system call may fail with the same errors as the .Xr connect 2 system call or with the following errors: .Bl -tag -width Er .It Bq Er EBADF The .Fa sun_path field does not specify an absolute path and the .Fa fd argument is neither .Dv AT_FDCWD nor a valid file descriptor. .It Bq Er ENOTDIR The .Fa sun_path field is not an absolute path and .Fa fd is neither .Dv AT_FDCWD nor a file descriptor associated with a directory. .El .Sh SEE ALSO .Xr bindat 2 , .Xr connect 2 , .Xr socket 2 , .Xr unix 4 .Sh AUTHORS The .Nm was developed by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship from the FreeBSD Foundation. diff --git a/lib/libc/sys/fcntl.c b/lib/libc/sys/fcntl.c index 682541774187..ff231981d079 100644 --- a/lib/libc/sys/fcntl.c +++ b/lib/libc/sys/fcntl.c @@ -1,56 +1,55 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ * Authors: Doug Rabson * Developed with Red Inc: Alfred Perlstein * * Copyright (c) 2014-2015 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include "libc_private.h" #pragma weak fcntl int fcntl(int fd, int cmd, ...) { va_list args; long arg; va_start(args, cmd); arg = va_arg(args, long); va_end(args); return (((int (*)(int, int, ...)) __libc_interposing[INTERPOS_fcntl])(fd, cmd, arg)); } diff --git a/lib/libc/sys/fdatasync.c b/lib/libc/sys/fdatasync.c index ff19ea6f02ae..b56d5aa533d4 100644 --- a/lib/libc/sys/fdatasync.c +++ b/lib/libc/sys/fdatasync.c @@ -1,44 +1,43 @@ /* * Copyright (c) 2016 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" int fdatasync(int fd) { return (((int (*)(int))__libc_interposing[INTERPOS_fdatasync])(fd)); } diff --git a/lib/libc/sys/fork.c b/lib/libc/sys/fork.c index dfa17fd0c670..c45e5c93f226 100644 --- a/lib/libc/sys/fork.c +++ b/lib/libc/sys/fork.c @@ -1,46 +1,45 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_fork, __fork); #pragma weak fork pid_t fork(void) { return (((pid_t (*)(void))__libc_interposing[INTERPOS_fork])()); } diff --git a/lib/libc/sys/fsync.2 b/lib/libc/sys/fsync.2 index df7b545af274..02cdf9bd656b 100644 --- a/lib/libc/sys/fsync.2 +++ b/lib/libc/sys/fsync.2 @@ -1,133 +1,132 @@ .\" Copyright (c) 1983, 1993 .\" The Regents of the University of California. All rights reserved. .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" Parts of this documentation were written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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. .\" .\" @(#)fsync.2 8.1 (Berkeley) 6/4/93 .\" .Dd March 30, 2020 .Dt FSYNC 2 .Os .Sh NAME .Nm fdatasync , .Nm fsync .Nd "synchronise changes to a file" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In unistd.h .Ft int .Fn fdatasync "int fd" .Ft int .Fn fsync "int fd" .Sh DESCRIPTION The .Fn fsync system call causes all modified data and attributes of the file referenced by the file descriptor .Fa fd to be moved to a permanent storage device. This normally results in all in-core modified copies of buffers for the associated file to be written to a disk. .Pp The .Fn fdatasync system call causes all modified data of .Fa fd to be moved to a permanent storage device. Unlike .Fn fsync , the system call does not guarantee that file attributes or metadata necessary to access the file are committed to the permanent storage. .Pp The .Fn fsync system call should be used by programs that require a file to be in a known state, for example, in building a simple transaction facility. If the file metadata has already been committed, using .Fn fdatasync can be more efficient than .Fn fsync . .Pp Both .Fn fdatasync and .Fn fsync calls are cancellation points. .Sh RETURN VALUES .Rv -std fsync .Sh ERRORS The .Fn fsync and .Fn fdatasync calls fail if: .Bl -tag -width Er .It Bq Er EBADF The .Fa fd argument is not a valid descriptor. .It Bq Er EINVAL The .Fa fd argument refers to a socket, not to a file. .It Bq Er EIO An I/O error occurred while reading from or writing to the file system. .It Bq Er EINTEGRITY Corrupted data was detected while reading from the file system. .El .Sh SEE ALSO .Xr fsync 1 , .Xr sync 2 , .Xr syncer 4 , .Xr sync 8 .Sh HISTORY The .Fn fsync system call appeared in .Bx 4.2 . The .Fn fdatasync system call appeared in .Fx 11.1 . .Sh BUGS The .Fn fdatasync system call currently does not guarantee that enqueued .Xr aio 4 requests for the file referenced by .Fa fd are completed before the syscall returns. diff --git a/lib/libc/sys/fsync.c b/lib/libc/sys/fsync.c index 27d108cd9c98..ae9554f468f6 100644 --- a/lib/libc/sys/fsync.c +++ b/lib/libc/sys/fsync.c @@ -1,46 +1,45 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_fsync, __fsync); int fsync(int fd) { return (((int (*)(int))__libc_interposing[INTERPOS_fsync])(fd)); } diff --git a/lib/libc/sys/interposing_table.c b/lib/libc/sys/interposing_table.c index 6c19180c589e..d5517a83b14a 100644 --- a/lib/libc/sys/interposing_table.c +++ b/lib/libc/sys/interposing_table.c @@ -1,92 +1,91 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include "libc_private.h" #define SLOT(a, b) \ [INTERPOS_##a] = (interpos_func_t)b interpos_func_t __libc_interposing[INTERPOS_MAX] = { SLOT(accept, __sys_accept), SLOT(accept4, __sys_accept4), SLOT(aio_suspend, __sys_aio_suspend), SLOT(close, __sys_close), SLOT(connect, __sys_connect), SLOT(fcntl, __sys_fcntl), SLOT(fsync, __sys_fsync), SLOT(fork, __sys_fork), SLOT(msync, __sys_msync), SLOT(nanosleep, __sys_nanosleep), SLOT(openat, __sys_openat), SLOT(poll, __sys_poll), SLOT(pselect, __sys_pselect), SLOT(read, __sys_read), SLOT(readv, __sys_readv), SLOT(recvfrom, __sys_recvfrom), SLOT(recvmsg, __sys_recvmsg), SLOT(select, __sys_select), SLOT(sendmsg, __sys_sendmsg), SLOT(sendto, __sys_sendto), SLOT(setcontext, __sys_setcontext), SLOT(sigaction, __sys_sigaction), SLOT(sigprocmask, __sys_sigprocmask), SLOT(sigsuspend, __sys_sigsuspend), SLOT(sigwait, __libc_sigwait), SLOT(sigtimedwait, __sys_sigtimedwait), SLOT(sigwaitinfo, __sys_sigwaitinfo), SLOT(swapcontext, __sys_swapcontext), SLOT(system, __libc_system), SLOT(tcdrain, __libc_tcdrain), SLOT(wait4, __sys_wait4), SLOT(write, __sys_write), SLOT(writev, __sys_writev), SLOT(_pthread_mutex_init_calloc_cb, _pthread_mutex_init_calloc_cb_stub), SLOT(spinlock, __libc_spinlock_stub), SLOT(spinunlock, __libc_spinunlock_stub), SLOT(kevent, __sys_kevent), SLOT(wait6, __sys_wait6), SLOT(ppoll, __sys_ppoll), SLOT(map_stacks_exec, __libc_map_stacks_exec), SLOT(fdatasync, __sys_fdatasync), SLOT(clock_nanosleep, __sys_clock_nanosleep), SLOT(distribute_static_tls, __libc_distribute_static_tls), SLOT(pdfork, __sys_pdfork), }; #undef SLOT interpos_func_t * __libc_interposing_slot(int interposno) { return (&__libc_interposing[interposno]); } diff --git a/lib/libc/sys/kevent.c b/lib/libc/sys/kevent.c index dafec8fa692f..ef2440721bb4 100644 --- a/lib/libc/sys/kevent.c +++ b/lib/libc/sys/kevent.c @@ -1,51 +1,50 @@ /* * Copyright (c) 2015 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_kevent, __kevent); #pragma weak kevent int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout) { return (((int (*)(int, const struct kevent *, int, struct kevent *, int, const struct timespec *)) __libc_interposing[INTERPOS_kevent])(kq, changelist, nchanges, eventlist, nevents, timeout)); } diff --git a/lib/libc/sys/msync.c b/lib/libc/sys/msync.c index a4cd6d16adc3..96b0e778d115 100644 --- a/lib/libc/sys/msync.c +++ b/lib/libc/sys/msync.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_msync, __msync); #pragma weak msync int msync(void *addr, size_t len, int flags) { return (((int (*)(void *, size_t, int)) __libc_interposing[INTERPOS_msync])(addr, len, flags)); } diff --git a/lib/libc/sys/nanosleep.c b/lib/libc/sys/nanosleep.c index 6b5711192d0a..076ee33e44ea 100644 --- a/lib/libc/sys/nanosleep.c +++ b/lib/libc/sys/nanosleep.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_nanosleep, __nanosleep); #pragma weak nanosleep int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { return (((int (*)(const struct timespec *, struct timespec *)) __libc_interposing[INTERPOS_nanosleep])(rqtp, rmtp)); } diff --git a/lib/libc/sys/open.c b/lib/libc/sys/open.c index 24552c024ef2..020134d5693b 100644 --- a/lib/libc/sys/open.c +++ b/lib/libc/sys/open.c @@ -1,57 +1,56 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_open, __open); #pragma weak open int open(const char *path, int flags, ...) { va_list ap; int mode; if ((flags & O_CREAT) != 0) { va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); } else { mode = 0; } return (((int (*)(int, const char *, int, ...)) __libc_interposing[INTERPOS_openat])(AT_FDCWD, path, flags, mode)); } diff --git a/lib/libc/sys/openat.c b/lib/libc/sys/openat.c index 3150400a9dca..9edf7d493bfd 100644 --- a/lib/libc/sys/openat.c +++ b/lib/libc/sys/openat.c @@ -1,60 +1,59 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_openat, __openat); __sym_compat(openat, __impl_openat, FBSD_1.1); __weak_reference(openat, __impl_openat); __sym_default(openat, openat, FBSD_1.2); #pragma weak openat int openat(int fd, const char *path, int flags, ...) { va_list ap; int mode; if ((flags & O_CREAT) != 0) { va_start(ap, flags); mode = va_arg(ap, int); va_end(ap); } else { mode = 0; } return (((int (*)(int, const char *, int, ...)) __libc_interposing[INTERPOS_openat])(fd, path, flags, mode)); } diff --git a/lib/libc/sys/pdfork.c b/lib/libc/sys/pdfork.c index 912aba2b23dc..601426b4d4db 100644 --- a/lib/libc/sys/pdfork.c +++ b/lib/libc/sys/pdfork.c @@ -1,44 +1,43 @@ /* * Copyright (c) 2021 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" #pragma weak pdfork pid_t pdfork(int *fdp, int flags) { return (((pid_t (*)(int *, int))__libc_interposing[ INTERPOS_pdfork])(fdp, flags)); } diff --git a/lib/libc/sys/poll.c b/lib/libc/sys/poll.c index f4c92a9463bf..f03320dc9319 100644 --- a/lib/libc/sys/poll.c +++ b/lib/libc/sys/poll.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_poll, __poll); #pragma weak poll int poll(struct pollfd pfd[], nfds_t nfds, int timeout) { return (((int (*)(struct pollfd *, nfds_t, int)) __libc_interposing[INTERPOS_poll])(pfd, nfds, timeout)); } diff --git a/lib/libc/sys/ppoll.c b/lib/libc/sys/ppoll.c index a58dac393439..8f886b8c5108 100644 --- a/lib/libc/sys/ppoll.c +++ b/lib/libc/sys/ppoll.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2015 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_ppoll, __ppoll); #pragma weak ppoll int ppoll(struct pollfd pfd[], nfds_t nfds, const struct timespec *__restrict timeout, const sigset_t *__restrict newsigmask) { return (((int (*)(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *)) __libc_interposing[INTERPOS_ppoll])(pfd, nfds, timeout, newsigmask)); } diff --git a/lib/libc/sys/pselect.c b/lib/libc/sys/pselect.c index 1774c465f0db..2ea717ef1d65 100644 --- a/lib/libc/sys/pselect.c +++ b/lib/libc/sys/pselect.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_pselect, __pselect); #pragma weak pselect int pselect(int n, fd_set *rs, fd_set *ws, fd_set *es, const struct timespec *t, const sigset_t *s) { return (((int (*)(int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *)) __libc_interposing[INTERPOS_pselect])(n, rs, ws, es, t, s)); } diff --git a/lib/libc/sys/ptrace.c b/lib/libc/sys/ptrace.c index 4d0d3a4a3f9a..55ad50e025aa 100644 --- a/lib/libc/sys/ptrace.c +++ b/lib/libc/sys/ptrace.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2016 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(_ptrace, ptrace); int _ptrace(int request, pid_t pid, caddr_t addr, int data) { errno = 0; return (__sys_ptrace(request, pid, addr, data)); } diff --git a/lib/libc/sys/read.c b/lib/libc/sys/read.c index ef4eced3ca13..abc37431194d 100644 --- a/lib/libc/sys/read.c +++ b/lib/libc/sys/read.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_read, __read); #pragma weak read ssize_t read(int fd, void *buf, size_t nbytes) { return (((ssize_t (*)(int, void *, size_t)) __libc_interposing[INTERPOS_read])(fd, buf, nbytes)); } diff --git a/lib/libc/sys/readv.c b/lib/libc/sys/readv.c index 4eae423008af..21bfc25c5d84 100644 --- a/lib/libc/sys/readv.c +++ b/lib/libc/sys/readv.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include #include "libc_private.h" __weak_reference(__sys_readv, __readv); #pragma weak readv ssize_t readv(int fd, const struct iovec *iov, int iovcnt) { return (((ssize_t (*)(int, const struct iovec *, int)) __libc_interposing[INTERPOS_readv])(fd, iov, iovcnt)); } diff --git a/lib/libc/sys/recvfrom.c b/lib/libc/sys/recvfrom.c index 00e2eb23d939..5f5f95640932 100644 --- a/lib/libc/sys/recvfrom.c +++ b/lib/libc/sys/recvfrom.c @@ -1,51 +1,50 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_recvfrom, __recvfrom); #pragma weak recvfrom ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr * __restrict from, socklen_t * __restrict fromlen) { return (((ssize_t (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *)) __libc_interposing[INTERPOS_recvfrom])(s, buf, len, flags, from, fromlen)); } diff --git a/lib/libc/sys/recvmsg.c b/lib/libc/sys/recvmsg.c index f205c4834b34..44b38aeab2d4 100644 --- a/lib/libc/sys/recvmsg.c +++ b/lib/libc/sys/recvmsg.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_recvmsg, __recvmsg); #pragma weak recvmsg ssize_t recvmsg(int s, struct msghdr *msg, int flags) { return (((int (*)(int, struct msghdr *, int)) __libc_interposing[INTERPOS_recvmsg])(s, msg, flags)); } diff --git a/lib/libc/sys/select.c b/lib/libc/sys/select.c index 9ad78b0787d3..a43e04bd5009 100644 --- a/lib/libc/sys/select.c +++ b/lib/libc/sys/select.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_select, __select); #pragma weak select int select(int n, fd_set *rs, fd_set *ws, fd_set *es, struct timeval *t) { return (((int (*)(int, fd_set *, fd_set *, fd_set *, struct timeval *)) __libc_interposing[INTERPOS_select])(n, rs, ws, es, t)); } diff --git a/lib/libc/sys/sendmsg.c b/lib/libc/sys/sendmsg.c index 3170f5cbc106..f78fbaa258a5 100644 --- a/lib/libc/sys/sendmsg.c +++ b/lib/libc/sys/sendmsg.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_sendmsg, __sendmsg); #pragma weak sendmsg ssize_t sendmsg(int s, const struct msghdr *msg, int flags) { return (((int (*)(int, const struct msghdr *, int)) __libc_interposing[INTERPOS_sendmsg])(s, msg, flags)); } diff --git a/lib/libc/sys/sendto.c b/lib/libc/sys/sendto.c index 4155f329d03c..d27d8638e750 100644 --- a/lib/libc/sys/sendto.c +++ b/lib/libc/sys/sendto.c @@ -1,51 +1,50 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_sendto, __sendto); #pragma weak sendto ssize_t sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) { return (((ssize_t (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t)) __libc_interposing[INTERPOS_sendto])(s, msg, len, flags, to, tolen)); } diff --git a/lib/libc/sys/setcontext.c b/lib/libc/sys/setcontext.c index 6e04c4782107..ffdd7ebbf890 100644 --- a/lib/libc/sys/setcontext.c +++ b/lib/libc/sys/setcontext.c @@ -1,50 +1,49 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_setcontext, __setcontext); __sym_compat(setcontext, __impl_setcontext, FBSD_1.0); __weak_reference(setcontext, __impl_setcontext); __sym_default(setcontext, setcontext, FBSD_1.2); #pragma weak setcontext int setcontext(const ucontext_t *uc) { return (((int (*)(const ucontext_t *)) __libc_interposing[INTERPOS_setcontext])(uc)); } diff --git a/lib/libc/sys/sigaction.c b/lib/libc/sys/sigaction.c index 16d4c286e39b..7352f0a84989 100644 --- a/lib/libc/sys/sigaction.c +++ b/lib/libc/sys/sigaction.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_sigaction, __sigaction); __weak_reference(sigaction, __libc_sigaction); #pragma weak sigaction int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { return (((int (*)(int, const struct sigaction *, struct sigaction *)) __libc_interposing[INTERPOS_sigaction])(sig, act, oact)); } diff --git a/lib/libc/sys/sigprocmask.c b/lib/libc/sys/sigprocmask.c index 866d3dcdcd76..c807d42fb2de 100644 --- a/lib/libc/sys/sigprocmask.c +++ b/lib/libc/sys/sigprocmask.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_sigprocmask, __sigprocmask); __weak_reference(sigprocmask, __libc_sigprocmask); #pragma weak sigprocmask int sigprocmask(int how, const sigset_t *set, sigset_t *oset) { return (((int (*)(int, const sigset_t *, sigset_t *)) __libc_interposing[INTERPOS_sigprocmask])(how, set, oset)); } diff --git a/lib/libc/sys/sigsuspend.c b/lib/libc/sys/sigsuspend.c index 3eb664f37037..46d5dc0edf49 100644 --- a/lib/libc/sys/sigsuspend.c +++ b/lib/libc/sys/sigsuspend.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_sigsuspend, __sigsuspend); __weak_reference(sigsuspend, __libc_sigsuspend); #pragma weak sigsuspend int sigsuspend(const sigset_t *set) { return (((int (*)(const sigset_t *)) __libc_interposing[INTERPOS_sigsuspend])(set)); } diff --git a/lib/libc/sys/sigtimedwait.c b/lib/libc/sys/sigtimedwait.c index 3ef107784a2e..898f723987e2 100644 --- a/lib/libc/sys/sigtimedwait.c +++ b/lib/libc/sys/sigtimedwait.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_sigtimedwait, __sigtimedwait); #pragma weak sigtimedwait int sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info, const struct timespec * __restrict t) { return (((int (*)(const sigset_t *, siginfo_t *, const struct timespec *)) __libc_interposing[INTERPOS_sigtimedwait])(set, info, t)); } diff --git a/lib/libc/sys/sigwaitinfo.c b/lib/libc/sys/sigwaitinfo.c index 39254839666c..4caa52f3398d 100644 --- a/lib/libc/sys/sigwaitinfo.c +++ b/lib/libc/sys/sigwaitinfo.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_sigwaitinfo, __sigwaitinfo); #pragma weak sigwaitinfo int sigwaitinfo(const sigset_t * __restrict set, siginfo_t * __restrict info) { return (((int (*)(const sigset_t *, siginfo_t *)) __libc_interposing[INTERPOS_sigwaitinfo])(set, info)); } diff --git a/lib/libc/sys/thr_exit.2 b/lib/libc/sys/thr_exit.2 index 54426d605ad8..62d6e6da22ce 100644 --- a/lib/libc/sys/thr_exit.2 +++ b/lib/libc/sys/thr_exit.2 @@ -1,93 +1,92 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_EXIT 2 .Os .Sh NAME .Nm thr_exit .Nd terminate current thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft void .Fn thr_exit "long *state" .Sh DESCRIPTION .Bf -symbolic This function is intended for implementing threading. Normal applications should call .Xr pthread_exit 3 instead. .Ef .Pp The .Fn thr_exit system call terminates the current kernel-scheduled thread. .Pp If the .Fa state argument is not .Dv NULL , the location pointed to by the argument is updated with an arbitrary non-zero value, and an .Xr _umtx_op 2 .Dv UMTX_OP_WAKE operation is consequently performed on the location. .Pp Attempts to terminate the last thread in the process are silently ignored. Use .Xr _exit 2 syscall to terminate the process. .Sh RETURN VALUES The function does not return a value. A return from the function indicates that the calling thread was the last one in the process. .Sh SEE ALSO .Xr _exit 2 , .Xr _umtx_op 2 , .Xr thr_kill 2 , .Xr thr_kill2 2 , .Xr thr_new 2 , .Xr thr_self 2 , .Xr thr_set_name 2 , .Xr pthread_exit 3 .Sh STANDARDS The .Fn thr_exit system call is non-standard and is used by .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh HISTORY The .Fn thr_exit system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_kill.2 b/lib/libc/sys/thr_kill.2 index dd43b6c90f90..a18e53e61008 100644 --- a/lib/libc/sys/thr_kill.2 +++ b/lib/libc/sys/thr_kill.2 @@ -1,138 +1,137 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_kill 2 .Os .Sh NAME .Nm thr_kill .Nd send signal to thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_kill "long id" "int sig" .Ft int .Fn thr_kill2 "pid_t pid" "long id" "int sig" .Sh DESCRIPTION The .Fn thr_kill and .Fn thr_kill2 system calls allow sending a signal, specified by the .Fa sig argument, to some threads in a process. For the .Fn thr_kill function, signalled threads are always limited to the current process. For the .Fn thr_kill2 function, the .Fa pid argument specifies the process with threads to be signalled. .Pp The .Fa id argument specifies which threads get the signal. If .Fa id is equal to \-1, all threads in the specified process are signalled. Otherwise, only the thread with the thread identifier equal to the argument is signalled. .Pp The .Fa sig argument defines the delivered signal. It must be a valid signal number or zero. In the latter case no signal is actually sent, and the call is used to verify the liveness of the thread. .Pp The signal is delivered with .Dv siginfo .Dv si_code set to .Dv SI_LWP . .Sh RETURN VALUES If successful, .Fn thr_kill and .Fn thr_kill2 will return zero, otherwise \-1 is returned, and .Va errno is set to indicate the error. .Sh ERRORS The .Fn thr_kill and .Fn thr_kill2 operations return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The .Fa sig argument is not zero and does not specify valid signal. .It Bq Er ESRCH The specified process or thread was not found. .El .Pp Additionally, the .Fn thr_kill2 may return the following errors: .Bl -tag -width Er .It Bq Er EPERM The current process does not have sufficient privilege to check existence or send a signal to the specified process. .El .Sh SEE ALSO .Xr kill 2 , .Xr thr_exit 2 , .Xr thr_new 2 , .Xr thr_self 2 , .Xr thr_set_name 2 , .Xr _umtx_op 2 , .Xr pthread_kill 3 , .Xr signal 3 .Sh STANDARDS The .Fn thr_kill and .Fn thr_kill2 system calls are non-standard and are used by the .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh HISTORY The .Fn thr_kill and .Fn thr_kill2 system calls first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_new.2 b/lib/libc/sys/thr_new.2 index 9576039f79a8..eb57fb67ac2a 100644 --- a/lib/libc/sys/thr_new.2 +++ b/lib/libc/sys/thr_new.2 @@ -1,248 +1,247 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_NEW 2 .Os .Sh NAME .Nm thr_new .Nd create new thread of execution .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_new "struct thr_param *param" "int param_size" .Sh DESCRIPTION .Bf -symbolic This function is intended for implementing threading. Normal applications should call .Xr pthread_create 3 instead. .Ef .Pp The .Fn thr_new system call creates a new kernel-scheduled thread of execution in the context of the current process. The newly created thread shares all attributes of the process with the existing kernel-scheduled threads in the process, but has private processor execution state. The machine context for the new thread is copied from the creating thread's context, including coprocessor state. FPU state and specific machine registers are excluded from the copy. These are set according to ABI requirements and syscall parameters. The FPU state for the new thread is reinitialized to clean. .Pp The .Fa param structure supplies parameters affecting the thread creation. The structure is defined in the .In sys/thr.h header as follows .Bd -literal struct thr_param { void (*start_func)(void *); void *arg; char *stack_base; size_t stack_size; char *tls_base; size_t tls_size; long *child_tid; long *parent_tid; int flags; struct rtprio *rtp; }; .Ed and contains the following fields: .Bl -tag -width ".Va parent_tid" .It Va start_func Pointer to the thread entry function. The kernel arranges for the new thread to start executing the function upon the first return to userspace. .It Va arg Opaque argument supplied to the entry function. .It Va stack_base Stack base address. The stack must be allocated by the caller. On some architectures, the ABI might require that the system put information on the stack to ensure the execution environment for .Va start_func . .It Va stack_size Stack size. .It Va tls_base TLS base address. The value of TLS base is loaded into the ABI-defined machine register in the new thread context. .It Va tls_size TLS size. .It Va child_tid Address to store the new thread identifier, for the child's use. .It Va parent_tid Address to store the new thread identifier, for the parent's use. .Pp Both .Va child_tid and .Va parent_tid are provided, with the intent that .Va child_tid is used by the new thread to get its thread identifier without issuing the .Xr thr_self 2 syscall, while .Va parent_tid is used by the thread creator. The latter is separate from .Va child_tid because the new thread might exit and free its thread data before the parent has a chance to execute far enough to access it. .It Va flags Thread creation flags. The .Va flags member may specify the following flags: .Bl -tag -width ".Dv THR_SYSTEM_SCOPE" .It Dv THR_SUSPENDED Create the new thread in the suspended state. The flag is not currently implemented. .It Dv THR_SYSTEM_SCOPE Create the system scope thread. The flag is not currently implemented. .El .It Va rtp Real-time scheduling priority for the new thread. May be .Dv NULL to inherit the priority from the creating thread. .El .Pp The .Fa param_size argument should be set to the size of the .Fa param structure. .Pp After the first successful creation of an additional thread, the process is marked by the kernel as multi-threaded. In particular, the .Dv P_HADTHREADS flag is set in the process' .Dv p_flag (visible in the .Xr ps 1 output), and several operations are executed in multi-threaded mode. For instance, the .Xr execve 2 system call terminates all threads but the calling one on successful execution. .Sh RETURN VALUES If successful, .Fn thr_new will return zero, otherwise \-1 is returned, and .Va errno is set to indicate the error. .Sh ERRORS The .Fn thr_new operation returns the following errors: .Bl -tag -width Er .\" When changing this list, consider updating share/man/man3/pthread_create.3, .\" since that function can return any of these errors. .It Bq Er EFAULT The memory pointed to by the .Fa param argument is not valid. .It Bq Er EFAULT The memory pointed to by the .Fa param structure .Fa child_tid , parent_tid or .Fa rtp arguments is not valid. .It Bq Er EFAULT The specified stack base is invalid, or the kernel was unable to put required initial data on the stack. .It Bq Er EINVAL The .Fa param_size argument specifies a negative value, or the value is greater than the largest .Fa struct param size the kernel can interpret. .It Bq Er EINVAL The .Fa rtp member is not .Dv NULL and specifies invalid scheduling parameters. .It Bq Er EINVAL The specified TLS base is invalid. .It Bq Er EPERM The caller does not have permission to set the scheduling parameters or scheduling policy. .It Bq Er EPROCLIM Creation of the new thread would exceed the .Dv RACCT_NTHR limit, see .Xr racct 2 . .It Bq Er EPROCLIM Creation of the new thread would exceed the .Dv kern.threads.max_threads_per_proc .Xr sysctl 2 limit. .It Bq Er ENOMEM There was not enough kernel memory to allocate the new thread structures. .El .Sh SEE ALSO .Xr ps 1 , .Xr _umtx_op 2 , .Xr execve 2 , .Xr racct 2 , .Xr thr_exit 2 , .Xr thr_kill 2 , .Xr thr_kill2 2 , .Xr thr_self 2 , .Xr thr_set_name 2 , .Xr pthread_create 3 .Sh STANDARDS The .Fn thr_new system call is non-standard and is used by the .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh HISTORY The .Fn thr_new system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_self.2 b/lib/libc/sys/thr_self.2 index 99b96b64ba9b..0637dca1d7b7 100644 --- a/lib/libc/sys/thr_self.2 +++ b/lib/libc/sys/thr_self.2 @@ -1,93 +1,92 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_SELF 2 .Os .Sh NAME .Nm thr_self .Nd return thread identifier for the calling thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_self "long *id" .Sh DESCRIPTION The .Fn thr_self system call stores the system-wide thread identifier for the current kernel-scheduled thread in the variable pointed by the argument .Va id . .Pp The thread identifier is an integer in the range from .Dv PID_MAX + 2 (100001) to .Dv INT_MAX . The thread identifier is guaranteed to be unique at any given time, for each running thread in the system. After the thread exits, the identifier may be reused. .Sh RETURN VALUES If successful, .Fn thr_self will return zero, otherwise \-1 is returned, and .Va errno is set to indicate the error. .Sh ERRORS The .Fn thr_self operation may return the following errors: .Bl -tag -width Er .It Bq Er EFAULT The memory pointed to by the .Fa id argument is not valid. .El .Sh SEE ALSO .Xr _umtx_op 2 , .Xr thr_exit 2 , .Xr thr_kill 2 , .Xr thr_kill2 2 , .Xr thr_new 2 , .Xr thr_set_name 2 , .Xr pthread_getthreadid_np 3 , .Xr pthread_self 3 .Sh STANDARDS The .Fn thr_self system call is non-standard and is used by .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh HISTORY The .Fn thr_self system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_set_name.2 b/lib/libc/sys/thr_set_name.2 index 0a2c126062d1..f43a60a4b3a5 100644 --- a/lib/libc/sys/thr_set_name.2 +++ b/lib/libc/sys/thr_set_name.2 @@ -1,97 +1,96 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_SET_NAME 2 .Os .Sh NAME .Nm thr_set_name .Nd set user-visible thread name .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_set_name "long id" "const char *name" .Sh DESCRIPTION The .Fn thr_set_name system call sets the user-visible name for the thread with the identifier .Va id in the current process to the NUL-terminated string .Va name . The name will be silently truncated to fit into a buffer of .Dv MAXCOMLEN + 1 bytes. The thread name can be seen in the output of the .Xr ps 1 and .Xr top 1 commands, in the kernel debuggers and kernel tracing facility outputs, and in userland debuggers and program core files, as notes. .Sh RETURN VALUES If successful, .Fn thr_set_name returns zero; otherwise, \-1 is returned, and .Va errno is set to indicate the error. .Sh ERRORS The .Fn thr_set_name system call may return the following errors: .Bl -tag -width Er .It Bq Er EFAULT The memory pointed to by the .Fa name argument is not valid. .It Bq Er ESRCH The thread with the identifier .Fa id does not exist in the current process. .El .Sh SEE ALSO .Xr ps 1 , .Xr _umtx_op 2 , .Xr thr_exit 2 , .Xr thr_kill 2 , .Xr thr_kill2 2 , .Xr thr_new 2 , .Xr thr_self 2 , .Xr pthread_set_name_np 3 , .Xr ddb 4 , .Xr ktr 9 .Sh STANDARDS The .Fn thr_set_name system call is non-standard and is used by the .Lb libthr . .Sh HISTORY The .Fn thr_set_name system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_suspend.2 b/lib/libc/sys/thr_suspend.2 index b1c16811a527..ee4261b3676c 100644 --- a/lib/libc/sys/thr_suspend.2 +++ b/lib/libc/sys/thr_suspend.2 @@ -1,132 +1,131 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_SUSPEND 2 .Os .Sh NAME .Nm thr_suspend .Nd suspend the calling thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_suspend "struct timespec *timeout" .Sh DESCRIPTION .Bf -symbolic This function is intended for implementing threading. Normal applications should use .Xr pthread_cond_timedwait 3 together with .Xr pthread_cond_broadcast 3 for typical safe suspension with cooperation of the thread being suspended, or .Xr pthread_suspend_np 3 and .Xr pthread_resume_np 3 in some specific situations, instead. .Ef .Pp The .Fn thr_suspend system call puts the calling thread in a suspended state, where it is not eligible for CPU time. This state is exited by another thread calling .Xr thr_wake 2 , when the time interval specified by .Fa timeout has elapsed, or by the delivery of a signal to the suspended thread. .Pp If the .Fa timeout argument is .Dv NULL , the suspended state can be only terminated by explicit .Fn thr_wake or signal. .Pp If a wake from .Xr thr_wake 2 was delivered before the .Nm call, the thread is not put into a suspended state. Instead, the call returns immediately without an error. .Pp If a thread previously called .Xr thr_wake 2 with its own thread identifier, which resulted in setting the internal kernel flag to immediately abort interruptible sleeps with an .Er EINTR error .Po see .Xr thr_wake 2 .Pc , the flag is cleared. As with .Xr thr_wake 2 called from another thread, the next .Nm call does not result in suspension. .Sh RETURN VALUES .Rv -std thr_suspend .Sh ERRORS The .Fn thr_suspend operation returns the following errors: .Bl -tag -width Er .It Bq Er EFAULT The memory pointed to by the .Fa timeout argument is not valid. .It Bq Er ETIMEDOUT The specified timeout expired. .It Bq Er ETIMEDOUT The .Fa timeout argument specified a zero time interval. .It Bq Er EINTR The sleep was interrupted by a signal. .El .Sh SEE ALSO .Xr ps 1 , .Xr thr_wake 2 , .Xr pthread_resume_np 3 , .Xr pthread_suspend_np 3 .Sh STANDARDS The .Fn thr_suspend system call is non-standard. .Sh HISTORY The .Fn thr_suspend system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/thr_wake.2 b/lib/libc/sys/thr_wake.2 index c7d32ff95564..0a196c2dd18b 100644 --- a/lib/libc/sys/thr_wake.2 +++ b/lib/libc/sys/thr_wake.2 @@ -1,115 +1,114 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 May 5, 2020 .Dt THR_WAKE 2 .Os .Sh NAME .Nm thr_wake .Nd wake up the suspended thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/thr.h .Ft int .Fn thr_wake "long id" .Sh DESCRIPTION .Bf -symbolic This function is intended for implementing threading. Normal applications should use .Xr pthread_cond_timedwait 3 together with .Xr pthread_cond_broadcast 3 for typical safe suspension with cooperation of the thread being suspended, or .Xr pthread_suspend_np 3 and .Xr pthread_resume_np 3 in some specific situations, instead. .Ef .Pp Passing the thread identifier of the calling thread .Po see .Xr thr_self 2 .Pc to .Fn thr_wake sets a thread's flag to cause the next signal-interruptible sleep of that thread in the kernel to fail immediately with the .Er EINTR error. The flag is cleared by an interruptible sleep attempt or by a call to .Xr thr_suspend 2 . This is used by the system threading library to implement cancellation. .Pp If .Fa id is not equal to the current thread identifier, the specified thread is woken up if suspended by the .Xr thr_suspend 2 system call. If the thread is not suspended at the time of the .Nm call, the wake is remembered and the next attempt of the thread to suspend itself with the .Xr thr_suspend 2 results in immediate return with success. Only one wake is remembered. .Sh RETURN VALUES .Rv -std thr_wake .Sh ERRORS The .Fn thr_wake operation returns these errors: .Bl -tag -width Er .It Bq Er ESRCH The specified thread was not found or does not belong to the process of the calling thread. .El .Sh SEE ALSO .Xr ps 1 , .Xr thr_self 2 , .Xr thr_suspend 2 , .Xr pthread_cancel 3 , .Xr pthread_resume_np 3 , .Xr pthread_suspend_np 3 .Sh STANDARDS The .Fn thr_suspend system call is non-standard and is used by .Lb libthr to implement .St -p1003.1-2001 .Xr pthread 3 functionality. .Sh HISTORY The .Fn thr_suspend system call first appeared in .Fx 5.2 . diff --git a/lib/libc/sys/wait4.c b/lib/libc/sys/wait4.c index 8d243f387b09..9efabec529d7 100644 --- a/lib/libc/sys/wait4.c +++ b/lib/libc/sys/wait4.c @@ -1,47 +1,46 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include "libc_private.h" __weak_reference(__sys_wait4, __wait4); #pragma weak wait4 pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru) { return (((pid_t (*)(pid_t, int *, int, struct rusage *)) __libc_interposing[INTERPOS_wait4])(pid, status, options, ru)); } diff --git a/lib/libc/sys/wait6.c b/lib/libc/sys/wait6.c index 1f19ec4d5bcc..1bba04200e69 100644 --- a/lib/libc/sys/wait6.c +++ b/lib/libc/sys/wait6.c @@ -1,50 +1,49 @@ /* * Copyright (c) 2015 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_wait6, __wait6); #pragma weak wait6 pid_t wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *ru, siginfo_t *infop) { return (((pid_t (*)(idtype_t, id_t, int *, int, struct __wrusage *, siginfo_t *))__libc_interposing[INTERPOS_wait6])(idtype, id, status, options, ru, infop)); } diff --git a/lib/libc/sys/write.c b/lib/libc/sys/write.c index b7014a35c3b9..461975cd72fb 100644 --- a/lib/libc/sys/write.c +++ b/lib/libc/sys/write.c @@ -1,48 +1,47 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include "libc_private.h" __weak_reference(__sys_write, __write); #pragma weak write ssize_t write(int fd, const void *buf, size_t nbytes) { return (((ssize_t (*)(int, const void *, size_t)) __libc_interposing[INTERPOS_write])(fd, buf, nbytes)); } diff --git a/lib/libc/sys/writev.c b/lib/libc/sys/writev.c index fa760e14b6fc..4d91d4dec95a 100644 --- a/lib/libc/sys/writev.c +++ b/lib/libc/sys/writev.c @@ -1,49 +1,48 @@ /* * Copyright (c) 2014 The FreeBSD Foundation. - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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(s), this list of conditions and the following disclaimer as * the first lines of this file unmodified other than the possible * addition of one or more copyright notices. * 2. Redistributions in binary form must reproduce the above copyright * notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 #include #include #include #include #include "libc_private.h" __weak_reference(__sys_writev, __writev); #pragma weak writev ssize_t writev(int fd, const struct iovec *iov, int iovcnt) { return (((ssize_t (*)(int, const struct iovec *, int)) __libc_interposing[INTERPOS_writev])(fd, iov, iovcnt)); } diff --git a/lib/libc/x86/sys/pkru.3 b/lib/libc/x86/sys/pkru.3 index f2c923b508ed..1785f93cf4b6 100644 --- a/lib/libc/x86/sys/pkru.3 +++ b/lib/libc/x86/sys/pkru.3 @@ -1,204 +1,203 @@ .\" Copyright (c) 2019 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 February 16, 2019 .Dt PKRU 3 .Os .Sh NAME .Nm Protection Key Rights for User pages .Nd provide fast user-managed key-based access control for pages .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In machine/sysarch.h .Ft int .Fn x86_pkru_get_perm "unsigned int keyidx" "int *access" "int *modify" .Ft int .Fn x86_pkru_set_perm "unsigned int keyidx" "int access" "int modify" .Ft int .Fo x86_pkru_protect_range .Fa "void *addr" .Fa "unsigned long len" .Fa "unsigned int keyidx" .Fa "int flag" .Fc .Ft int .Fn x86_pkru_unprotect_range "void *addr" "unsigned long len" .Sh DESCRIPTION The protection keys feature provides an additional mechanism, besides the normal page permissions as established by .Xr mmap 2 and .Xr mprotect 2 , to control access to user-mode addresses. The mechanism gives safety measures which can be used to avoid incidental read or modification of sensitive memory, or as a debugging feature. It cannot guard against conscious accesses since permissions are user-controllable. .Pp If supported by hardware, each mapped user linear address has an associated 4-bit protection key. A new per-thread PKRU hardware register determines, for each protection key, whether user-mode addresses with that protection key may be read or written. .Pp Only one key may apply to a given range at a time. The default protection key index is zero, it is used even if no key was explicitly assigned to the address, or if the key was removed. .Pp The protection prevents the system from accessing user addresses as well as the user applications. When a system call was unable to read or write user memory due to key protection, it returns the .Er EFAULT error code. Note that some side effects may have occurred if this error is reported. .Pp Protection keys require that the system uses 4-level paging (also called long mode), which means that it is only available on amd64 system. Both 64-bit and 32-bit applications can use protection keys. More information about the hardware feature is provided in the IA32 Software Developer's Manual published by Intel Corp. .Pp The key indexes written into the page table entries are managed by the .Fn sysarch syscall. Per-key permissions are managed using the user-mode instructions .Em RDPKRU and .Em WRPKRU . The system provides convenient library helpers for both the syscall and the instructions, described below. .Pp The .Fn x86_pkru_protect_range function assigns key .Fa keyidx to the range starting at .Fa addr and having length .Fa len . Starting address is truncated to the page start, and the end is rounded up to the end of the page. After a successfull call, the range has the specified key assigned, even if the key is zero and it did not change the page table entries. .Pp The .Fa flags argument takes the logical OR of the following values: .Bl -tag -width .It Bq Va AMD64_PKRU_EXCL Only assign the key if the range does not have any other keys assigned (including the zero key). You must first remove any existing key with .Fn x86_pkru_unprotect_range in order for this request to succeed. If the .Va AMD64_PKRU_EXCL flag is not specified, .Fn x86_pkru_protect_range replaces any existing key. .It Bq Va AMD64_PKRU_PERSIST The keys assigned to the range are persistent. They are re-established when the current mapping is destroyed and a new mapping is created in any sub-range of the specified range. You must use a .Fn x86_pkru_unprotect_range call to forget the key. .El .Pp The .Fn x86_pkru_unprotect_range function removes any keys assigned to the specified range. Existing mappings are changed to use key index zero in page table entries. Keys are no longer considered installed for all mappings in the range, for the purposes of .Fn x86_pkru_protect_range with the .Va AMD64_PKRU_EXCL flag. .Pp The .Fn x86_pkru_get_perm function returns access rights for the key specified by the .Fa keyidx argument. If the value pointed to by .Fa access is zero after the call, no read or write permissions is granted for mappings which are assigned the key .Fa keyidx . If .Fa access is not zero, read access is permitted. The non-zero value of the variable pointed to by the .Fa modify argument indicates that write access is permitted. .Pp Conversely, the .Fn x86_pkru_set_perm establishes the access and modify permissions for the given key index as specified by its arguments. .Sh RETURN VALUES .Rv -std .Sh ERRORS .Bl -tag -width Er .It Bq Er EOPNOTSUPP The hardware does not support protection keys. .It Bq Er EINVAL The supplied key index is invalid (greater than 15). .It Bq Er EINVAL The supplied .Fa flags argument for .Fn x86_pkru_protect_range has reserved bits set. .It Bq Er EFAULT The supplied address range does not completely fit into the user-managed address range. .It Bq Er ENOMEM The memory shortage prevents the completion of the operation. .It Bq Er EBUSY The .Va AMD64_PKRU_EXCL flag was specified for .Fn x86_pkru_protect_range and the range already has defined protection keys. .El .Sh SEE ALSO .Xr mmap 2 , .Xr mprotect 2 , .Xr munmap 2 , .Xr sysarch 2 . .Sh STANDARDS The .Nm functions are non-standard and first appeared in .Fx 13.0 . diff --git a/lib/libc/x86/sys/pkru.c b/lib/libc/x86/sys/pkru.c index d21c03331ab9..a03becb3e101 100644 --- a/lib/libc/x86/sys/pkru.c +++ b/lib/libc/x86/sys/pkru.c @@ -1,136 +1,135 @@ /*- * Copyright (c) 2019 The FreeBSD Foundation - * All rights reserved. * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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 #include #include #include #include #include #include #include #define MAX_PKRU_IDX 0xf #ifdef __i386__ #define X86_SET_PKRU I386_SET_PKRU #define X86_CLEAR_PKRU I386_CLEAR_PKRU #else #define X86_SET_PKRU AMD64_SET_PKRU #define X86_CLEAR_PKRU AMD64_CLEAR_PKRU #endif static int x86_pkru_get_perm_unsup(u_int keyidx, int *access, int *modify) { errno = EOPNOTSUPP; return (-1); } static int x86_pkru_get_perm_hw(u_int keyidx, int *access, int *modify) { uint32_t pkru; if (keyidx > MAX_PKRU_IDX) { errno = EINVAL; return (-1); } keyidx *= 2; pkru = rdpkru(); *access = (pkru & (1 << keyidx)) == 0; *modify = (pkru & (2 << keyidx)) == 0; return (0); } DEFINE_UIFUNC(, int, x86_pkru_get_perm, (u_int, int *, int *)) { return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ? x86_pkru_get_perm_unsup : x86_pkru_get_perm_hw); } static int x86_pkru_set_perm_unsup(u_int keyidx, int access, int modify) { errno = EOPNOTSUPP; return (-1); } static int x86_pkru_set_perm_hw(u_int keyidx, int access, int modify) { uint32_t pkru; if (keyidx > MAX_PKRU_IDX) { errno = EINVAL; return (-1); } keyidx *= 2; pkru = rdpkru(); pkru &= ~(3 << keyidx); if (!access) pkru |= 1 << keyidx; if (!modify) pkru |= 2 << keyidx; wrpkru(pkru); return (0); } DEFINE_UIFUNC(, int, x86_pkru_set_perm, (u_int, int, int)) { return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ? x86_pkru_set_perm_unsup : x86_pkru_set_perm_hw); } int x86_pkru_protect_range(void *addr, unsigned long len, u_int keyidx, int flags) { struct amd64_set_pkru a64pkru; memset(&a64pkru, 0, sizeof(a64pkru)); a64pkru.addr = addr; a64pkru.len = len; a64pkru.keyidx = keyidx; a64pkru.flags = flags; return (sysarch(X86_SET_PKRU, &a64pkru)); } int x86_pkru_unprotect_range(void *addr, unsigned long len) { struct amd64_set_pkru a64pkru; memset(&a64pkru, 0, sizeof(a64pkru)); a64pkru.addr = addr; a64pkru.len = len; return (sysarch(X86_CLEAR_PKRU, &a64pkru)); } diff --git a/share/man/man3/pthread_mutex_consistent.3 b/share/man/man3/pthread_mutex_consistent.3 index d16f8b86b9b8..ac44a8d99718 100644 --- a/share/man/man3/pthread_mutex_consistent.3 +++ b/share/man/man3/pthread_mutex_consistent.3 @@ -1,92 +1,91 @@ .\" Copyright (c) 2016 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 March 27, 2017 .Dt PTHREAD_MUTEX_CONSISTENT 3 .Os .Sh NAME .Nm pthread_mutex_consistent .Nd mark state protected by robust mutex as consistent .Sh LIBRARY .Lb libpthread .Sh SYNOPSIS .In pthread.h .Ft int .Fn pthread_mutex_consistent "pthread_mutex_t *mutex" .Sh DESCRIPTION If the process containing the thread owning a robust mutex terminates while holding the mutex, the mutex becomes inconsistent and the next thread that acquires the mutex lock is notified of the state by the return value .Er EOWNERDEAD . In this case, the mutex does not become normally usable again until the state is marked consistent. .Pp The .Fn pthread_mutex_consistent , when called with the .Fa mutex argument, which points to the initialized robust mutex in an inconsistent state, marks the by mutex as consistent again. The consequent unlock of the mutex, by either .Fn pthread_mutex_unlock or other methods, allows other contenders to lock the mutex. .Pp If the mutex in the inconsistent state is not marked consistent by the call to .Fn pthread_mutex_consistent before unlock, further attempts to lock the .Fa mutex result in the .Er ENOTRECOVERABLE condition reported by the locking functions. .Sh RETURN VALUES If successful, .Fn pthread_mutex_consistent will return zero, otherwise an error number will be returned to indicate the error. .Sh ERRORS The .Fn pthread_mutex_lock function will fail if: .Bl -tag -width Er .It Bq Er EINVAL The mutex pointed to by the .Fa mutex argument is not robust, or is not in the inconsistent state. .El .Sh SEE ALSO .Xr pthread_mutex_init 3 , .Xr pthread_mutex_lock 3 , .Xr pthread_mutex_unlock 3 , .Xr pthread_mutexattr_setrobust 3 .Sh STANDARDS The .Fn pthread_mutex_lock function conforms to .St -susv4 . diff --git a/share/man/man4/bhnd_chipc.4 b/share/man/man4/bhnd_chipc.4 index 60c7fcce4a98..b4fbeea9d278 100644 --- a/share/man/man4/bhnd_chipc.4 +++ b/share/man/man4/bhnd_chipc.4 @@ -1,79 +1,78 @@ .\" Copyright (c) 2017 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Landon Fuller under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 October 16, 2017 .Dt BHND_CHIPC 4 .Os .Sh NAME .Nm bhnd_chipc .Nd Broadcom Home Networking Division ChipCommon Driver .Sh SYNOPSIS To compile this driver into the kernel, add this line to the kernel configuration file: .Bd -ragged -offset indent .Cd "device bhnd" .Ed .Pp To compile driver support for all additional devices found in embedded systems, add the following additional lines to the kernel configuration file: .Bd -ragged -offset indent .Cd "device cfi" .Cd "device gpio" .Cd "device spibus" .Cd "device uart" .Ed .Pp To load the driver as a module at boot, add this line to .Xr loader.conf 5 : .Bd -literal -offset indent bhnd_load="YES" .Ed .Sh DESCRIPTION The .Nm driver supports the ChipCommon core found in Broadcom Home Networking Division network chipsets and embedded systems. .Pp The ChipCommon core provides an interface to common hardware facilities, including device identification, UARTs, CFI and SPI flash, One-time Programmable (OTP) Memory, and GPIO. .Sh SEE ALSO .Xr bhnd 4 , .Xr intro 4 .Sh HISTORY The .Nm device driver first appeared in .Fx 11.0 . .Sh AUTHORS .An -nosplit The .Nm driver was written by .An Landon Fuller Aq Mt landonf@FreeBSD.org , and .An Michael Zhilin Aq Mt mizhka@FreeBSD.org . diff --git a/share/man/man4/bhnd_pmu.4 b/share/man/man4/bhnd_pmu.4 index 9bf3cbcc05ee..6ad913e40527 100644 --- a/share/man/man4/bhnd_pmu.4 +++ b/share/man/man4/bhnd_pmu.4 @@ -1,72 +1,71 @@ .\" Copyright (c) 2017 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by Landon Fuller under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 October 16, 2017 .Dt BHND_PMU 4 .Os .Sh NAME .Nm bhnd_pmu .Nd Broadcom Home Networking Division PMU Driver .Sh SYNOPSIS To compile this driver into the kernel, add this line to the kernel configuration file: .Bd -ragged -offset indent .Cd "device bhnd" .Ed .Pp To load the driver as a module at boot, add this line to .Xr loader.conf 5 : .Bd -literal -offset indent bhnd_load="YES" .Ed .Sh DESCRIPTION The .Nm driver supports the Power Management Unit (PMU) found in Broadcom Home Networking Division network chipsets and embedded systems. .Pp The PMU provides a hardware interface for managing the device's clock and power topology. .Sh SEE ALSO .Xr bhnd 4 , .Xr intro 4 .Sh HISTORY The .Nm device driver first appeared in .Fx 12.0 . .Sh AUTHORS .An -nosplit The .Nm driver was derived from Broadcom's ISC-licensed Linux PMU drivers, and was ported to .Fx and .Xr bhnd 4 by .An Landon Fuller Aq Mt landonf@FreeBSD.org . diff --git a/share/man/man4/cc_chd.4 b/share/man/man4/cc_chd.4 index 616a9e0546f9..82a44dd2169d 100644 --- a/share/man/man4/cc_chd.4 +++ b/share/man/man4/cc_chd.4 @@ -1,128 +1,127 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes under sponsorship from the FreeBSD Foundation. .\" .\" 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 May 13, 2021 .Dt CC_CHD 4 .Os .Sh NAME .Nm cc_chd .Nd CHD Congestion Control Algorithm .Sh DESCRIPTION CHD enhances the HD algorithm implemented in .Xr cc_hd 4 . It provides tolerance to non-congestion related packet loss and improvements to coexistence with traditional loss-based TCP flows, especially when the bottleneck link is lightly multiplexed. .Pp Like HD, the algorithm aims to keep network queuing delays below a particular threshold (queue_threshold) and decides to reduce the congestion window (cwnd) probabilistically based on its estimate of the network queuing delay. .Pp It differs from HD in three key aspects: .Bl -bullet .It The probability of cwnd reduction due to congestion is calculated once per round trip time instead of each time an acknowledgement is received as done by .Xr cc_hd 4 . .It Packet losses that occur while the queuing delay is less than queue_threshold do not cause cwnd to be reduced. .It CHD uses a shadow window to help regain lost transmission opportunities when competing with loss-based TCP flows. .El .Sh MIB Variables The algorithm exposes the following tunable variables in the .Va net.inet.tcp.cc.chd branch of the .Xr sysctl 3 MIB: .Bl -tag -width ".Va queue_threshold" .It Va queue_threshold Queueing congestion threshold (qth) in ticks. Default is 20. .It Va pmax Per RTT maximum backoff probability as a percentage. Default is 50. .It Va qmin Minimum queuing delay threshold (qmin) in ticks. Default is 5. .It Va loss_fair If 1, cwnd is adjusted using the shadow window when a congestion related loss is detected. Default is 1. .It Va use_max If 1, the maximum RTT seen within the measurement period is used as the basic delay measurement for the algorithm, otherwise a sampled RTT measurement is used. Default is 1. .El .Sh SEE ALSO .Xr cc_cdg 4 , .Xr cc_cubic 4 , .Xr cc_dctcp 4 , .Xr cc_hd 4 , .Xr cc_htcp 4 , .Xr cc_newreno 4 , .Xr cc_vegas 4 , .Xr h_ertt 4 , .Xr mod_cc 4 , .Xr tcp 4 , .Xr khelp 9 , .Xr mod_cc 9 .Rs .%A "D. A. Hayes" .%A "G. Armitage" .%T "Improved coexistence and loss tolerance for delay based TCP congestion control" .%J "in 35th Annual IEEE Conference on Local Computer Networks" .%D "October 2010" .%P "24-31" .Re .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm congestion control module first appeared in .Fx 9.0 . .Pp The module was first released in 2010 by David Hayes whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm congestion control module and this manual page were written by .An David Hayes Aq Mt david.hayes@ieee.org . diff --git a/share/man/man4/cc_hd.4 b/share/man/man4/cc_hd.4 index 4c88cc166c54..f401e150315d 100644 --- a/share/man/man4/cc_hd.4 +++ b/share/man/man4/cc_hd.4 @@ -1,120 +1,119 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes under sponsorship from the FreeBSD Foundation. .\" .\" 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 May 13, 2021 .Dt CC_HD 4 .Os .Sh NAME .Nm cc_hd .Nd HD Congestion Control Algorithm .Sh DESCRIPTION The HD congestion control algorithm is an implementation of the Hamilton Institute's delay-based congestion control which aims to keep network queuing delays below a particular threshold (queue_threshold). .Pp HD probabilistically reduces the congestion window (cwnd) based on its estimate of the network queuing delay. The probability of reducing cwnd is zero at hd_qmin or less, rising to a maximum at queue_threshold, and then back to zero at the maximum queuing delay. .Pp Loss-based congestion control algorithms such as NewReno probe for network capacity by filling queues until there is a packet loss. HD competes with loss-based congestion control algorithms by allowing its probability of reducing cwnd to drop from a maximum at queue_threshold to be zero at the maximum queuing delay. This has been shown to work well when the bottleneck link is highly multiplexed. .Sh MIB Variables The algorithm exposes the following tunable variables in the .Va net.inet.tcp.cc.hd branch of the .Xr sysctl 3 MIB: .Bl -tag -width ".Va queue_threshold" .It Va queue_threshold Queueing congestion threshold (qth) in ticks. Default is 20. .It Va pmax Per packet maximum backoff probability as a percentage. Default is 5. .It Va qmin Minimum queuing delay threshold (qmin) in ticks. Default is 5. .El .Sh SEE ALSO .Xr cc_cdg 4 , .Xr cc_chd 4 , .Xr cc_cubic 4 , .Xr cc_dctcp 4 , .Xr cc_htcp 4 , .Xr cc_newreno 4 , .Xr cc_vegas 4 , .Xr h_ertt 4 , .Xr mod_cc 4 , .Xr tcp 4 , .Xr khelp 9 , .Xr mod_cc 9 .Rs .%A "L. Budzisz" .%A "R. Stanojevic" .%A "R. Shorten" .%A "F. Baker" .%T "A strategy for fair coexistence of loss and delay-based congestion control algorithms" .%J "IEEE Commun. Lett." .%D "Jul 2009" .%V "13" .%N "7" .%P "555-557" .Re .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh FUTURE WORK The Hamilton Institute have recently made some improvements to the algorithm implemented by this module and have called it Coexistent-TCP (C-TCP). The improvements should be evaluated and potentially incorporated into this module. .Sh HISTORY The .Nm congestion control module first appeared in .Fx 9.0 . .Pp The module was first released in 2010 by David Hayes whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm congestion control module and this manual page were written by .An David Hayes Aq Mt david.hayes@ieee.org . diff --git a/share/man/man4/cc_vegas.4 b/share/man/man4/cc_vegas.4 index c387e17f0551..ba755dbc62bb 100644 --- a/share/man/man4/cc_vegas.4 +++ b/share/man/man4/cc_vegas.4 @@ -1,136 +1,135 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes under sponsorship from the FreeBSD Foundation. .\" .\" 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 May 13, 2021 .Dt CC_VEGAS 4 .Os .Sh NAME .Nm cc_vegas .Nd Vegas Congestion Control Algorithm .Sh DESCRIPTION The Vegas congestion control algorithm uses what the authors term the actual and expected transmission rates to determine whether there is congestion along the network path i.e. .Bl -item -offset indent .It actual rate = (total data sent in a RTT) / RTT .It expected rate = cwnd / RTTmin .It diff = expected - actual .El .Pp where RTT is the measured instantaneous round trip time and RTTmin is the smallest round trip time observed during the connection. .Pp The algorithm aims to keep diff between two parameters alpha and beta, such that: .Bl -item -offset indent .It alpha < diff < beta .El .Pp If diff > beta, congestion is inferred and cwnd is decremented by one packet (or the maximum TCP segment size). If diff < alpha, then cwnd is incremented by one packet. Alpha and beta govern the amount of buffering along the path. .Pp The implementation was done in a clean-room fashion, and is based on the paper referenced in the .Sx SEE ALSO section below. .Sh IMPLEMENTATION NOTES The time from the transmission of a marked packet until the receipt of an acknowledgement for that packet is measured once per RTT. This implementation does not implement Brakmo's and Peterson's original duplicate ACK policy since clock ticks in today's machines are not as coarse as they were (i.e. 500ms) when Vegas was originally designed. Note that modern TCP recovery processes such as fast retransmit and SACK are enabled by default in the TCP stack. .Sh MIB Variables The algorithm exposes the following tunable variables in the .Va net.inet.tcp.cc.vegas branch of the .Xr sysctl 3 MIB: .Bl -tag -width ".Va alpha" .It Va alpha Query or set the Vegas alpha parameter as a number of buffers on the path. When setting alpha, the value must satisfy: 0 < alpha < beta. Default is 1. .It Va beta Query or set the Vegas beta parameter as a number of buffers on the path. When setting beta, the value must satisfy: 0 < alpha < beta. Default is 3. .El .Sh SEE ALSO .Xr cc_cdg 4 , .Xr cc_chd 4 , .Xr cc_cubic 4 , .Xr cc_dctcp 4 , .Xr cc_hd 4 , .Xr cc_htcp 4 , .Xr cc_newreno 4 , .Xr h_ertt 4 , .Xr mod_cc 4 , .Xr tcp 4 , .Xr khelp 9 , .Xr mod_cc 9 .Rs .%A "L. S. Brakmo" .%A "L. L. Peterson" .%T "TCP Vegas: end to end congestion avoidance on a global internet" .%J "IEEE J. Sel. Areas Commun." .%D "October 1995" .%V "13" .%N "8" .%P "1465-1480" .Re .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm congestion control module first appeared in .Fx 9.0 . .Pp The module was first released in 2010 by David Hayes whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm congestion control module and this manual page were written by .An David Hayes Aq Mt david.hayes@ieee.org . diff --git a/share/man/man4/fdt.4 b/share/man/man4/fdt.4 index fb381e0753c6..2ac570a5223c 100644 --- a/share/man/man4/fdt.4 +++ b/share/man/man4/fdt.4 @@ -1,204 +1,203 @@ .\" .\" Copyright (c) 2010 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This software was developed by Semihalf under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 March 28, 2019 .Dt FDT 4 .Os .Sh NAME .Nm fdt .Nd Flattened Device Tree support .Sh SYNOPSIS .Cd "options FDT" .Cd "makeoptions FDT_DTS_FILE=.dts" .Cd "options FDT_DTB_STATIC" .Sh DESCRIPTION .Em Flattened Device Tree is a mechanism for describing computer hardware resources, which cannot be probed or self enumerated, in a uniform and portable way. The primary consumers of this technology are .Em embedded systems, where a lot of designs are based on similar chips, but have different assignment of pins, memory layout, addresses bindings, interrupts routing and other resources. .Pp Configuration data, which cannot be self discovered in run-time, has to be supplied from external source. The concept of a flattened device tree is a platform and architecture independent approach for resolving such problems. The idea is inherited from Open Firmware IEEE 1275 device-tree notion, and has been successfully adopted by the embedded industry. The scheme works in the following way: .Bl -bullet .It Hardware platform resources are .Em manually described in a human readable text source format, where all non self-enumerating information is gathered. .It This source description is converted .Em (compiled) into a binary object i.e. a flattened device tree .Em blob which is passed to the kernel at boot time. .It The kernel (driver) learns about hardware resources details and dependencies from this [externally supplied] blob, which eliminates the need for embedding any information about the underlying platform hardware resources in the kernel. .It The flattened device tree mechanism in principle does not depend on any particular first-stage bootloader or firmware features. The only overall requirement for the environment is to provide a complete device tree description to the kernel. .El .Pp The .Nm layer allows any platform code in the kernel to retrieve information about hardware resources from a unified origin, which brings advantages to the embedded applications (eliminates hard-coded configuration approach, enforces code to be data driven and extensible) leading to easier porting and maintenance. .Sh DEFINITIONS .Bl -tag -width Ar .It Va Device tree source (DTS) The device tree source is a text file which describes hardware resources of a computer system in a human-readable form, with certain hierarchical structure (a tree). The default location for DTS files in the .Fx source repository is .Pa sys/dts directory. .It Va Device tree blob (DTB) The textual device tree description (DTS file) is first converted (compiled) into a binary object (the device tree blob) i.e. the DTB, which is handed over to the final consumer (typically kernel) for parsing and processing of its contents. .It Va Device tree compiler (DTC) A utility program executed on the host, which transforms (compiles) a textual description of a device tree (DTS) into a binary object (DTB). .It Va Device tree bindings While the device tree textual description and the binary object are media to convey the hardware configuration information, an actual meaning and interpretation of the contents are defined by the device tree .Pa bindings . They are certain conventions describing definitions (encoding) of particular nodes in a device tree and their properties, allowed values, ranges and so on. Such reference conventions were provided by the legacy Open Firmware bindings, further supplemented by the ePAPR specification. .El .Sh "BUILDING THE WORLD" In order for the system to support .Nm it is required that .Fx world be built with the .Pa WITH_FDT build knob supplied either via .Xr src.conf 5 or command line defined with -D. .Pp This creates the user space .Pa dtc compiler and enables .Nm support in .Xr loader 8 . .Sh "BUILDING KERNEL" There is a couple of options for managing .Nm support at the .Fx kernel level. .Bl -tag -width Ar .It Va makeoptions DTS+=.dts Specifies device tree source (DTS) files for a given kernel. The indicated DTS files will be converted (compiled) into a binary form along with building the kernel itself. Any DTS file names not written as an absolute path must be specified relative to the default location of DTS sources i.e., .Pa sys/dts . .It Va makeoptions DTSO+=.dtso Specifies device tree source overlay (DTSO) files for a given kernel. Overlay files will be built with the kernel as with the makeoption .Va DTS described above. Overlay files specified as relative paths will be relative to the default location of DTS overlays for the platform being built i.e., .Pa sys/dts/arm/overlays . .It Va options FDT The primary option for enabling .Nm support in the kernel. It covers all low-level and infrastructure parts of .Nm kernel support, which primarily are the .Xr fdtbus 4 and .Xr simplebus 4 drivers, as well as helper routines and libraries. .It Va makeoptions FDT_DTS_FILE=.dts Specifies a preferred (default) device tree source (DTS) file for a given kernel. It will be built along with the kernel as if it were supplied via the makeoption .Va DTS described above. This makeoption is not mandatory unless FDT_DTB_STATIC is also defined (see below). .It Va options FDT_DTB_STATIC Typically, the device tree blob (DTB) is a stand-alone file, physically separate from the kernel, but this option lets statically embed a DTB file into a kernel image. Note that when this is specified the FDT_DTS_FILE makeoption becomes mandatory (as there needs to be a DTS file specified in order to embed it into the kernel image). .El .Sh SEE ALSO .Xr fdtbus 4 , .Xr openfirm 4 , .Xr simplebus 4 .Sh STANDARDS IEEE Std 1275: IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices .Pq Vt Open Firmware . .Pp Power.org Standard for Embedded Power Architecture Platform Requirements .Pq Vt ePAPR . .Sh HISTORY The .Nm support first appeared in .Fx 9.0 . .Sh AUTHORS The .Nm support was developed by Semihalf under sponsorship from the FreeBSD Foundation. This manual page was written by .An Rafal Jaworowski . diff --git a/share/man/man4/fdtbus.4 b/share/man/man4/fdtbus.4 index 128a86f82c03..7fb13b01b3b9 100644 --- a/share/man/man4/fdtbus.4 +++ b/share/man/man4/fdtbus.4 @@ -1,88 +1,87 @@ .\" .\" Copyright (c) 2010 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This software was developed by Semihalf under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 July 12, 2010 .Dt FDTBUS 4 .Os .Sh NAME .Nm fdtbus .Nd Flattened Device Tree bus driver .Sh SYNOPSIS .Cd "options FDT" .Sh DESCRIPTION The .Nm abstract bus driver is the primary connection and translation layer between .Xr fdt 4 hardware resources description and .Fx native newbus device drivers framework. For an embedded system .Nm represents peripherals typically found on a highly integrated chip (system-on-chip). .Pp The .Nm driver provides generic, common infrastructure for all .Xr fdt 4 oriented device drivers, and its main responsibilities are the following: .Bl -bullet .It Creating newbus children that reflect .Xr fdt 4 nodes in the flattened device tree. .It Managing SYS_RES_IRQ resources. .It Managing SYS_RES_MEMORY, SYS_RES_IOPORT resources. .El .Sh SEE ALSO .Xr fdt 4 , .Xr openfirm 4 , .Xr simplebus 4 .Sh STANDARDS IEEE Std 1275: IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices .Pq Vt Open Firmware . .Pp Power.org Standard for Embedded Power Architecture Platform Requirements .Pq Vt ePAPR . .Sh HISTORY The .Nm support first appeared in .Fx 9.0 . .Sh AUTHORS The .Nm support was developed by Semihalf under sponsorship from the FreeBSD Foundation. This manual page was written by .An Rafal Jaworowski . diff --git a/share/man/man4/h_ertt.4 b/share/man/man4/h_ertt.4 index edc6ac80eb0b..86ff2285c214 100644 --- a/share/man/man4/h_ertt.4 +++ b/share/man/man4/h_ertt.4 @@ -1,141 +1,140 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes under sponsorship from the FreeBSD Foundation. .\" .\" 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 January 18, 2012 .Dt H_ERTT 4 .Os .Sh NAME .Nm h_ertt .Nd Enhanced Round Trip Time Khelp module .Sh SYNOPSIS .In netinet/khelp/h_ertt.h .Sh DESCRIPTION The .Nm Khelp module works within the .Xr khelp 9 framework to provide TCP with a per-connection, low noise estimate of the instantaneous RTT. The implementation attempts to be robust in the face of delayed acknowledgements, TCP Segmentation Offload (TSO), receivers who manipulate TCP timestamps and lack of the TCP timestamp option altogether. .Pp TCP receivers using delayed acknowledgements either acknowledge every second packet (reflecting the time stamp of the first) or use a timeout to trigger the acknowledgement if no second packet arrives. If the heuristic used by .Nm determines that the receiver is using delayed acknowledgements, it measures the RTT using the second packet (the one that triggers the acknowledgement). It does not measure the RTT if the acknowledgement is for the first packet, since it cannot be accurately determined. .Pp When TSO is in use, .Nm will momentarily disable TSO whilst marking a packet to use for a new measurement. The process has negligible impact on the connection. .Pp .Nm associates the following struct with each connection's TCP control block: .Bd -literal struct ertt { TAILQ_HEAD(txseginfo_head, txseginfo) txsegi_q; /* Private. */ long bytes_tx_in_rtt; /* Private. */ long bytes_tx_in_marked_rtt; unsigned long marked_snd_cwnd; int rtt; int maxrtt; int minrtt; int dlyack_rx; /* Private. */ int timestamp_errors; /* Private. */ int markedpkt_rtt; /* Private. */ uint32_t flags; }; .Ed .Pp The fields marked as private should not be manipulated by any code outside of the .Nm implementation. The non-private fields provide the following data: .Bl -tag -width ".Va bytes_tx_in_marked_rtt" -offset indent .It Va bytes_tx_in_marked_rtt The number of bytes transmitted in the .Va markedpkt_rtt . .It Va marked_snd_cwnd The value of cwnd for the marked rtt measurement. .It Va rtt The most recent RTT measurement. .It Va maxrtt The longest RTT measurement that has been taken. .It Va minrtt The shortest RTT measurement that has been taken. .It Va flags The ERTT_NEW_MEASUREMENT flag will be set by the implementation when a new measurement is available. It is the responsibility of .Nm consumers to unset the flag if they wish to use it as a notification method for new measurements. .El .Sh SEE ALSO .Xr cc_chd 4 , .Xr cc_hd 4 , .Xr cc_vegas 4 , .Xr mod_cc 4 , .Xr hhook 9 , .Xr khelp 9 .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm module first appeared in .Fx 9.0 . .Pp The module was first released in 2010 by David Hayes whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm Khelp module and this manual page were written by .An David Hayes Aq Mt david.hayes@ieee.org . .Sh BUGS The module maintains enhanced RTT estimates for all new TCP connections created after the time at which the module was loaded. It might be beneficial to see if it is possible to have the module only affect connections which actually care about ERTT estimates. diff --git a/share/man/man4/man4.aarch64/armv8crypto.4 b/share/man/man4/man4.aarch64/armv8crypto.4 index 3ffc7b330754..7b8704395daf 100644 --- a/share/man/man4/man4.aarch64/armv8crypto.4 +++ b/share/man/man4/man4.aarch64/armv8crypto.4 @@ -1,82 +1,81 @@ .\" Copyright (c) 2016 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This software was developed by Andrew Turner under .\" sponsorship from the FreeBSD Foundation. .\" .\" 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 July 29, 2020 .Dt ARMV8CRYPTO 4 .Os .Sh NAME .Nm armv8crypto .Nd "driver for the AES accelerator on ARM CPUs" .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your kernel configuration file: .Bd -ragged -offset indent .Cd "device crypto" .Cd "device armv8crypto" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent armv8crypto_load="YES" .Ed .Sh DESCRIPTION Starting with the ARMv8 architecture ARM Limited has added optional cryptography instructions to accelerate AES, SHA-1, SHA-2, and finite field arithmetic. .Pp The processor capability is reported as AES in the Instruction Set Attributes 0 line at boot. The .Nm driver does not attach on systems that lack the required CPU capability. .Pp The .Nm driver registers itself to accelerate AES operations for .Xr crypto 4 . .Sh SEE ALSO .Xr crypt 3 , .Xr crypto 4 , .Xr intro 4 , .Xr ipsec 4 , .Xr random 4 , .Xr crypto 7 , .Xr crypto 9 .Sh HISTORY The .Nm driver first appeared in .Fx 11.0 . .Sh AUTHORS .An -nosplit The .Nm driver was written by .An Andrew Turner Aq Mt andrew@FreeBSD.org . diff --git a/share/man/man4/mod_cc.4 b/share/man/man4/mod_cc.4 index 8fec348a092c..f899c2daa8d2 100644 --- a/share/man/man4/mod_cc.4 +++ b/share/man/man4/mod_cc.4 @@ -1,136 +1,135 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD .\" Foundation. .\" .\" 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 August 6, 2019 .Dt MOD_CC 4 .Os .Sh NAME .Nm mod_cc .Nd Modular congestion control .Sh DESCRIPTION The modular congestion control framework allows the TCP implementation to dynamically change the congestion control algorithm used by new and existing connections. Algorithms are identified by a unique .Xr ascii 7 name. Algorithm modules can be compiled into the kernel or loaded as kernel modules using the .Xr kld 4 facility. .Pp The default algorithm is NewReno, and all connections use the default unless explicitly overridden using the .Dv TCP_CONGESTION socket option (see .Xr tcp 4 for details). The default can be changed using a .Xr sysctl 3 MIB variable detailed in the .Sx MIB Variables section below. .Pp Algorithm specific parameters can be set or queried using the .Dv TCP_CCALGOOPT socket option (see .Xr tcp 4 for details). Callers must pass a pointer to an algorithm specific data, and specify its size. .Sh MIB Variables The framework exposes the following variables in the .Va net.inet.tcp.cc branch of the .Xr sysctl 3 MIB: .Bl -tag -width ".Va abe_frlossreduce" .It Va available Read-only list of currently available congestion control algorithms by name. .It Va algorithm Returns the current default congestion control algorithm when read, and changes the default when set. When attempting to change the default algorithm, this variable should be set to one of the names listed by the .Va net.inet.tcp.cc.available MIB variable. .It Va abe Enable support for RFC 8511, which alters the window decrease factor applied to the congestion window in response to an ECN congestion signal. Refer to individual congestion control man pages to determine if they implement support for ABE and for configuration details. .It Va abe_frlossreduce If non-zero, apply standard beta instead of ABE-beta during ECN-signalled congestion recovery episodes if loss also needs to be repaired. .El .Sh SEE ALSO .Xr cc_cdg 4 , .Xr cc_chd 4 , .Xr cc_cubic 4 , .Xr cc_dctcp 4 , .Xr cc_hd 4 , .Xr cc_htcp 4 , .Xr cc_newreno 4 , .Xr cc_vegas 4 , .Xr tcp 4 , .Xr mod_cc 9 .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm modular congestion control framework first appeared in .Fx 9.0 . .Pp The framework was first released in 2007 by James Healy and Lawrence Stewart whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia, which was made possible in part by a grant from the Cisco University Research Program Fund at Community Foundation Silicon Valley. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm facility was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org , .An James Healy Aq Mt jimmy@deefa.com and .An David Hayes Aq Mt david.hayes@ieee.org . .Pp This manual page was written by .An David Hayes Aq Mt david.hayes@ieee.org and .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . diff --git a/share/man/man4/siftr.4 b/share/man/man4/siftr.4 index d5250ef55cc2..e99c4b12d19f 100644 --- a/share/man/man4/siftr.4 +++ b/share/man/man4/siftr.4 @@ -1,792 +1,791 @@ .\" .\" Copyright (c) 2010 The FreeBSD Foundation -.\" All rights reserved. .\" .\" Portions of this software were developed at the Centre for Advanced .\" Internet Architectures, Swinburne University of Technology, Melbourne, .\" Australia by Lawrence Stewart under sponsorship from the FreeBSD .\" Foundation. .\" .\" 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, .\" without modification, immediately at the beginning of the file. .\" 2. 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 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 October 7, 2019 .Dt SIFTR 4 .Os .Sh NAME .Nm SIFTR .Nd Statistical Information For TCP Research .Sh SYNOPSIS To load the driver as a module at run-time, run the following command as root: .Bd -literal -offset indent kldload siftr .Ed .Pp Alternatively, to load the driver as a module at boot time, add the following line into the .Xr loader.conf 5 file: .Bd -literal -offset indent siftr_load="YES" .Ed .Sh DESCRIPTION The .Nm .Po .Em S Ns tatistical .Em I Ns nformation .Em F Ns or .Em T Ns CP .Em R Ns esearch .Pc kernel module logs a range of statistics on active TCP connections to a log file. It provides the ability to make highly granular measurements of TCP connection state, aimed at system administrators, developers and researchers. .Ss Compile-time Configuration The default operation of .Nm is to capture IPv4 TCP/IP packets. .Nm can be configured to support IPv4 and IPv6 by uncommenting: .Bd -literal -offset indent CFLAGS+=-DSIFTR_IPV6 .Ed .Pp in .Aq sys/modules/siftr/Makefile and recompiling. .Pp In the IPv4-only (default) mode, standard dotted decimal notation (e.g. "136.186.229.95") is used to format IPv4 addresses for logging. In IPv6 mode, standard dotted decimal notation is used to format IPv4 addresses, and standard colon-separated hex notation (see RFC 4291) is used to format IPv6 addresses for logging. Note that SIFTR uses uncompressed notation to format IPv6 addresses. For example, the address "fe80::20f:feff:fea2:531b" would be logged as "fe80:0:0:0:20f:feff:fea2:531b". .Ss Run-time Configuration .Nm utilises the .Xr sysctl 8 interface to export its configuration variables to user-space. The following variables are available: .Bl -tag -offset indent -width Va .It Va net.inet.siftr.enabled controls whether the module performs its measurements or not. By default, the value is set to 0, which means the module will not be taking any measurements. Having the module loaded with .Va net.inet.siftr.enabled set to 0 will have no impact on the performance of the network stack, as the packet filtering hooks are only inserted when .Va net.inet.siftr.enabled is set to 1. .El .Bl -tag -offset indent -width Va .It Va net.inet.siftr.ppl controls how many inbound/outbound packets for a given TCP connection will cause a log message to be generated for the connection. By default, the value is set to 1, which means the module will log a message for every packet of every TCP connection. The value can be set to any integer in the range [1,2^32], and can be changed at any time, even while the module is enabled. .El .Bl -tag -offset indent -width Va .It Va net.inet.siftr.logfile controls the path to the file that the module writes its log messages to. By default, the file /var/log/siftr.log is used. The path can be changed at any time, even while the module is enabled. .El .Bl -tag -offset indent -width Va .It Va net.inet.siftr.genhashes controls whether a hash is generated for each TCP packet seen by .Nm . By default, the value is set to 0, which means no hashes are generated. The hashes are useful to correlate which TCP packet triggered the generation of a particular log message, but calculating them adds additional computational overhead into the fast path. .El .Bl -tag -offset indent -width Va .It Va net.inet.siftr.port_filter controls on which source or destination port siftr should capture .Nm . By default, the value is set to 0, which means all ports are eligible for logging. Set to any other value, only packets where either the source or destination port is equal to this number are logged. .El .Ss Log Format A typical .Nm log file will contain 3 different types of log message. All messages are written in plain ASCII text. .Pp Note: The .Qq \e present in the example log messages in this section indicates a line continuation and is not part of the actual log message. .Pp The first type of log message is written to the file when the module is enabled and starts collecting data from the running kernel. The text below shows an example module enable log. The fields are tab delimited key-value pairs which describe some basic information about the system. .Bd -literal -offset indent enable_time_secs=1238556193 enable_time_usecs=462104 \\ siftrver=1.2.2 hz=1000 tcp_rtt_scale=32 \\ sysname=FreeBSD sysver=604000 ipmode=4 .Ed .Pp Field descriptions are as follows: .Bl -tag -offset indent -width Va .It Va enable_time_secs time at which the module was enabled, in seconds since the UNIX epoch. .El .Bl -tag -offset indent -width Va .It Va enable_time_usecs time at which the module was enabled, in microseconds since enable_time_secs. .El .Bl -tag -offset indent -width Va .It Va siftrver version of .Nm . .El .Bl -tag -offset indent -width Va .It Va hz tick rate of the kernel in ticks per second. .El .Bl -tag -offset indent -width Va .It Va tcp_rtt_scale smoothed RTT estimate scaling factor. .El .Bl -tag -offset indent -width Va .It Va sysname operating system name. .El .Bl -tag -offset indent -width Va .It Va sysver operating system version. .El .Bl -tag -offset indent -width Va .It Va ipmode IP mode as defined at compile time. An ipmode of "4" means IPv6 is not supported and IP addresses are logged in regular dotted quad format. An ipmode of "6" means IPv6 is supported, and IP addresses are logged in dotted quad or hex format, as described in the .Qq Compile-time Configuration subsection. .El .Pp The second type of log message is written to the file when a data log message is generated. The text below shows an example data log triggered by an IPv4 TCP/IP packet. The data is CSV formatted. .Bd -literal -offset indent o,0xbec491a5,1238556193.463551,172.16.7.28,22,172.16.2.5,55931, \\ 1073725440,172312,6144,66560,66608,8,1,4,1448,936,1,996,255, \\ 33304,208,66608,0,208,0 .Ed .Pp Field descriptions are as follows: .Bl -tag -offset indent -width Va .It Va 1 Direction of packet that triggered the log message. Either .Qq i for in, or .Qq o for out. .El .Bl -tag -offset indent -width Va .It Va 2 Hash of the packet that triggered the log message. .El .Bl -tag -offset indent -width Va .It Va 3 Time at which the packet that triggered the log message was processed by the .Xr pfil 9 hook function, in seconds and microseconds since the UNIX epoch. .El .Bl -tag -offset indent -width Va .It Va 4 The IPv4 or IPv6 address of the local host, in dotted quad (IPv4 packet) or colon-separated hex (IPv6 packet) notation. .El .Bl -tag -offset indent -width Va .It Va 5 The TCP port that the local host is communicating via. .El .Bl -tag -offset indent -width Va .It Va 6 The IPv4 or IPv6 address of the foreign host, in dotted quad (IPv4 packet) or colon-separated hex (IPv6 packet) notation. .El .Bl -tag -offset indent -width Va .It Va 7 The TCP port that the foreign host is communicating via. .El .Bl -tag -offset indent -width Va .It Va 8 The slow start threshold for the flow, in bytes. .El .Bl -tag -offset indent -width Va .It Va 9 The current congestion window for the flow, in bytes. .El .Bl -tag -offset indent -width Va .It Va 10 The current bandwidth-controlled window for the flow, in bytes. .El .Bl -tag -offset indent -width Va .It Va 11 The current sending window for the flow, in bytes. The post scaled value is reported, except during the initial handshake (first few packets), during which time the unscaled value is reported. .El .Bl -tag -offset indent -width Va .It Va 12 The current receive window for the flow, in bytes. The post scaled value is always reported. .El .Bl -tag -offset indent -width Va .It Va 13 The current window scaling factor for the sending window. .El .Bl -tag -offset indent -width Va .It Va 14 The current window scaling factor for the receiving window. .El .Bl -tag -offset indent -width Va .It Va 15 The current state of the TCP finite state machine, as defined in .Aq Pa netinet/tcp_fsm.h . .El .Bl -tag -offset indent -width Va .It Va 16 The maximum segment size for the flow, in bytes. .El .Bl -tag -offset indent -width Va .It Va 17 The current smoothed RTT estimate for the flow, in units of TCP_RTT_SCALE * HZ, where TCP_RTT_SCALE is a define found in tcp_var.h, and HZ is the kernel's tick timer. Divide by TCP_RTT_SCALE * HZ to get the RTT in secs. TCP_RTT_SCALE and HZ are reported in the enable log message. .El .Bl -tag -offset indent -width Va .It Va 18 SACK enabled indicator. 1 if SACK enabled, 0 otherwise. .El .Bl -tag -offset indent -width Va .It Va 19 The current state of the TCP flags for the flow. See .Aq Pa netinet/tcp_var.h for information about the various flags. .El .Bl -tag -offset indent -width Va .It Va 20 The current retransmission timeout length for the flow, in units of HZ, where HZ is the kernel's tick timer. Divide by HZ to get the timeout length in seconds. HZ is reported in the enable log message. .El .Bl -tag -offset indent -width Va .It Va 21 The current size of the socket send buffer in bytes. .El .Bl -tag -offset indent -width Va .It Va 22 The current number of bytes in the socket send buffer. .El .Bl -tag -offset indent -width Va .It Va 23 The current size of the socket receive buffer in bytes. .El .Bl -tag -offset indent -width Va .It Va 24 The current number of bytes in the socket receive buffer. .El .Bl -tag -offset indent -width Va .It Va 25 The current number of unacknowledged bytes in-flight. Bytes acknowledged via SACK are not excluded from this count. .El .Bl -tag -offset indent -width Va .It Va 26 The current number of segments in the reassembly queue. .El .Bl -tag -offset indent -width Va .It Va 27 Flowid for the connection. A caveat: Zero '0' either represents a valid flowid or a default value when it's not being set. There is no easy way to differentiate without looking at actual network interface card and drivers being used. .El .Bl -tag -offset indent -width Va .It Va 28 Flow type for the connection. Flowtype defines which protocol fields are hashed to produce the flowid. A complete listing is available in .Pa sys/mbuf.h under .Dv M_HASHTYPE_* . .El .Pp The third type of log message is written to the file when the module is disabled and ceases collecting data from the running kernel. The text below shows an example module disable log. The fields are tab delimited key-value pairs which provide statistics about operations since the module was most recently enabled. .Bd -literal -offset indent disable_time_secs=1238556197 disable_time_usecs=933607 \\ num_inbound_tcp_pkts=356 num_outbound_tcp_pkts=627 \\ total_tcp_pkts=983 num_inbound_skipped_pkts_malloc=0 \\ num_outbound_skipped_pkts_malloc=0 num_inbound_skipped_pkts_mtx=0 \\ num_outbound_skipped_pkts_mtx=0 num_inbound_skipped_pkts_tcb=0 \\ num_outbound_skipped_pkts_tcb=0 num_inbound_skipped_pkts_icb=0 \\ num_outbound_skipped_pkts_icb=0 total_skipped_tcp_pkts=0 \\ flow_list=172.16.7.28;22-172.16.2.5;55931, .Ed .Pp Field descriptions are as follows: .Bl -tag -offset indent -width Va .It Va disable_time_secs Time at which the module was disabled, in seconds since the UNIX epoch. .El .Bl -tag -offset indent -width Va .It Va disable_time_usecs Time at which the module was disabled, in microseconds since disable_time_secs. .El .Bl -tag -offset indent -width Va .It Va num_inbound_tcp_pkts Number of TCP packets that traversed up the network stack. This only includes inbound TCP packets during the periods when .Nm was enabled. .El .Bl -tag -offset indent -width Va .It Va num_outbound_tcp_pkts Number of TCP packets that traversed down the network stack. This only includes outbound TCP packets during the periods when .Nm was enabled. .El .Bl -tag -offset indent -width Va .It Va total_tcp_pkts The summation of num_inbound_tcp_pkts and num_outbound_tcp_pkts. .El .Bl -tag -offset indent -width Va .It Va num_inbound_skipped_pkts_malloc Number of inbound packets that were not processed because of failed .Fn malloc calls. .El .Bl -tag -offset indent -width Va .It Va num_outbound_skipped_pkts_malloc Number of outbound packets that were not processed because of failed .Fn malloc calls. .El .Bl -tag -offset indent -width Va .It Va num_inbound_skipped_pkts_mtx Number of inbound packets that were not processed because of failure to add the packet to the packet processing queue. .El .Bl -tag -offset indent -width Va .It Va num_outbound_skipped_pkts_mtx Number of outbound packets that were not processed because of failure to add the packet to the packet processing queue. .El .Bl -tag -offset indent -width Va .It Va num_inbound_skipped_pkts_tcb Number of inbound packets that were not processed because of failure to find the TCP control block associated with the packet. .El .Bl -tag -offset indent -width Va .It Va num_outbound_skipped_pkts_tcb Number of outbound packets that were not processed because of failure to find the TCP control block associated with the packet. .El .Bl -tag -offset indent -width Va .It Va num_inbound_skipped_pkts_icb Number of inbound packets that were not processed because of failure to find the IP control block associated with the packet. .El .Bl -tag -offset indent -width Va .It Va num_outbound_skipped_pkts_icb Number of outbound packets that were not processed because of failure to find the IP control block associated with the packet. .El .Bl -tag -offset indent -width Va .It Va total_skipped_tcp_pkts The summation of all skipped packet counters. .El .Bl -tag -offset indent -width Va .It Va flow_list A CSV list of TCP flows that triggered data log messages to be generated since the module was loaded. Each flow entry in the CSV list is formatted as .Qq local_ip;local_port-foreign_ip;foreign_port . If there are no entries in the list (i.e., no data log messages were generated), the value will be blank. If there is at least one entry in the list, a trailing comma will always be present. .El .Pp The total number of data log messages found in the log file for a module enable/disable cycle should equate to total_tcp_pkts - total_skipped_tcp_pkts. .Sh IMPLEMENTATION NOTES .Nm hooks into the network stack using the .Xr pfil 9 interface. In its current incarnation, it hooks into the AF_INET/AF_INET6 (IPv4/IPv6) .Xr pfil 9 filtering points, which means it sees packets at the IP layer of the network stack. This means that TCP packets inbound to the stack are intercepted before they have been processed by the TCP layer. Packets outbound from the stack are intercepted after they have been processed by the TCP layer. .Pp The diagram below illustrates how .Nm inserts itself into the stack. .Bd -literal -offset indent ---------------------------------- Upper Layers ---------------------------------- ^ | | | | | | v TCP in TCP out ---------------------------------- ^ | |________ _________| | | | v --------- | SIFTR | --------- ^ | ________| |__________ | | | v IPv{4/6} in IPv{4/6} out ---------------------------------- ^ | | | | v Layer 2 in Layer 2 out ---------------------------------- Physical Layer ---------------------------------- .Ed .Pp .Nm uses the .Xr alq 9 interface to manage writing data to disk. .Pp At first glance, you might mistakenly think that .Nm extracts information from individual TCP packets. This is not the case. .Nm uses TCP packet events (inbound and outbound) for each TCP flow originating from the system to trigger a dump of the state of the TCP control block for that flow. With the PPL set to 1, we are in effect sampling each TCP flow's control block state as frequently as flow packets enter/leave the system. For example, setting PPL to 2 halves the sampling rate i.e., every second flow packet (inbound OR outbound) causes a dump of the control block state. .Pp The distinction between interrogating individual packets versus interrogating the control block is important, because .Nm does not remove the need for packet capturing tools like .Xr tcpdump 1 . .Nm allows you to correlate and observe the cause-and-affect relationship between what you see on the wire (captured using a tool like .Xr tcpdump 1 Ns ) and changes in the TCP control block corresponding to the flow of interest. It is therefore useful to use .Nm and a tool like .Xr tcpdump 1 to gather the necessary data to piece together the complete picture. Use of either tool on its own will not be able to provide all of the necessary data. .Pp As a result of needing to interrogate the TCP control block, certain packets during the lifecycle of a connection are unable to trigger a .Nm log message. The initial handshake takes place without the existence of a control block and the final ACK is exchanged when the connection is in the TIMEWAIT state. .Pp .Nm was designed to minimise the delay introduced to packets traversing the network stack. This design called for a highly optimised and minimal hook function that extracted the minimal details necessary whilst holding the packet up, and passing these details to another thread for actual processing and logging. .Pp This multithreaded design does introduce some contention issues when accessing the data structure shared between the threads of operation. When the hook function tries to place details in the structure, it must first acquire an exclusive lock. Likewise, when the processing thread tries to read details from the structure, it must also acquire an exclusive lock to do so. If one thread holds the lock, the other must wait before it can obtain it. This does introduce some additional bounded delay into the kernel's packet processing code path. .Pp In some cases (e.g., low memory, connection termination), TCP packets that enter the .Nm .Xr pfil 9 hook function will not trigger a log message to be generated. .Nm refers to this outcome as a .Qq skipped packet . Note that .Nm always ensures that packets are allowed to continue through the stack, even if they could not successfully trigger a data log message. .Nm will therefore not introduce any packet loss for TCP/IP packets traversing the network stack. .Ss Important Behaviours The behaviour of a log file path change whilst the module is enabled is as follows: .Bl -enum .It Attempt to open the new file path for writing. If this fails, the path change will fail and the existing path will continue to be used. .It Assuming the new path is valid and opened successfully: .Bl -dash .It Flush all pending log messages to the old file path. .It Close the old file path. .It Switch the active log file pointer to point at the new file path. .It Commence logging to the new file. .El .El .Pp During the time between the flush of pending log messages to the old file and commencing logging to the new file, new log messages will still be generated and buffered. As soon as the new file path is ready for writing, the accumulated log messages will be written out to the file. .Sh EXAMPLES To enable the module's operations, run the following command as root: sysctl net.inet.siftr.enabled=1 .Pp To change the granularity of log messages such that 1 log message is generated for every 10 TCP packets per connection, run the following command as root: sysctl net.inet.siftr.ppl=10 .Pp To change the log file location to /tmp/siftr.log, run the following command as root: sysctl net.inet.siftr.logfile=/tmp/siftr.log .Sh SEE ALSO .Xr tcpdump 1 , .Xr tcp 4 , .Xr sysctl 8 , .Xr alq 9 , .Xr pfil 9 .Sh ACKNOWLEDGEMENTS Development of this software was made possible in part by grants from the Cisco University Research Program Fund at Community Foundation Silicon Valley, and the FreeBSD Foundation. .Sh HISTORY .Nm first appeared in .Fx 7.4 and .Fx 8.2 . .Pp .Nm was first released in 2007 by Lawrence Stewart and James Healy whilst working on the NewTCP research project at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia, which was made possible in part by a grant from the Cisco University Research Program Fund at Community Foundation Silicon Valley. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Pp Work on .Nm v1.2.x was sponsored by the FreeBSD Foundation as part of the .Qq Enhancing the FreeBSD TCP Implementation project 2008-2009. More details are available at: .Pp http://www.freebsdfoundation.org/ .Pp http://caia.swin.edu.au/freebsd/etcp09/ .Sh AUTHORS .An -nosplit .Nm was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org and .An James Healy Aq Mt jimmy@deefa.com . .Pp This manual page was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . .Sh BUGS Current known limitations and any relevant workarounds are outlined below: .Bl -dash .It The internal queue used to pass information between the threads of operation is currently unbounded. This allows .Nm to cope with bursty network traffic, but sustained high packet-per-second traffic can cause exhaustion of kernel memory if the processing thread cannot keep up with the packet rate. .It If using .Nm on a machine that is also running other modules utilising the .Xr pfil 9 framework e.g. .Xr dummynet 4 , .Xr ipfw 8 , .Xr pf 4 Ns , the order in which you load the modules is important. You should kldload the other modules first, as this will ensure TCP packets undergo any necessary manipulations before .Nm .Qq sees and processes them. .It There is a known, harmless lock order reversal warning between the .Xr pfil 9 mutex and tcbinfo TCP lock reported by .Xr witness 4 when .Nm is enabled in a kernel compiled with .Xr witness 4 support. .It There is no way to filter which TCP flows you wish to capture data for. Post processing is required to separate out data belonging to particular flows of interest. .It The module does not detect deletion of the log file path. New log messages will simply be lost if the log file being used by .Nm is deleted whilst the module is set to use the file. Switching to a new log file using the .Em net.inet.siftr.logfile variable will create the new file and allow log messages to begin being written to disk again. The new log file path must differ from the path to the deleted file. .It The hash table used within the code is sized to hold 65536 flows. This is not a hard limit, because chaining is used to handle collisions within the hash table structure. However, we suspect (based on analogies with other hash table performance data) that the hash table look up performance (and therefore the module's packet processing performance) will degrade in an exponential manner as the number of unique flows handled in a module enable/disable cycle approaches and surpasses 65536. .It There is no garbage collection performed on the flow hash table. The only way currently to flush it is to disable .Nm . .It The PPL variable applies to packets that make it into the processing thread, not total packets received in the hook function. Packets are skipped before the PPL variable is applied, which means there may be a slight discrepancy in the triggering of log messages. For example, if PPL was set to 10, and the 8th packet since the last log message is skipped, the 11th packet will actually trigger the log message to be generated. This is discussed in greater depth in CAIA technical report 070824A. .It At the time of writing, there was no simple way to hook into the TCP layer to intercept packets. .Nm Ap s use of IP layer hook points means all IP traffic will be processed by the .Nm .Xr pfil 9 hook function, which introduces minor, but nonetheless unnecessary packet delay and processing overhead on the system for non-TCP packets as well. Hooking in at the IP layer is also not ideal from the data gathering point of view. Packets traversing up the stack will be intercepted and cause a log message generation BEFORE they have been processed by the TCP layer, which means we cannot observe the cause-and-affect relationship between inbound events and the corresponding TCP control block as precisely as could be. Ideally, .Nm should intercept packets after they have been processed by the TCP layer i.e. intercept packets coming up the stack after they have been processed by .Fn tcp_input , and intercept packets coming down the stack after they have been processed by .Fn tcp_output . The current code still gives satisfactory granularity though, as inbound events tend to trigger outbound events, allowing the cause-and-effect to be observed indirectly by capturing the state on outbound events as well. .It The .Qq inflight bytes value logged by .Nm does not take into account bytes that have been .No SACK Ap ed by the receiving host. .It Packet hash generation does not currently work for IPv6 based TCP packets. .It Compressed notation is not used for IPv6 address representation. This consumes more bytes than is necessary in log output. .El diff --git a/share/man/man4/simplebus.4 b/share/man/man4/simplebus.4 index 219837a29664..78cb8d77f61b 100644 --- a/share/man/man4/simplebus.4 +++ b/share/man/man4/simplebus.4 @@ -1,82 +1,81 @@ .\" .\" Copyright (c) 2010 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This software was developed by Semihalf under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 July 12, 2010 .Dt SIMPLEBUS 4 .Os .Sh NAME .Nm simplebus .Nd ePAPR simple-bus driver .Sh SYNOPSIS .Cd "options FDT" .Sh DESCRIPTION This bus driver is dedicated for the .Pa simple-bus node of a flattened device tree compliant with the .Pa ePAPR specification. .Pp The .Nm entity does not represent any physical element by itself, it is rather an umbrella node grouping integrated on-chip peripherals like interrupt controller, connectivity controllers, accelerating engines and so on. .Pp The driver is generic and common for all flattened device tree nodes claiming .Pa simple-bus compatibility. It iterates over direct descendants of the .Pa simple-bus node, instantiates newbus children and assigns resources to them, based on the configuration data retrieved from the nodes properties in .Xr fdt 4 . .Pp Note the .Nm does not manage device resources and passes through any requests to the .Xr fdtbus 4 layer. .Sh SEE ALSO .Xr fdt 4 , .Xr fdtbus 4 , .Xr openfirm 4 .Sh STANDARDS Power.org Standard for Embedded Power Architecture Platform Requirements .Pq Vt ePAPR . .Sh HISTORY The .Nm support first appeared in .Fx 9.0 . .Sh AUTHORS The .Nm support was developed by Semihalf under sponsorship from the FreeBSD Foundation. This manual page was written by .An Rafal Jaworowski . diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7 index 6d505e83daf0..b70f5f395de6 100644 --- a/share/man/man7/arch.7 +++ b/share/man/man7/arch.7 @@ -1,493 +1,493 @@ -.\" Copyright (c) 2016-2017 The FreeBSD Foundation. All rights reserved. +.\" Copyright (c) 2016-2017 The FreeBSD Foundation. .\" .\" This documentation was created by Ed Maste under sponsorship of .\" The FreeBSD Foundation. .\" .\" 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 COPYRIGHT HOLDERS ``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 COPYRIGHT HOLDERS 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 25, 2021 .Dt ARCH 7 .Os .Sh NAME .Nm arch .Nd Architecture-specific details .Sh DESCRIPTION Differences between CPU architectures and platforms supported by .Fx . .Ss Introduction This document is a quick reference of key ABI details of .Fx architecture ports. For full details consult the processor-specific ABI supplement documentation. .Pp If not explicitly mentioned, sizes are in bytes. The architecture details in this document apply to .Fx 12.0 and later, unless otherwise noted. .Pp .Fx uses a flat address space. Variables of types .Vt unsigned long , .Vt uintptr_t , and .Vt size_t and pointers all have the same representation. .Pp In order to maximize compatibility with future pointer integrity mechanisms, manipulations of pointers as integers should be performed via .Vt uintptr_t or .Vt intptr_t and no other types. In particular, .Vt long and .Vt ptrdiff_t should be avoided. .Pp On some architectures, e.g., .Dv powerpc and AIM variants of .Dv powerpc64 , the kernel uses a separate address space. On other architectures, kernel and a user mode process share a single address space. The kernel is located at the highest addresses. .Pp On each architecture, the main user mode thread's stack starts near the highest user address and grows down. .Pp .Fx architecture support varies by release. This table shows the first .Fx release to support each architecture, and, for discontinued architectures, the final release. .Bl -column -offset indent "Architecture" "Initial Release" "Final Release" .It Sy Architecture Ta Sy Initial Release Ta Sy Final Release .It aarch64 Ta 11.0 .It alpha Ta 3.2 Ta 6.4 .It amd64 Ta 5.1 .It arm Ta 6.0 Ta 12.x .It armeb Ta 8.0 Ta 11.4 .It armv6 Ta 10.0 .It armv7 Ta 12.0 .It ia64 Ta 5.0 Ta 10.4 .It i386 Ta 1.0 .It mips Ta 8.0 Ta 13.x .It mipsel Ta 9.0 Ta 13.x .It mipselhf Ta 12.0 Ta 13.x .It mipshf Ta 12.0 Ta 13.x .It mipsn32 Ta 9.0 Ta 13.x .It mips64 Ta 9.0 Ta 13.x .It mips64el Ta 9.0 Ta 13.x .It mips64elhf Ta 12.0 Ta 13.x .It mips64hf Ta 12.0 Ta 13.x .It pc98 Ta 2.2 Ta 11.4 .It powerpc Ta 6.0 .It powerpcspe Ta 12.0 .It powerpc64 Ta 6.0 .It powerpc64le Ta 13.0 .It riscv64 Ta 12.0 .It riscv64sf Ta 12.0 .It sparc64 Ta 5.0 Ta 12.x .El .Ss Type sizes All .Fx architectures use some variant of the ELF (see .Xr elf 5 ) .Sy Application Binary Interface (ABI) for the machine processor. All supported ABIs can be divided into two groups: .Bl -tag -width "Dv ILP32" .It Dv ILP32 .Vt int , .Vt long , .Vt void * types machine representations all have 4-byte size. .It Dv LP64 .Vt int type machine representation uses 4 bytes, while .Vt long and .Vt void * are 8 bytes. .El .Pp Some machines support more than one .Fx ABI. Typically these are 64-bit machines, where the .Dq native .Dv LP64 execution environment is accompanied by the .Dq legacy .Dv ILP32 environment, which was the historical 32-bit predecessor for 64-bit evolution. Examples are: .Bl -column -offset indent "powerpc64" "ILP32 counterpart" .It Sy LP64 Ta Sy ILP32 counterpart .It Dv amd64 Ta Dv i386 .It Dv powerpc64 Ta Dv powerpc .It Dv mips64* Ta Dv mips* .It Dv aarch64 Ta Dv armv6/armv7 .El .Pp .Dv aarch64 will support execution of .Dv armv6 or .Dv armv7 binaries if the CPU implements .Dv AArch32 execution state, however .Dv armv5 binaries aren't supported. .Pp On all supported architectures: .Bl -column -offset -indent "long long" "Size" .It Sy Type Ta Sy Size .It short Ta 2 .It int Ta 4 .It long Ta sizeof(void*) .It long long Ta 8 .It float Ta 4 .It double Ta 8 .El .Pp Integers are represented in two's complement. Alignment of integer and pointer types is natural, that is, the address of the variable must be congruent to zero modulo the type size. Most ILP32 ABIs, except .Dv arm , require only 4-byte alignment for 64-bit integers. .Pp Machine-dependent type sizes: .Bl -column -offset indent "Architecture" "void *" "long double" "time_t" .It Sy Architecture Ta Sy void * Ta Sy long double Ta Sy time_t .It aarch64 Ta 8 Ta 16 Ta 8 .It amd64 Ta 8 Ta 16 Ta 8 .It armv6 Ta 4 Ta 8 Ta 8 .It armv7 Ta 4 Ta 8 Ta 8 .It i386 Ta 4 Ta 12 Ta 4 .It mips Ta 4 Ta 8 Ta 8 .It mipsel Ta 4 Ta 8 Ta 8 .It mipselhf Ta 4 Ta 8 Ta 8 .It mipshf Ta 4 Ta 8 Ta 8 .It mipsn32 Ta 4 Ta 8 Ta 8 .It mips64 Ta 8 Ta 8 Ta 8 .It mips64el Ta 8 Ta 8 Ta 8 .It mips64elhf Ta 8 Ta 8 Ta 8 .It mips64hf Ta 8 Ta 8 Ta 8 .It powerpc Ta 4 Ta 8 Ta 8 .It powerpcspe Ta 4 Ta 8 Ta 8 .It powerpc64 Ta 8 Ta 8 Ta 8 .It powerpc64le Ta 8 Ta 8 Ta 8 .It riscv64 Ta 8 Ta 16 Ta 8 .It riscv64sf Ta 8 Ta 16 Ta 8 .El .Pp .Sy time_t is 8 bytes on all supported architectures except i386. .Ss Endianness and Char Signedness .Bl -column -offset indent "Architecture" "Endianness" "char Signedness" .It Sy Architecture Ta Sy Endianness Ta Sy char Signedness .It aarch64 Ta little Ta unsigned .It amd64 Ta little Ta signed .It armv6 Ta little Ta unsigned .It armv7 Ta little Ta unsigned .It i386 Ta little Ta signed .It mips Ta big Ta signed .It mipsel Ta little Ta signed .It mipselhf Ta little Ta signed .It mipshf Ta big Ta signed .It mipsn32 Ta big Ta signed .It mips64 Ta big Ta signed .It mips64el Ta little Ta signed .It mips64elhf Ta little Ta signed .It mips64hf Ta big Ta signed .It powerpc Ta big Ta unsigned .It powerpcspe Ta big Ta unsigned .It powerpc64 Ta big Ta unsigned .It powerpc64le Ta little Ta unsigned .It riscv64 Ta little Ta signed .It riscv64sf Ta little Ta signed .El .Ss Page Size .Bl -column -offset indent "Architecture" "Page Sizes" .It Sy Architecture Ta Sy Page Sizes .It aarch64 Ta 4K, 2M, 1G .It amd64 Ta 4K, 2M, 1G .It armv6 Ta 4K, 1M .It armv7 Ta 4K, 1M .It i386 Ta 4K, 2M (PAE), 4M .It mips Ta 4K .It mipsel Ta 4K .It mipselhf Ta 4K .It mipshf Ta 4K .It mipsn32 Ta 4K .It mips64 Ta 4K .It mips64el Ta 4K .It mips64elhf Ta 4K .It mips64hf Ta 4K .It powerpc Ta 4K .It powerpcspe Ta 4K .It powerpc64 Ta 4K .It powerpc64le Ta 4K .It riscv64 Ta 4K, 2M, 1G .It riscv64sf Ta 4K, 2M, 1G .El .Ss Floating Point .Bl -column -offset indent "Architecture" "float, double" "long double" .It Sy Architecture Ta Sy float, double Ta Sy long double .It aarch64 Ta hard Ta soft, quad precision .It amd64 Ta hard Ta hard, 80 bit .It armv6 Ta hard Ta hard, double precision .It armv7 Ta hard Ta hard, double precision .It i386 Ta hard Ta hard, 80 bit .It mips Ta soft Ta identical to double .It mipsel Ta soft Ta identical to double .It mipselhf Ta hard Ta identical to double .It mipshf Ta hard Ta identical to double .It mipsn32 Ta soft Ta identical to double .It mips64 Ta soft Ta identical to double .It mips64el Ta soft Ta identical to double .It mips64elhf Ta hard Ta identical to double .It mips64hf Ta hard Ta identical to double .It powerpc Ta hard Ta hard, double precision .It powerpcspe Ta hard Ta hard, double precision .It powerpc64 Ta hard Ta hard, double precision .It powerpc64le Ta hard Ta hard, double precision .It riscv64 Ta hard Ta hard, quad precision .It riscv64sf Ta soft Ta soft, quad precision .El .Ss Default Tool Chain .Fx uses .Xr clang 1 as the default compiler on all supported CPU architectures, LLVM's .Xr ld.lld 1 as the default linker, and ELF Tool Chain binary utilities such as .Xr objcopy 1 and .Xr readelf 1 . .Ss MACHINE_ARCH vs MACHINE_CPUARCH vs MACHINE .Dv MACHINE_CPUARCH should be preferred in Makefiles when the generic architecture is being tested. .Dv MACHINE_ARCH should be preferred when there is something specific to a particular type of architecture where there is a choice of many, or could be a choice of many. Use .Dv MACHINE when referring to the kernel, interfaces dependent on a specific type of kernel or similar things like boot sequences. .Bl -column -offset indent "Dv MACHINE" "Dv MACHINE_CPUARCH" "Dv MACHINE_ARCH" .It Dv MACHINE Ta Dv MACHINE_CPUARCH Ta Dv MACHINE_ARCH .It arm64 Ta aarch64 Ta aarch64 .It amd64 Ta amd64 Ta amd64 .It arm Ta arm Ta armv6, armv7 .It i386 Ta i386 Ta i386 .It mips Ta mips Ta mips, mipsel, mips64, mips64el, mipshf, mipselhf, mips64elhf, mipsn32 .It powerpc Ta powerpc Ta powerpc, powerpcspe, powerpc64, powerpc64le .It riscv Ta riscv Ta riscv64, riscv64sf .El .Ss Predefined Macros The compiler provides a number of predefined macros. Some of these provide architecture-specific details and are explained below. Other macros, including those required by the language standard, are not included here. .Pp The full set of predefined macros can be obtained with this command: .Bd -literal -offset indent cc -x c -dM -E /dev/null .Ed .Pp Common type size and endianness macros: .Bl -column -offset indent "BYTE_ORDER" "Meaning" .It Sy Macro Ta Sy Meaning .It Dv __LP64__ Ta 64-bit (8-byte) long and pointer, 32-bit (4-byte) int .It Dv __ILP32__ Ta 32-bit (4-byte) int, long and pointer .It Dv BYTE_ORDER Ta Either Dv BIG_ENDIAN or Dv LITTLE_ENDIAN . .Dv PDP11_ENDIAN is not used on .Fx . .El .Pp Architecture-specific macros: .Bl -column -offset indent "Architecture" "Predefined macros" .It Sy Architecture Ta Sy Predefined macros .It aarch64 Ta Dv __aarch64__ .It amd64 Ta Dv __amd64__ , Dv __x86_64__ .It armv6 Ta Dv __arm__ , Dv __ARM_ARCH >= 6 .It armv7 Ta Dv __arm__ , Dv __ARM_ARCH >= 7 .It i386 Ta Dv __i386__ .It mips Ta Dv __mips__ , Dv __MIPSEB__ , Dv __mips_o32 .It mipsel Ta Dv __mips__ , Dv __mips_o32 .It mipselhf Ta Dv __mips__ , Dv __mips_o32 .It mipshf Ta Dv __mips__ , Dv __MIPSEB__ , Dv __mips_o32 .It mipsn32 Ta Dv __mips__ , Dv __MIPSEB__ , Dv __mips_n32 .It mips64 Ta Dv __mips__ , Dv __MIPSEB__ , Dv __mips_n64 .It mips64el Ta Dv __mips__ , Dv __mips_n64 .It mips64elhf Ta Dv __mips__ , Dv __mips_n64 .It mips64hf Ta Dv __mips__ , Dv __MIPSEB__ , Dv __mips_n64 .It powerpc Ta Dv __powerpc__ .It powerpcspe Ta Dv __powerpc__ , Dv __SPE__ .It powerpc64 Ta Dv __powerpc__ , Dv __powerpc64__ .It powerpc64le Ta Dv __powerpc__ , Dv __powerpc64__ .It riscv64 Ta Dv __riscv , Dv __riscv_xlen == 64 .It riscv64sf Ta Dv __riscv , Dv __riscv_xlen == 64 , Dv __riscv_float_abi_soft .El .Pp Compilers may define additional variants of architecture-specific macros. The macros above are preferred for use in .Fx . .Ss Important Xr make 1 variables Most of the externally settable variables are defined in the .Xr build 7 man page. These variables are not otherwise documented and are used extensively in the build system. .Bl -tag -width "MACHINE_CPUARCH" .It Dv MACHINE Represents the hardware platform. This is the same as the native platform's .Xr uname 1 .Fl m output. It defines both the userland / kernel interface, as well as the bootloader / kernel interface. It should only be used in these contexts. Each CPU architecture may have multiple hardware platforms it supports where .Dv MACHINE differs among them. It is used to collect together all the files from .Xr config 8 to build the kernel. It is often the same as .Dv MACHINE_ARCH just as one CPU architecture can be implemented by many different hardware platforms, one hardware platform may support multiple CPU architecture family members, though with different binaries. For example, .Dv MACHINE of i386 supported the IBM-AT hardware platform while the .Dv MACHINE of pc98 supported the Japanese company NEC's PC-9801 and PC-9821 hardware platforms. Both of these hardware platforms supported only the .Dv MACHINE_ARCH of i386 where they shared a common ABI, except for certain kernel / userland interfaces relating to underlying hardware platform differences in bus architecture, device enumeration and boot interface. Generally, .Dv MACHINE should only be used in src/sys and src/stand or in system imagers or installers. .It Dv MACHINE_ARCH Represents the CPU processor architecture. This is the same as the native platforms .Xr uname 1 .Fl p output. It defines the CPU instruction family supported. It may also encode a variation in the byte ordering of multi-byte integers (endian). It may also encode a variation in the size of the integer or pointer. It may also encode a ISA revision. It may also encode hard versus soft floating point ABI and usage. It may also encode a variant ABI when the other factors do not uniquely define the ABI (e.g., MIPS' n32 ABI). It, along with .Dv MACHINE , defines the ABI used by the system. For example, the MIPS CPU processor family supports 9 different combinations encoding pointer size, endian and hard versus soft float (for 8 combinations) as well as N32 (which only ever had one variation of all these). Generally, the plain CPU name specifies the most common (or at least first) variant of the CPU. This is why mips and mips64 imply 'big endian' while 'armv6' and 'armv7' imply little endian. If we ever were to support the so-called x32 ABI (using 32-bit pointers on the amd64 architecture), it would most likely be encoded as amd64-x32. It is unfortunate that amd64 specifies the 64-bit evolution of the x86 platform (it matches the 'first rule') as everybody else uses x86_64. There is no standard name for the processor: each OS selects its own conventions. .It Dv MACHINE_CPUARCH Represents the source location for a given .Dv MACHINE_ARCH . It is generally the common prefix for all the MACHINE_ARCH that share the same implementation, though 'riscv' breaks this rule. For example, .Dv MACHINE_CPUARCH is defined to be mips for all the flavors of mips that we support since we support them all with a shared set of sources. While amd64 and i386 are closely related, MACHINE_CPUARCH is not x86 for them. The .Fx source base supports amd64 and i386 with two distinct source bases living in subdirectories named amd64 and i386 (though behind the scenes there's some sharing that fits into this framework). .It Dv CPUTYPE Sets the flavor of .Dv MACHINE_ARCH to build. It is used to optimize the build for a specific CPU / core that the binaries run on. Generally, this does not change the ABI, though it can be a fine line between optimization for specific cases. .It Dv TARGET Used to set .Dv MACHINE in the top level Makefile for cross building. Unused outside of that scope. It is not passed down to the rest of the build. Makefiles outside of the top level should not use it at all (though some have their own private copy for hysterical raisons). .It Dv TARGET_ARCH Used to set .Dv MACHINE_ARCH by the top level Makefile for cross building. Like .Dv TARGET , it is unused outside of that scope. .El .Sh SEE ALSO .Xr src.conf 5 , .Xr build 7 .Sh HISTORY An .Nm manual page appeared in .Fx 11.1 . diff --git a/share/man/man7/crypto.7 b/share/man/man7/crypto.7 index 6df73c4f413c..5c00bb4bd1d3 100644 --- a/share/man/man7/crypto.7 +++ b/share/man/man7/crypto.7 @@ -1,178 +1,177 @@ .\" Copyright (c) 2014-2021 The FreeBSD Foundation -.\" All rights reserved. .\" .\" Portions of this documentation were written by John-Mark Gurney .\" under the sponsorship of the FreeBSD Foundation and .\" Rubicon Communications, LLC (Netgate). .\" .\" Portions of this documentation were written by Ararat River .\" Consulting, LLC under sponsorship of the FreeBSD Foundation. .\" .\" 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 October 6, 2021 .Dt CRYPTO 7 .Os .Sh NAME .Nm crypto .Nd OpenCrypto algorithms .Sh DESCRIPTION The in-kernel OpenCrypto framework supports several different encryption and authentication algorithms. This document describes the parameters and requirements of these algorithms. Unless otherwise noted, all sizes listed below are in bytes. .Ss Authenticators Authenticators compute a value (also known as a digest, hash, or tag) over an input of bytes. In-kernel requests can either compute the value for a given input, or verify if a given tag matches the computed tag for a given input. The following authentication algorithms are supported: .Bl -column "CRYPTO_AES_CCM_CBC_MAC" "XXX" "16, 24, 32" "Digest" .It Sy Name Ta Sy Nonce Ta Sy Key Sizes Ta Sy Digest Ta Sy Description .It Dv CRYPTO_AES_CCM_CBC_MAC Ta 12 Ta 16, 24, 32 Ta 16 Ta Authentication-only mode of AES-CCM .It Dv CRYPTO_AES_NIST_GMAC Ta 12 Ta 16, 24, 32 Ta 16 Ta Galois message authentication code .It Dv CRYPTO_BLAKE2B Ta Ta 0, 64 Ta 64 Ta Blake2b .It Dv CRYPTO_BLAKE2S Ta Ta 0, 32 Ta 32 Ta Blake2s .It Dv CRYPTO_NULL_HMAC Ta Ta Ta 12 Ta IPsec NULL HMAC .It Dv CRYPTO_POLY1305 Ta Ta 32 Ta 16 Ta Poly1305 authenticator .It Dv CRYPTO_RIPEMD160 Ta Ta Ta 20 Ta RIPE Message Digest-160 .It Dv CRYPTO_RIPEMD160_HMAC Ta Ta 64 Ta 20 Ta RIPE Message Digest-160 HMAC .It Dv CRYPTO_SHA1 Ta Ta Ta 20 Ta SHA-1 .It Dv CRYPTO_SHA1_HMAC Ta Ta 64 Ta 20 Ta SHA-1 HMAC .It Dv CRYPTO_SHA2_224 Ta Ta Ta 28 Ta SHA-2 224 .It Dv CRYPTO_SHA2_224_HMAC Ta Ta 64 Ta 28 Ta SHA-2 224 HMAC .It Dv CRYPTO_SHA2_256 Ta Ta Ta 32 Ta SHA-2 256 .It Dv CRYPTO_SHA2_256_HMAC Ta Ta 64 Ta 32 Ta SHA-2 256 HMAC .It Dv CRYPTO_SHA2_384 Ta Ta Ta 48 Ta SHA-2 384 .It Dv CRYPTO_SHA2_384_HMAC Ta Ta 128 Ta 48 Ta SHA-2 384 HMAC .It Dv CRYPTO_SHA2_512 Ta Ta Ta 64 Ta SHA-2 512 .It Dv CRYPTO_SHA2_512_HMAC Ta Ta 128 Ta 64 Ta SHA-2 512 HMAC .El .Ss Block Ciphers Block ciphers in OCF can only operate on messages whose length is an exact multiple of the cipher's block size. OCF supports the following block ciphers: .Bl -column "CRYPTO_CAMELLIA_CBC" "IV Size" "Block Size" "16, 24, 32" .It Sy Name Ta Sy IV Size Ta Sy Block Size Ta Sy Key Sizes Ta Sy Description .It Dv CRYPTO_AES_CBC Ta 16 Ta 16 Ta 16, 24, 32 Ta AES-CBC .It Dv CRYPTO_AES_XTS Ta 8 Ta 16 Ta 32, 64 Ta AES-XTS .It Dv CRYPTO_CAMELLIA_CBC Ta 16 Ta 16 Ta 16, 24, 32 Ta Camellia CBC .It Dv CRYPTO_NULL_CBC Ta 0 Ta 4 Ta 0-256 Ta IPsec NULL cipher .El .Pp .Dv CRYPTO_AES_XTS implements XEX Tweakable Block Cipher with Ciphertext Stealing as defined in NIST SP 800-38E. OCF consumers provide the first 8 bytes of the IV. The remaining 8 bytes are defined to be a block counter beginning at 0. .Pp NOTE: The ciphertext stealing part is not implemented in all backends which is why this cipher requires input that is a multiple of the block size. .Ss Stream Ciphers Stream ciphers can operate on messages with arbitrary lengths. OCF supports the following stream ciphers: .Bl -column "CRYPTO_CHACHA20" "IV Size" "16, 24, 32" .It Sy Name Ta Sy IV Size Ta Sy Key Sizes Ta Sy Description .It Dv CRYPTO_AES_ICM Ta 16 Ta 16, 24, 32 Ta AES Counter Mode .It Dv CRYPTO_CHACHA20 Ta 16 Ta 16, 32 Ta ChaCha20 .El .Pp The IV for each request must be provided in .Fa crp_iv via the .Dv CRYPTO_F_IV_SEPARATE flag. .Pp .Dv CRYPTO_AES_ICM uses the entire IV as a 128-bit big endian block counter. The IV sets the initial counter value for a message. If a consumer wishes to use an IV whose value is split into separate nonce and counter fields (e.g., IPsec), the consumer is responsible for splitting requests to handle counter rollover. .Pp .Dv CRYPTO_CHACHA20 accepts a 16 byte IV. The first 8 bytes are used as a nonce. The last 8 bytes are used as a 64-bit little-endian block counter. .Ss Authenticated Encryption with Associated Data Algorithms AEAD algorithms in OCF combine a stream cipher with an authentication algorithm to provide both secrecy and authentication. AEAD algorithms accept additional authentication data (AAD) in addition to the ciphertext or plaintext. AAD is passed to the authentication algorithm as input in a method defined by the specific AEAD algorithm. .Pp AEAD algorithms in OCF accept a nonce that is combined with an algorithm-defined counter to construct the IV for the underlying stream cipher. This nonce must be provided in .Fa crp_iv via the .Dv CRYPTO_F_IV_SEPARATE flag. Some AEAD algorithms support multiple nonce sizes. The first size listed is the default nonce size. .Pp The following AEAD algorithms are supported: .Bl -column "CRYPTO_AES_NIST_GCM_16" "12, 7-13" "16, 24, 32" "Tag" .It Sy Name Ta Sy Nonce Ta Sy Key Sizes Ta Sy Tag Ta Sy Description .It Dv CRYPTO_AES_NIST_GCM_16 Ta 12 Ta 16, 24, 32 Ta 16 Ta AES Galois/Counter Mode .It Dv CRYPTO_AES_CCM_16 Ta 12, 7-13 Ta 16, 24, 32 Ta 16 Ta AES Counter with CBC-MAC .It Dv CRYPTO_CHACHA20_POLY1305 Ta 12, 8 Ta 32 Ta 16 Ta ChaCha20-Poly1305 .El .Sh SEE ALSO .Xr crypto 4 , .Xr crypto 9 .Sh HISTORY The .Nm manual page first appeared in .Fx 10.1 . diff --git a/share/man/man8/uefi.8 b/share/man/man8/uefi.8 index ee0263c89599..b9adc3c766a3 100644 --- a/share/man/man8/uefi.8 +++ b/share/man/man8/uefi.8 @@ -1,132 +1,131 @@ .\" Copyright (c) 2014 The FreeBSD Foundation -.\" 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 AUTHORS 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 AUTHORS 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 August 31, 2023 .Dt UEFI 8 .Os .Sh NAME .Nm UEFI .Nd Unified Extensible Firmware Interface bootstrapping procedures .Sh DESCRIPTION The .Nm Unified Extensible Firmware Interface provides boot- and run-time services to operating systems. .Nm is a replacement for the legacy BIOS on the i386 and amd64 CPU architectures, and is also used on arm, arm64 and ia64. .Pp The UEFI specification is the successor to the Extensible Firmware Interface (EFI) specification. The terms are often used interchangeably. .Pp The .Nm boot process loads system bootstrap code located in an EFI System Partition (ESP). The ESP is a GPT or MBR partition with a specific identifier that contains an .Xr msdosfs 5 FAT file system with a specified file hierarchy. .Bl -column -offset indent "Partition Scheme" "ESP Identifier" .It Sy "Partition Scheme" Ta Sy "ESP Identifier" .It GPT Ta C12A7328-F81F-11D2-BA4B-00A0C93EC93B .It MBR Ta 0xEF .El .Pp The .Nm boot process proceeds as follows: .Bl -enum -offset indent -compact .It .Nm firmware runs at power up and searches for an OS loader in the EFI system partition. The path to the loader may be set by an EFI environment variable. If not set, an architecture-specific default is used. .Bl -column -offset indent "Architecture" "Default Path" .It Sy Architecture Ta Sy Default Path .It amd64 Ta Pa /EFI/BOOT/BOOTX64.EFI .It arm Ta Pa /EFI/BOOT/BOOTARM.EFI .It arm64 Ta Pa /EFI/BOOT/BOOTAA64.EFI .It i386 Ta Pa /EFI/BOOT/BOOTIA32.EFI .It riscv Ta Pa /EFI/BOOT/BOOTRISCV64.EFI .El .Pp The default .Nm boot configuration for .Fx installs .Pa loader.efi in the default path. .It .Pa loader.efi reads boot configuration from .Pa /boot.config or .Pa /boot/config . .It .Pa loader.efi loads and boots the kernel, as described in .Xr loader.efi 8 . .El .Pp The .Xr vt 4 system console is automatically selected when booting via .Nm . .Sh FILES .Bl -tag -width /boot/loader -compact .Nm bootstrap .It Pa /boot/loader.efi Final stage bootstrap .It Pa /boot/kernel/kernel Default kernel .It Pa /boot/kernel.old/kernel Typical non-default kernel (optional) .El .Sh SEE ALSO .Xr vt 4 , .Xr boot.config 5 , .Xr msdosfs 5 , .Xr boot 8 , .Xr efibootmgr 8 , .Xr efidp 8 , .Xr efivar 8 , .Xr gpart 8 , .Xr loader.efi 8 , .Xr uefisign 8 .Sh HISTORY EFI boot support for the ia64 architecture first appeared in .Fx 5.0 . .Nm boot support for amd64 first appeared in .Fx 10.1 ; for arm64 in .Fx 11.0 ; for armv6 and armv7 in .Fx 12.0 ; and for riscv in .Fx 13.0 . diff --git a/share/man/man9/VOP_READ_PGCACHE.9 b/share/man/man9/VOP_READ_PGCACHE.9 index bf22546a4d73..f8f67eb00f13 100644 --- a/share/man/man9/VOP_READ_PGCACHE.9 +++ b/share/man/man9/VOP_READ_PGCACHE.9 @@ -1,132 +1,131 @@ .\" Copyright (c) 2021 The FreeBSD Foundation, Inc. -.\" All rights reserved. .\" .\" This documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 February 28, 2021 .Dt VOP_READ_PGCACHE 9 .Os .Sh NAME .Nm VOP_READ_PGCACHE .Nd read a file, fast .Sh SYNOPSIS .In sys/param.h .In sys/vnode.h .In sys/uio.h .Ft int .Fo VOP_READ_PGCACHE .Fa "struct vnode *vp" .Fa "struct uio *uio" .Fa "int ioflag" .Fa "struct ucred *cred" .Fc .Sh DESCRIPTION This entry point reads the contents of a file. The intent is to provide the data from caches, which do not require expensive operations or any disk IO. For instance, if filesystem uses normal VM page cache and maintains .Dv v_object lifetime, it can use .Xr vn_read_from_obj 9 helper to return data from the resident .Dv vp->v_object pages. .Pp The filesystem indicates support for the .Nm on specific vnode by setting the .Dv VIRF_PGREAD flag in .Dv vp->v_irflag . .Pp The function does not need to satisfy the whole request; it also might choose to not provide any data. In these cases, the .Fa uio must be advanced by the amount of read data, .Nm should return .Er EJUSTRETURN , and VFS would handle the rest of the read operation using the .Xr VOP_READ 9 . .Pp The VFS layer does the same deadlock avoidance for accessing userspace pages from .Nm as for .Xr VOP_READ 9 . .Pp Vnode is not locked on the call entry and should not be locked on return. For a filesystem that requires vnode lock to return any data, it does not make sense to implement .Nm (and set .Dv VIRF_PGREAD flag) since VFS arranges the call to .Xr VOP_READ 9 as needed. .Pp The arguments are: .Bl -tag -width ioflag .It Fa vp The vnode of the file. .It Fa uio The location of the data to be read. .It Fa ioflag Various flags, see .Xr VOP_READ 9 for the list. .It Fa cred The credentials of the caller. .El .Pp .Nm does not handle non-zero .Fa ioflag argument. .Sh LOCKS The file should be referenced on entry on entry and will still be referenced on exit. Rangelock covering the whole read range should be owned around the call. .Sh RETURN VALUES Zero is returned on success, when the whole request is satisfied, and no more data cannot be provided for it by any means. If more data can be returned, but .Nm was unable to provide it, .Er EJUSTRETURN must be returned. The .Dv uio records should be updated according to the partial operation done. .Pp Otherwise an error code is returned, same as from .Xr VOP_READ 9 .Sh SEE ALSO .Xr uiomove 9 , .Xr vnode 9 , .Xr VOP_READ 9 diff --git a/share/man/man9/casuword.9 b/share/man/man9/casuword.9 index 6733313be788..2623bea97a92 100644 --- a/share/man/man9/casuword.9 +++ b/share/man/man9/casuword.9 @@ -1,113 +1,112 @@ .\" Copyright (c) 2014, 2019 The FreeBSD Foundation -.\" All rights reserved. .\" .\" Part of this documentation was written by .\" Konstantin Belousov under sponsorship .\" from the FreeBSD Foundation. .\" .\" 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 AUTHORS 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 AUTHORS 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 19, 2019 .Dt CASU 9 .Os .Sh NAME .Nm casueword , .Nm casueword32 , .Nm casuword , .Nm casuword32 .Nd fetch, compare and store data from user-space .Sh SYNOPSIS .In sys/types.h .In sys/systm.h .Ft int .Fo casueword .Fa "volatile u_long *base" .Fa "u_long oldval" .Fa "u_long *oldvalp" .Fa "u_long newval" .Fc .Ft int .Fo casueword32 .Fa "volatile uint32_t *base" .Fa "uint32_t oldval" .Fa "uint32_t *oldvalp" .Fa "uint32_t newval" .Fc .Ft u_long .Fo casuword .Fa "volatile u_long *base" .Fa "u_long oldval" .Fa "u_long newval" .Fc .Ft uint32_t .Fo casuword32 .Fa "volatile uint32_t *base" .Fa "uint32_t oldval" .Fa "uint32_t newval" .Fc .Sh DESCRIPTION The .Nm functions are designed to perform atomic compare-and-swap operation on the value in the usermode memory of the current process. .Pp The .Nm routines reads the value from user memory with address .Pa base , and compare the value read with .Pa oldval . If the values are equal, .Pa newval is written to the .Pa *base . In case of .Fn casueword32 and .Fn casueword , old value is stored into the (kernel-mode) variable pointed by .Pa *oldvalp . The userspace value must be naturally aligned. .Pp The callers of .Fn casuword and .Fn casuword32 functions cannot distinguish between -1 read from userspace and function failure. .Sh RETURN VALUES The .Fn casuword and .Fn casuword32 functions return the data fetched or -1 on failure. The .Fn casueword and .Fn casueword32 functions return 0 on success, -1 on failure to access memory, and 1 when comparison or store failed. The store can fail on load-linked/store-conditional architectures. .Sh SEE ALSO .Xr atomic 9 , .Xr fetch 9 , .Xr store 9 diff --git a/share/man/man9/hhook.9 b/share/man/man9/hhook.9 index 37efbe36b6cb..592ac7a91414 100644 --- a/share/man/man9/hhook.9 +++ b/share/man/man9/hhook.9 @@ -1,380 +1,379 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD .\" Foundation. .\" .\" 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 June 21, 2013 .Dt HHOOK 9 .Os .Sh NAME .Nm hhook , .Nm hhook_head_register , .Nm hhook_head_deregister , .Nm hhook_head_deregister_lookup , .Nm hhook_run_hooks , .Nm HHOOKS_RUN_IF , .Nm HHOOKS_RUN_LOOKUP_IF .Nd Helper Hook Framework .Sh SYNOPSIS .In sys/hhook.h .Ft typedef int .Fn "\*(lp*hhook_func_t\*(rp" "int32_t hhook_type" "int32_t hhook_id" \ "void *udata" "void *ctx_data" "void *hdata" "struct osd *hosd" .Fn "int hhook_head_register" "int32_t hhook_type" "int32_t hhook_id" \ "struct hhook_head **hhh" "uint32_t flags" .Fn "int hhook_head_deregister" "struct hhook_head *hhh" .Fn "int hhook_head_deregister_lookup" "int32_t hhook_type" "int32_t hhook_id" .Fn "void hhook_run_hooks" "struct hhook_head *hhh" "void *ctx_data" \ "struct osd *hosd" .Fn HHOOKS_RUN_IF "hhh" "ctx_data" "hosd" .Fn HHOOKS_RUN_LOOKUP_IF "hhook_type" "hhook_id" "ctx_data" "hosd" .Sh DESCRIPTION .Nm provides a framework for managing and running arbitrary hook functions at defined hook points within the kernel. The KPI was inspired by .Xr pfil 9 , and in many respects can be thought of as a more generic superset of pfil. .Pp The .Xr khelp 9 and .Nm frameworks are tightly integrated. Khelp is responsible for registering and deregistering Khelp module hook functions with .Nm points. The KPI functions used by .Xr khelp 9 to do this are not documented here as they are not relevant to consumers wishing to instantiate hook points. .Ss Information for Khelp Module Implementors Khelp modules indirectly interact with .Nm by defining appropriate hook functions for insertion into hook points. Hook functions must conform to the .Ft hhook_func_t function pointer declaration outlined in the .Sx SYNOPSIS . .Pp The .Fa hhook_type and .Fa hhook_id arguments identify the hook point which has called into the hook function. These are useful when a single hook function is registered for multiple hook points and wants to know which hook point has called into it. .In sys/hhook.h lists available .Fa hhook_type defines and subsystems which export hook points are responsible for defining the .Fa hhook_id value in appropriate header files. .Pp The .Fa udata argument will be passed to the hook function if it was specified in the .Vt struct hookinfo at hook registration time. .Pp The .Fa ctx_data argument contains context specific data from the hook point call site. The data type passed is subsystem dependent. .Pp The .Fa hdata argument is a pointer to the persistent per-object storage allocated for use by the module if required. The pointer will only ever be NULL if the module did not request per-object storage. .Pp The .Fa hosd argument can be used with the .Xr khelp 9 framework's .Fn khelp_get_osd function to access data belonging to a different Khelp module. .Pp Khelp modules instruct the Khelp framework to register their hook functions with .Nm points by creating a .Vt "struct hookinfo" per hook point, which contains the following members: .Bd -literal -offset indent struct hookinfo { hhook_func_t hook_func; struct helper *hook_helper; void *hook_udata; int32_t hook_id; int32_t hook_type; }; .Ed .Pp Khelp modules are responsible for setting all members of the struct except .Va hook_helper which is handled by the Khelp framework. .Ss Creating and Managing Hook Points Kernel subsystems that wish to provide .Nm points typically need to make four and possibly five key changes to their implementation: .Bl -bullet .It Define a list of .Va hhook_id mappings in an appropriate subsystem header. .It Register each hook point with the .Fn hhook_head_register function during initialisation of the subsystem. .It Select or create a standardised data type to pass to hook functions as contextual data. .It Add a call to .Fn HHOOKS_RUN_IF or .Fn HHOOKS_RUN_IF_LOOKUP at the point in the subsystem's code where the hook point should be executed. .It If the subsystem can be dynamically added/removed at runtime, each hook point registered with the .Fn hhook_head_register function when the subsystem was initialised needs to be deregistered with the .Fn hhook_head_deregister or .Fn hhook_head_deregister_lookup functions when the subsystem is being deinitialised prior to removal. .El .Pp The .Fn hhook_head_register function registers a hook point with the .Nm framework. The .Fa hook_type argument defines the high level type for the hook point. Valid types are defined in .In sys/hhook.h and new types should be added as required. The .Fa hook_id argument specifies a unique, subsystem specific identifier for the hook point. The .Fa hhh argument will, if not NULL, be used to store a reference to the .Vt struct hhook_head created as part of the registration process. Subsystems will generally want to store a local copy of the .Vt struct hhook_head so that they can use the .Fn HHOOKS_RUN_IF macro to instantiate hook points. The HHOOK_WAITOK flag may be passed in via the .Fa flags argument if .Xr malloc 9 is allowed to sleep waiting for memory to become available. If the hook point is within a virtualised subsystem (e.g. the network stack), the HHOOK_HEADISINVNET flag should be passed in via the .Fa flags argument so that the .Vt struct hhook_head created during the registration process will be added to a virtualised list. .Pp The .Fn hhook_head_deregister function deregisters a previously registered hook point from the .Nm framework. The .Fa hhh argument is the pointer to the .Vt struct hhook_head returned by .Fn hhoook_head_register when the hook point was registered. .Pp The .Fn hhook_head_deregister_lookup function can be used instead of .Fn hhook_head_deregister in situations where the caller does not have a cached copy of the .Vt struct hhook_head and wants to deregister a hook point using the appropriate .Fa hook_type and .Fa hook_id identifiers instead. .Pp The .Fn hhook_run_hooks function should normally not be called directly and should instead be called indirectly via the .Fn HHOOKS_RUN_IF macro. However, there may be circumstances where it is preferable to call the function directly, and so it is documented here for completeness. The .Fa hhh argument references the .Nm point to call all registered hook functions for. The .Fa ctx_data argument specifies a pointer to the contextual hook point data to pass into the hook functions. The .Fa hosd argument should be the pointer to the appropriate object's .Vt struct osd if the subsystem provides the ability for Khelp modules to associate per-object data. Subsystems which do not should pass NULL. .Pp The .Fn HHOOKS_RUN_IF macro is the preferred way to implement hook points. It only calls the .Fn hhook_run_hooks function if at least one hook function is registered for the hook point. By checking for registered hook functions, the macro minimises the cost associated with adding hook points to frequently used code paths by reducing to a simple if test in the common case where no hook functions are registered. The arguments are as described for the .Fn hhook_run_hooks function. .Pp The .Fn HHOOKS_RUN_IF_LOOKUP macro performs the same function as the .Fn HHOOKS_RUN_IF macro, but performs an additional step to look up the .Vt struct hhook_head for the specified .Fa hook_type and .Fa hook_id identifiers. It should not be used except in code paths which are infrequently executed because of the reference counting overhead associated with the look up. .Sh IMPLEMENTATION NOTES Each .Vt struct hhook_head protects its internal list of hook functions with a .Xr rmlock 9 . Therefore, anytime .Fn hhook_run_hooks is called directly or indirectly via the .Fn HHOOKS_RUN_IF or .Fn HHOOKS_RUN_IF_LOOKUP macros, a non-sleepable read lock will be acquired and held across the calls to all registered hook functions. .Sh RETURN VALUES .Fn hhook_head_register returns 0 if no errors occurred. It returns EEXIST if a hook point with the same .Fa hook_type and .Fa hook_id is already registered. It returns EINVAL if the HHOOK_HEADISINVNET flag is not set in .Fa flags because the implementation does not yet support hook points in non-virtualised subsystems (see the .Sx BUGS section for details). It returns ENOMEM if .Xr malloc 9 failed to allocate memory for the new .Vt struct hhook_head . .Pp .Fn hhook_head_deregister and .Fn hhook_head_deregister_lookup return 0 if no errors occurred. They return ENOENT if .Fa hhh is NULL. They return EBUSY if the reference count of .Fa hhh is greater than one. .Sh EXAMPLES A well commented example Khelp module can be found at: .Pa /usr/share/examples/kld/khelp/h_example.c .Pp The .Xr tcp 4 implementation provides two .Nm points which are called for packets sent/received when a connection is in the established phase. Search for HHOOK in the following files: .Pa sys/netinet/tcp_var.h , .Pa sys/netinet/tcp_input.c , .Pa sys/netinet/tcp_output.c and .Pa sys/netinet/tcp_subr.c . .Sh SEE ALSO .Xr khelp 9 .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm framework first appeared in .Fx 9.0 . .Pp The .Nm framework was first released in 2010 by Lawrence Stewart whilst studying at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm framework was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . .Pp This manual page was written by .An David Hayes Aq Mt david.hayes@ieee.org and .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . diff --git a/share/man/man9/khelp.9 b/share/man/man9/khelp.9 index 8d649ae83989..39515eef237c 100644 --- a/share/man/man9/khelp.9 +++ b/share/man/man9/khelp.9 @@ -1,436 +1,435 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD .\" Foundation. .\" .\" 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 February 15, 2011 .Dt KHELP 9 .Os .Sh NAME .Nm khelp , .Nm khelp_init_osd , .Nm khelp_destroy_osd , .Nm khelp_get_id , .Nm khelp_get_osd , .Nm khelp_add_hhook , .Nm khelp_remove_hhook , .Nm KHELP_DECLARE_MOD , .Nm KHELP_DECLARE_MOD_UMA .Nd Kernel Helper Framework .Sh SYNOPSIS .In sys/khelp.h .In sys/module_khelp.h .Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd" .Fn "int khelp_destroy_osd" "struct osd *hosd" .Fn "int32_t khelp_get_id" "char *hname" .Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id" .Fn "int khelp_add_hhook" "struct hookinfo *hki" "uint32_t flags" .Fn "int khelp_remove_hhook" "struct hookinfo *hki" .Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version" .Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor" .Sh DESCRIPTION .Nm provides a framework for managing .Nm modules, which indirectly use the .Xr hhook 9 KPI to register their hook functions with hook points of interest within the kernel. Khelp modules aim to provide a structured way to dynamically extend the kernel at runtime in an ABI preserving manner. Depending on the subsystem providing hook points, a .Nm module may be able to associate per-object data for maintaining relevant state between hook calls. The .Xr hhook 9 and .Nm frameworks are tightly integrated and anyone interested in .Nm should also read the .Xr hhook 9 manual page thoroughly. .Ss Information for Khelp Module Implementors .Nm modules are represented within the .Nm framework by a .Vt struct helper which has the following members: .Bd -literal -offset indent struct helper { int (*mod_init) (void); int (*mod_destroy) (void); #define HELPER_NAME_MAXLEN 16 char h_name[HELPER_NAME_MAXLEN]; uma_zone_t h_zone; struct hookinfo *h_hooks; uint32_t h_nhooks; uint32_t h_classes; int32_t h_id; volatile uint32_t h_refcount; uint16_t h_flags; TAILQ_ENTRY(helper) h_next; }; .Ed .Pp Modules must instantiate a .Vt struct helper , but are only required to set the .Va h_classes field, and may optionally set the .Va h_flags , .Va mod_init and .Va mod_destroy fields where required. The framework takes care of all other fields and modules should refrain from manipulating them. Using the C99 designated initialiser feature to set fields is encouraged. .Pp If specified, the .Va mod_init function will be run by the .Nm framework prior to completing the registration process. Returning a non-zero value from the .Va mod_init function will abort the registration process and fail to load the module. If specified, the .Va mod_destroy function will be run by the .Nm framework during the deregistration process, after the module has been deregistered by the .Nm framework. The return value is currently ignored. Valid .Nm classes are defined in .In sys/khelp.h . Valid flags are defined in .In sys/module_khelp.h . The HELPER_NEEDS_OSD flag should be set in the .Va h_flags field if the .Nm module requires persistent per-object data storage. There is no programmatic way (yet) to check if a .Nm class provides the ability for .Nm modules to associate persistent per-object data, so a manual check is required. .Pp The .Fn KHELP_DECLARE_MOD and .Fn KHELP_DECLARE_MOD_UMA macros provide convenient wrappers around the .Xr DECLARE_MODULE 9 macro, and are used to register a .Nm module with the .Nm framework. .Fn KHELP_DECLARE_MOD_UMA should only be used by modules which require the use of persistent per-object storage i.e. modules which set the HELPER_NEEDS_OSD flag in their .Vt struct helper Ns 's .Va h_flags field. .Pp The first four arguments common to both macros are as follows. The .Fa hname argument specifies the unique .Xr ascii 7 name for the .Nm module. It should be no longer than HELPER_NAME_MAXLEN-1 characters in length. The .Fa hdata argument is a pointer to the module's .Vt struct helper . The .Fa hhooks argument points to a static array of .Vt struct hookinfo structures. The array should contain a .Vt struct hookinfo for each .Xr hhook 9 point the module wishes to hook, even when using the same hook function multiple times for different .Xr hhook 9 points. The .Fa version argument specifies a version number for the module which will be passed to .Xr MODULE_VERSION 9 . The .Fn KHELP_DECLARE_MOD_UMA macro takes the additional .Fa ctor and .Fa dtor arguments, which specify optional .Xr uma 9 constructor and destructor functions. NULL should be passed where the functionality is not required. .Pp The .Fn khelp_get_id function returns the numeric identifier for the .Nm module with name .Fa hname . .Pp The .Fn khelp_get_osd function is used to obtain the per-object data pointer for a specified .Nm module. The .Fa hosd argument is a pointer to the underlying subsystem object's .Vt struct osd . This is provided by the .Xr hhook 9 framework when calling into a .Nm module's hook function. The .Fa id argument specifies the numeric identifier for the .Nm module to extract the data pointer from .Fa hosd for. The .Fa id is obtained using the .Fn khelp_get_id function. .Pp The .Fn khelp_add_hhook and .Fn khelp_remove_hhook functions allow a .Nm module to dynamically hook/unhook .Xr hhook 9 points at run time. The .Fa hki argument specifies a pointer to a .Vt struct hookinfo which encapsulates the required information about the .Xr hhook 9 point and hook function being manipulated. The HHOOK_WAITOK flag may be passed in via the .Fa flags argument of .Fn khelp_add_hhook if .Xr malloc 9 is allowed to sleep waiting for memory to become available. .Ss Integrating Khelp Into a Kernel Subsystem Most of the work required to allow .Nm modules to do useful things relates to defining and instantiating suitable .Xr hhook 9 points for .Nm modules to hook into. The only additional decision a subsystem needs to make is whether it wants to allow .Nm modules to associate persistent per-object data. Providing support for persistent data storage can allow .Nm modules to perform more complex functionality which may be desirable. Subsystems which want to allow Khelp modules to associate persistent per-object data with one of the subsystem's data structures need to make the following two key changes: .Bl -bullet .It Embed a .Vt struct osd pointer in the structure definition for the object. .It Add calls to .Fn khelp_init_osd and .Fn khelp_destroy_osd to the subsystem code paths which are responsible for respectively initialising and destroying the object. .El .Pp The .Fn khelp_init_osd function initialises the per-object data storage for all currently loaded .Nm modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their .Va h_flags field. The .Fa classes argument specifies a bitmask of .Nm classes which this subsystem associates with. If a .Nm module matches any of the classes in the bitmask, that module will be associated with the object. The .Fa hosd argument specifies the pointer to the object's .Vt struct osd which will be used to provide the persistent storage for use by .Nm modules. .Pp The .Fn khelp_destroy_osd function frees all memory that was associated with an object's .Vt struct osd by a previous call to .Fn khelp_init_osd . The .Fa hosd argument specifies the pointer to the object's .Vt struct osd which will be purged in preparation for destruction. .Sh IMPLEMENTATION NOTES .Nm modules are protected from being prematurely unloaded by a reference count. The count is incremented each time a subsystem calls .Fn khelp_init_osd causing persistent storage to be allocated for the module, and decremented for each corresponding call to .Fn khelp_destroy_osd . Only when a module's reference count has dropped to zero can the module be unloaded. .Sh RETURN VALUES The .Fn khelp_init_osd function returns zero if no errors occurred. It returns ENOMEM if a .Nm module which requires per-object storage fails to allocate the necessary memory. .Pp The .Fn khelp_destroy_osd function only returns zero to indicate that no errors occurred. .Pp The .Fn khelp_get_id function returns the unique numeric identifier for the registered .Nm module with name .Fa hname . It return -1 if no module with the specified name is currently registered. .Pp The .Fn khelp_get_osd function returns the pointer to the .Nm module's persistent object storage memory. If the module identified by .Fa id does not have persistent object storage registered with the object's .Fa hosd .Vt struct osd , NULL is returned. .Pp The .Fn khelp_add_hhook function returns zero if no errors occurred. It returns ENOENT if it could not find the requested .Xr hhook 9 point. It returns ENOMEM if .Xr malloc 9 failed to allocate memory. It returns EEXIST if attempting to register the same hook function more than once for the same .Xr hhook 9 point. .Pp The .Fn khelp_remove_hhook function returns zero if no errors occurred. It returns ENOENT if it could not find the requested .Xr hhook 9 point. .Sh EXAMPLES A well commented example Khelp module can be found at: .Pa /usr/share/examples/kld/khelp/h_example.c .Pp The Enhanced Round Trip Time (ERTT) .Xr h_ertt 4 .Nm module provides a more complex example of what is possible. .Sh SEE ALSO .Xr h_ertt 4 , .Xr hhook 9 , .Xr osd 9 .Sh ACKNOWLEDGEMENTS Development and testing of this software were made possible in part by grants from the FreeBSD Foundation and Cisco University Research Program Fund at Community Foundation Silicon Valley. .Sh HISTORY The .Nm kernel helper framework first appeared in .Fx 9.0 . .Pp The .Nm framework was first released in 2010 by Lawrence Stewart whilst studying at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm framework was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . .Pp This manual page was written by .An David Hayes Aq Mt david.hayes@ieee.org and .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . diff --git a/share/man/man9/vnet.9 b/share/man/man9/vnet.9 index 04724e9a97b0..28e28bfd3242 100644 --- a/share/man/man9/vnet.9 +++ b/share/man/man9/vnet.9 @@ -1,516 +1,515 @@ .\"- .\" Copyright (c) 2010 The FreeBSD Foundation -.\" All rights reserved. .\" .\" This documentation was written by CK Software GmbH under sponsorship from .\" the FreeBSD Foundation. .\" .\" 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 December 10, 2020 .Dt VNET 9 .Os .Sh NAME .Nm VNET .Nd "network subsystem virtualization infrastructure" .Sh SYNOPSIS .Cd "options VIMAGE" .Cd "options VNET_DEBUG" .Pp .In net/vnet.h .\"------------------------------------------------------------ .Ss "Constants and Global Variables" .\" .Dv VNET_SETNAME .\" "set_vnet" .Dv VNET_SYMPREFIX .\" "vnet_entry_" .Vt extern struct vnet *vnet0; .\"------------------------------------------------------------ .Ss "Variable Declaration" .Fo VNET .Fa "name" .Fc .\" .Fo VNET_NAME .Fa "name" .Fc .\" .Fo VNET_DECLARE .Fa "type" "name" .Fc .\" .Fo VNET_DEFINE .Fa "type" "name" .Fc .\" .Fo VNET_DEFINE_STATIC .Fa "type" "name" .Fc .\" .Bd -literal #define V_name VNET(name) .Ed .\" ------------------------------------------------------------ .Ss "Virtual Instance Selection" .\" .Fo CRED_TO_VNET .Fa "struct ucred *" .Fc .\" .Fo TD_TO_VNET .Fa "struct thread *" .Fc .\" .Fo P_TO_VNET .Fa "struct proc *" .Fc .\" .Fo IS_DEFAULT_VNET .Fa "struct vnet *" .Fc .\" .Fo VNET_ASSERT .Fa exp msg .Fc .\" .Fo CURVNET_SET .Fa "struct vnet *" .Fc .\" .Fo CURVNET_SET_QUIET .Fa "struct vnet *" .Fc .\" .Fn CURVNET_RESTORE .\" .Fo VNET_ITERATOR_DECL .Fa "struct vnet *" .Fc .\" .Fo VNET_FOREACH .Fa "struct vnet *" .Fc .\" ------------------------------------------------------------ .Ss "Locking" .\" .Fn VNET_LIST_RLOCK .Fn VNET_LIST_RUNLOCK .Fn VNET_LIST_RLOCK_NOSLEEP .Fn VNET_LIST_RUNLOCK_NOSLEEP .\" ------------------------------------------------------------ .Ss "Startup and Teardown Functions" .\" .Ft "struct vnet *" .Fo vnet_alloc .Fa void .Fc .\" .Ft void .Fo vnet_destroy .Fa "struct vnet *" .Fc .\" .Fo VNET_SYSINIT .Fa ident .Fa "enum sysinit_sub_id subsystem" .Fa "enum sysinit_elem_order order" .Fa "sysinit_cfunc_t func" .Fa "const void *arg" .Fc .\" .Fo VNET_SYSUNINIT .Fa ident .Fa "enum sysinit_sub_id subsystem" .Fa "enum sysinit_elem_order order" .Fa "sysinit_cfunc_t func" .Fa "const void *arg" .Fc .\" ------------------------------------------------------------ .Ss "Eventhandlers" .\" .Fo VNET_GLOBAL_EVENTHANDLER_REGISTER .Fa "const char *name" .Fa "void *func" .Fa "void *arg" .Fa "int priority" .Fc .\" .Fo VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG .Fa "eventhandler_tag tag" .Fa "const char *name" .Fa "void *func" .Fa "void *arg" .Fa "int priority" .Fc .\" ------------------------------------------------------------ .Ss "Sysctl Handling" .Fo SYSCTL_VNET_INT .Fa parent nbr name access ptr val descr .Fc .Fo SYSCTL_VNET_PROC .Fa parent nbr name access ptr arg handler fmt descr .Fc .Fo SYSCTL_VNET_STRING .Fa parent nbr name access arg len descr .Fc .Fo SYSCTL_VNET_STRUCT .Fa parent nbr name access ptr type descr .Fc .Fo SYSCTL_VNET_UINT .Fa parent nbr name access ptr val descr .Fc .Fo VNET_SYSCTL_ARG .Fa req arg1 .Fc .\" ------------------------------------------------------------ .Sh DESCRIPTION .Nm is the name of a technique to virtualize the network stack. The basic idea is to change global resources most notably variables into per network stack resources and have functions, sysctls, eventhandlers, etc. access and handle them in the context of the correct instance. Each (virtual) network stack is attached to a .Em prison , with .Vt vnet0 being the unrestricted default network stack of the base system. .Pp The global defines for .Dv VNET_SETNAME and .Dv VNET_SYMPREFIX are shared with .Xr kvm 3 to access internals for debugging reasons. .\" ------------------------------------------------------------ .Ss "Variable Declaration" .\" Variables are virtualized by using the .Fn VNET_DEFINE macro rather than writing them out as .Em type name . One can still use static initialization, e.g., .Pp .Dl Li VNET_DEFINE(int, foo) = 1; .Pp Variables declared with the static keyword can use the .Fn VNET_DEFINE_STATIC macro, e.g., .Pp .Dl Li VNET_DEFINE_STATIC(SLIST_HEAD(, bar), bars); .Pp Static initialization is not possible when the virtualized variable would need to be referenced, e.g., with .Dq TAILQ_HEAD_INITIALIZER() . In that case a .Fn VNET_SYSINIT based initialization function must be used. .Pp External variables have to be declared using the .Fn VNET_DECLARE macro. In either case the convention is to define another macro, that is then used throughout the implementation to access that variable. The variable name is usually prefixed by .Em V_ to express that it is virtualized. The .Fn VNET macro will then translate accesses to that variable to the copy of the currently selected instance (see the .Sx "Virtual instance selection" section): .Pp .Dl Li #define V_name VNET(name) .Pp .Em NOTE: Do not confuse this with the convention used by .Xr VFS 9 . .Pp The .Fn VNET_NAME macro returns the offset within the memory region of the virtual network stack instance. It is usually only used with .Fn SYSCTL_VNET_* macros. .\" ------------------------------------------------------------ .Ss "Virtual Instance Selection" .\" There are three different places where the current virtual network stack pointer is stored and can be taken from: .Bl -enum -offset indent .It a .Em prison : .Dl "(struct prison *)->pr_vnet" .Pp For convenience the following macros are provided: .Bd -literal -compact -offset indent .Fn CRED_TO_VNET "struct ucred *" .Fn TD_TO_VNET "struct thread *" .Fn P_TO_VNET "struct proc *" .Ed .It a .Em socket : .Dl "(struct socket *)->so_vnet" .It an .Em interface : .Dl "(struct ifnet *)->if_vnet" .El .Pp .\" In addition the currently active instance is cached in .Dq "curthread->td_vnet" which is usually only accessed through the .Dv curvnet macro. .Pp .\" To set the correct context of the current virtual network instance, use the .Fn CURVNET_SET or .Fn CURVNET_SET_QUIET macros. The .Fn CURVNET_SET_QUIET version will not record vnet recursions in case the kernel was compiled with .Cd "options VNET_DEBUG" and should thus only be used in well known cases, where recursion is unavoidable. Both macros will save the previous state on the stack and it must be restored with the .Fn CURVNET_RESTORE macro. .Pp .Em NOTE: As the previous state is saved on the stack, you cannot have multiple .Fn CURVNET_SET calls in the same block. .Pp .Em NOTE: As the previous state is saved on the stack, a .Fn CURVNET_RESTORE call has to be in the same block as the .Fn CURVNET_SET call or in a subblock with the same idea of the saved instances as the outer block. .Pp .Em NOTE: As each macro is a set of operations and, as previously explained, cannot be put into its own block when defined, one cannot conditionally set the current vnet context. The following will .Em not work: .Bd -literal -offset indent if (condition) CURVNET_SET(vnet); .Ed .Pp nor would this work: .Bd -literal -offset indent if (condition) { CURVNET_SET(vnet); } CURVNET_RESTORE(); .Ed .Pp .\" Sometimes one needs to loop over all virtual instances, for example to update virtual from global state, to run a function from a .Xr callout 9 for each instance, etc. For those cases the .Fn VNET_ITERATOR_DECL and .Fn VNET_FOREACH macros are provided. The former macro defines the variable that iterates over the loop, and the latter loops over all of the virtual network stack instances. See .Sx "Locking" for how to savely traverse the list of all virtual instances. .Pp .\" The .Fn IS_DEFAULT_VNET macro provides a safe way to check whether the currently active instance is the unrestricted default network stack of the base system .Pq Vt vnet0 . .Pp .\" The .Fn VNET_ASSERT macro provides a way to conditionally add assertions that are only active with .Cd "options VIMAGE" compiled in and either .Cd "options VNET_DEBUG" or .Cd "options INVARIANTS" enabled as well. It uses the same semantics as .Xr KASSERT 9 . .\" ------------------------------------------------------------ .Ss "Locking" .\" For public access to the list of virtual network stack instances e.g., by the .Fn VNET_FOREACH macro, read locks are provided. Macros are used to abstract from the actual type of the locks. If a caller may sleep while traversing the list, it must use the .Fn VNET_LIST_RLOCK and .Fn VNET_LIST_RUNLOCK macros. Otherwise, the caller can use .Fn VNET_LIST_RLOCK_NOSLEEP and .Fn VNET_LIST_RUNLOCK_NOSLEEP . .\" ------------------------------------------------------------ .Ss "Startup and Teardown Functions" .\" To start or tear down a virtual network stack instance the internal functions .Fn vnet_alloc and .Fn vnet_destroy are provided and called from the jail framework. They run the publicly provided methods to handle network stack startup and teardown. .Pp For public control, the system startup interface has been enhanced to not only handle a system boot but to also handle a virtual network stack startup and teardown. To the base system the .Fn VNET_SYSINIT and .Fn VNET_SYSUNINIT macros look exactly as if there were no virtual network stack. In fact, if .Cd "options VIMAGE" is not compiled in they are compiled to the standard .Fn SYSINIT macros. In addition to that they are run for each virtual network stack when starting or, in reverse order, when shutting down. .\" ------------------------------------------------------------ .Ss "Eventhandlers" .\" Eventhandlers can be handled in two ways: .Pp .Bl -enum -offset indent -compact .It save the .Em tags returned in each virtual instance and properly free the eventhandlers on teardown using those, or .It use one eventhandler that will iterate over all virtual network stack instances. .El .Pp For the first case one can just use the normal .Xr EVENTHANDLER 9 functions, while for the second case the .Fn VNET_GLOBAL_EVENTHANDLER_REGISTER and .Fn VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG macros are provided. These differ in that .Fn VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG takes an extra first argument that will carry the .Fa "tag" upon return. Eventhandlers registered with either of these will not run .Fa func directly but .Fa func will be called from an internal iterator function for each vnet. Both macros can only be used for eventhandlers that do not take additional arguments, as the variadic arguments from an .Xr EVENTHANDLER_INVOKE 9 call will be ignored. .\" ------------------------------------------------------------ .Ss "Sysctl Handling" .\" A .Xr sysctl 9 can be virtualized by using one of the .Fn SYSCTL_VNET_* macros. .Pp They take the same arguments as the standard .Xr sysctl 9 functions, with the only difference, that the .Fa ptr argument has to be passed as .Ql &VNET_NAME(foo) instead of .Ql &foo so that the variable can be selected from the correct memory region of the virtual network stack instance of the caller. .Pp For the very rare case a sysctl handler function would want to handle .Fa arg1 itself the .Fn VNET_SYSCTL_ARG req arg1 is provided that will translate the .Fa arg1 argument to the correct memory address in the virtual network stack context of the caller. .\" ------------------------------------------------------------ .Sh SEE ALSO .Xr jail 2 , .Xr kvm 3 , .Xr EVENTHANDLER 9 , .\" .Xr pcpu 9 , .Xr KASSERT 9 , .Xr sysctl 9 .\" .Xr SYSINIT 9 .Pp Marko Zec, Implementing a Clonable Network Stack in the FreeBSD Kernel, USENIX ATC'03, June 2003, Boston .Sh HISTORY The virtual network stack implementation first appeared in .Fx 8.0 . .Sh AUTHORS .An -nosplit The .Nm framework was designed and implemented at the University of Zagreb by .An Marko Zec under sponsorship of the FreeBSD Foundation and NLnet Foundation, and later extended and refined by .An Bjoern A. Zeeb (also under FreeBSD Foundation sponsorship), and .An Robert Watson . .Pp This manual page was written by .An Bjoern A. Zeeb, CK Software GmbH, under sponsorship from the FreeBSD Foundation.