Index: stable/10/lib/libc/amd64/gen/setjmp.S =================================================================== --- stable/10/lib/libc/amd64/gen/setjmp.S (revision 287479) +++ stable/10/lib/libc/amd64/gen/setjmp.S (revision 287480) @@ -1,117 +1,117 @@ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. 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) .asciz "@(#)setjmp.s 5.1 (Berkeley) 4/23/90" #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * C library -- _setjmp, _longjmp * * longjmp(a,v) * will generate a "return(v)" from the last call to * setjmp(a) * by restoring registers from the environment 'a'. * The previous signal state is restored. */ #include "SYS.h" ENTRY(setjmp) pushq %rdi movq %rdi,%rcx movq $1,%rdi /* SIG_BLOCK */ movq $0,%rsi /* (sigset_t*)set */ leaq 72(%rcx),%rdx /* 9,10; (sigset_t*)oset */ /* stack is 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask popq %rdi movq %rdi,%rcx movq 0(%rsp),%rdx /* retval */ movq %rdx, 0(%rcx) /* 0; retval */ movq %rbx, 8(%rcx) /* 1; rbx */ movq %rsp,16(%rcx) /* 2; rsp */ movq %rbp,24(%rcx) /* 3; rbp */ movq %r12,32(%rcx) /* 4; r12 */ movq %r13,40(%rcx) /* 5; r13 */ movq %r14,48(%rcx) /* 6; r14 */ movq %r15,56(%rcx) /* 7; r15 */ fnstcw 64(%rcx) /* 8; fpu cw */ stmxcsr 68(%rcx) /* and mxcsr */ xorq %rax,%rax ret END(setjmp) .weak CNAME(longjmp) .set CNAME(longjmp),CNAME(__longjmp) ENTRY(__longjmp) pushq %rdi pushq %rsi movq %rdi,%rdx movq $3,%rdi /* SIG_SETMASK */ leaq 72(%rdx),%rsi /* (sigset_t*)set */ movq $0,%rdx /* (sigset_t*)oset */ subq $0x8,%rsp /* make the stack 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask addq $0x8,%rsp popq %rsi popq %rdi /* jmpbuf */ movq %rdi,%rdx /* Restore the mxcsr, but leave exception flags intact. */ stmxcsr -4(%rsp) movl 68(%rdx),%eax andl $0xffffffc0,%eax movl -4(%rsp),%edi andl $0x3f,%edi xorl %eax,%edi movl %edi,-4(%rsp) ldmxcsr -4(%rsp) movq %rsi,%rax /* retval */ movq 0(%rdx),%rcx movq 8(%rdx),%rbx movq 16(%rdx),%rsp movq 24(%rdx),%rbp movq 32(%rdx),%r12 movq 40(%rdx),%r13 movq 48(%rdx),%r14 movq 56(%rdx),%r15 fldcw 64(%rdx) testq %rax,%rax jnz 1f incq %rax 1: movq %rcx,0(%rsp) ret END(__longjmp) .section .note.GNU-stack,"",%progbits Index: stable/10/lib/libc/amd64/gen/sigsetjmp.S =================================================================== --- stable/10/lib/libc/amd64/gen/sigsetjmp.S (revision 287479) +++ stable/10/lib/libc/amd64/gen/sigsetjmp.S (revision 287480) @@ -1,118 +1,118 @@ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. 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. * * @(#)setjmp.s 5.1 (Berkeley) 4/23/90" */ #if defined(LIBC_SCCS) && !defined(lint) .text .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $" #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "SYS.h" /*- * TODO: * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp, * remove the other *jmp functions and define everything in terms * of the renamed functions. This requires compiler support for * the renamed functions (introduced in gcc-2.5.3; previous versions * only supported *jmp with 0 or 1 leading underscores). * * Restore _all_ the registers and the signal mask atomically. Can * use sigreturn() if sigreturn() works. */ ENTRY(sigsetjmp) movl %esi,88(%rdi) /* 11; savemask */ testl %esi,%esi jz 2f pushq %rdi movq %rdi,%rcx movq $1,%rdi /* SIG_BLOCK */ movq $0,%rsi /* (sigset_t*)set */ leaq 72(%rcx),%rdx /* 9,10 (sigset_t*)oset */ /* stack is 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask popq %rdi 2: movq %rdi,%rcx movq 0(%rsp),%rdx /* retval */ movq %rdx, 0(%rcx) /* 0; retval */ movq %rbx, 8(%rcx) /* 1; rbx */ movq %rsp,16(%rcx) /* 2; rsp */ movq %rbp,24(%rcx) /* 3; rbp */ movq %r12,32(%rcx) /* 4; r12 */ movq %r13,40(%rcx) /* 5; r13 */ movq %r14,48(%rcx) /* 6; r14 */ movq %r15,56(%rcx) /* 7; r15 */ fnstcw 64(%rcx) /* 8; fpu cw */ xorq %rax,%rax ret END(sigsetjmp) .weak CNAME(siglongjmp) .set CNAME(siglongjmp),CNAME(__siglongjmp) ENTRY(__siglongjmp) cmpl $0,88(%rdi) jz 2f movq %rdi,%rdx pushq %rdi pushq %rsi movq $3,%rdi /* SIG_SETMASK */ leaq 72(%rdx),%rsi /* (sigset_t*)set */ movq $0,%rdx /* (sigset_t*)oset */ subq $0x8,%rsp /* make the stack 16-byte aligned */ - call PIC_PLT(CNAME(_sigprocmask)) + call __libc_sigprocmask addq $0x8,%rsp popq %rsi popq %rdi /* jmpbuf */ 2: movq %rdi,%rdx movq %rsi,%rax /* retval */ movq 0(%rdx),%rcx movq 8(%rdx),%rbx movq 16(%rdx),%rsp movq 24(%rdx),%rbp movq 32(%rdx),%r12 movq 40(%rdx),%r13 movq 48(%rdx),%r14 movq 56(%rdx),%r15 fninit fldcw 64(%rdx) testq %rax,%rax jnz 1f incq %rax 1: movq %rcx,0(%rsp) ret END(__siglongjmp) .section .note.GNU-stack,"",%progbits Index: stable/10/lib/libc/compat-43/sigcompat.c =================================================================== --- stable/10/lib/libc/compat-43/sigcompat.c (revision 287479) +++ stable/10/lib/libc/compat-43/sigcompat.c (revision 287480) @@ -1,189 +1,189 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. 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. * 4. 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[] = "@(#)sigcompat.c 8.1 (Berkeley) 6/2/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" int sigvec(signo, sv, osv) int signo; struct sigvec *sv, *osv; { struct sigaction sa, osa; struct sigaction *sap, *osap; int ret; if (sv != NULL) { sa.sa_handler = sv->sv_handler; sa.sa_flags = sv->sv_flags ^ SV_INTERRUPT; sigemptyset(&sa.sa_mask); sa.sa_mask.__bits[0] = sv->sv_mask; sap = &sa; } else sap = NULL; osap = osv != NULL ? &osa : NULL; - ret = _sigaction(signo, sap, osap); + ret = __libc_sigaction(signo, sap, osap); if (ret == 0 && osv != NULL) { osv->sv_handler = osa.sa_handler; osv->sv_flags = osa.sa_flags ^ SV_INTERRUPT; osv->sv_mask = osa.sa_mask.__bits[0]; } return (ret); } int sigsetmask(mask) int mask; { sigset_t set, oset; int n; sigemptyset(&set); set.__bits[0] = mask; - n = _sigprocmask(SIG_SETMASK, &set, &oset); + n = __libc_sigprocmask(SIG_SETMASK, &set, &oset); if (n) return (n); return (oset.__bits[0]); } int sigblock(mask) int mask; { sigset_t set, oset; int n; sigemptyset(&set); set.__bits[0] = mask; - n = _sigprocmask(SIG_BLOCK, &set, &oset); + n = __libc_sigprocmask(SIG_BLOCK, &set, &oset); if (n) return (n); return (oset.__bits[0]); } int sigpause(int mask) { sigset_t set; sigemptyset(&set); set.__bits[0] = mask; - return (_sigsuspend(&set)); + return (__libc_sigsuspend(&set)); } int xsi_sigpause(int sig) { sigset_t set; - if (_sigprocmask(SIG_BLOCK, NULL, &set) == -1) + if (__libc_sigprocmask(SIG_BLOCK, NULL, &set) == -1) return (-1); if (sigdelset(&set, sig) == -1) return (-1); - return (_sigsuspend(&set)); + return (__libc_sigsuspend(&set)); } int sighold(int sig) { sigset_t set; sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (-1); - return (_sigprocmask(SIG_BLOCK, &set, NULL)); + return (__libc_sigprocmask(SIG_BLOCK, &set, NULL)); } int sigignore(int sig) { struct sigaction sa; bzero(&sa, sizeof(sa)); sa.sa_handler = SIG_IGN; - return (_sigaction(sig, &sa, NULL)); + return (__libc_sigaction(sig, &sa, NULL)); } int sigrelse(int sig) { sigset_t set; sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (-1); - return (_sigprocmask(SIG_UNBLOCK, &set, NULL)); + return (__libc_sigprocmask(SIG_UNBLOCK, &set, NULL)); } void (*sigset(int sig, void (*disp)(int)))(int) { sigset_t set, pset; struct sigaction sa, psa; sigemptyset(&set); if (sigaddset(&set, sig) == -1) return (SIG_ERR); - if (_sigprocmask(SIG_BLOCK, NULL, &pset) == -1) + if (__libc_sigprocmask(SIG_BLOCK, NULL, &pset) == -1) return (SIG_ERR); if ((__sighandler_t *)disp == SIG_HOLD) { - if (_sigprocmask(SIG_BLOCK, &set, &pset) == -1) + if (__libc_sigprocmask(SIG_BLOCK, &set, &pset) == -1) return (SIG_ERR); if (sigismember(&pset, sig)) return (SIG_HOLD); else { - if (_sigaction(sig, NULL, &psa) == -1) + if (__libc_sigaction(sig, NULL, &psa) == -1) return (SIG_ERR); return (psa.sa_handler); } } else { - if (_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1) + if (__libc_sigprocmask(SIG_UNBLOCK, &set, &pset) == -1) return (SIG_ERR); } bzero(&sa, sizeof(sa)); sa.sa_handler = disp; - if (_sigaction(sig, &sa, &psa) == -1) + if (__libc_sigaction(sig, &sa, &psa) == -1) return (SIG_ERR); if (sigismember(&pset, sig)) return (SIG_HOLD); else return (psa.sa_handler); } Index: stable/10/lib/libc/db/btree/bt_open.c =================================================================== --- stable/10/lib/libc/db/btree/bt_open.c (revision 287479) +++ stable/10/lib/libc/db/btree/bt_open.c (revision 287480) @@ -1,448 +1,449 @@ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Mike Olson. * * 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. * 4. 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[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * Implementation of btree access method for 4.4BSD. * * The design here was originally based on that of the btree access method * used in the Postgres database system at UC Berkeley. This implementation * is wholly independent of the Postgres code. */ #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" #include #include "btree.h" #ifdef DEBUG #undef MINPSIZE #define MINPSIZE 128 #endif static int byteorder(void); static int nroot(BTREE *); static int tmp(void); /* * __BT_OPEN -- Open a btree. * * Creates and fills a DB struct, and calls the routine that actually * opens the btree. * * Parameters: * fname: filename (NULL for in-memory trees) * flags: open flag bits * mode: open permission bits * b: BTREEINFO pointer * * Returns: * NULL on failure, pointer to DB on success. * */ DB * __bt_open(const char *fname, int flags, int mode, const BTREEINFO *openinfo, int dflags) { struct stat sb; BTMETA m; BTREE *t; BTREEINFO b; DB *dbp; pgno_t ncache; ssize_t nr; int machine_lorder, saved_errno; t = NULL; /* * Intention is to make sure all of the user's selections are okay * here and then use them without checking. Can't be complete, since * we don't know the right page size, lorder or flags until the backing * file is opened. Also, the file's page size can cause the cachesize * to change. */ machine_lorder = byteorder(); if (openinfo) { b = *openinfo; /* Flags: R_DUP. */ if (b.flags & ~(R_DUP)) goto einval; /* * Page size must be indx_t aligned and >= MINPSIZE. Default * page size is set farther on, based on the underlying file * transfer size. */ if (b.psize && (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 || b.psize & (sizeof(indx_t) - 1) )) goto einval; /* Minimum number of keys per page; absolute minimum is 2. */ if (b.minkeypage) { if (b.minkeypage < 2) goto einval; } else b.minkeypage = DEFMINKEYPAGE; /* If no comparison, use default comparison and prefix. */ if (b.compare == NULL) { b.compare = __bt_defcmp; if (b.prefix == NULL) b.prefix = __bt_defpfx; } if (b.lorder == 0) b.lorder = machine_lorder; } else { b.compare = __bt_defcmp; b.cachesize = 0; b.flags = 0; b.lorder = machine_lorder; b.minkeypage = DEFMINKEYPAGE; b.prefix = __bt_defpfx; b.psize = 0; } /* Check for the ubiquitous PDP-11. */ if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN) goto einval; /* Allocate and initialize DB and BTREE structures. */ if ((t = (BTREE *)calloc(1, sizeof(BTREE))) == NULL) goto err; t->bt_fd = -1; /* Don't close unopened fd on error. */ t->bt_lorder = b.lorder; t->bt_order = NOT; t->bt_cmp = b.compare; t->bt_pfx = b.prefix; t->bt_rfd = -1; if ((t->bt_dbp = dbp = (DB *)calloc(1, sizeof(DB))) == NULL) goto err; if (t->bt_lorder != machine_lorder) F_SET(t, B_NEEDSWAP); dbp->type = DB_BTREE; dbp->internal = t; dbp->close = __bt_close; dbp->del = __bt_delete; dbp->fd = __bt_fd; dbp->get = __bt_get; dbp->put = __bt_put; dbp->seq = __bt_seq; dbp->sync = __bt_sync; /* * If no file name was supplied, this is an in-memory btree and we * open a backing temporary file. Otherwise, it's a disk-based tree. */ if (fname) { switch (flags & O_ACCMODE) { case O_RDONLY: F_SET(t, B_RDONLY); break; case O_RDWR: break; case O_WRONLY: default: goto einval; } if ((t->bt_fd = _open(fname, flags | O_CLOEXEC, mode)) < 0) goto err; } else { if ((flags & O_ACCMODE) != O_RDWR) goto einval; if ((t->bt_fd = tmp()) == -1) goto err; F_SET(t, B_INMEM); } if (_fstat(t->bt_fd, &sb)) goto err; if (sb.st_size) { if ((nr = _read(t->bt_fd, &m, sizeof(BTMETA))) < 0) goto err; if (nr != sizeof(BTMETA)) goto eftype; /* * Read in the meta-data. This can change the notion of what * the lorder, page size and flags are, and, when the page size * changes, the cachesize value can change too. If the user * specified the wrong byte order for an existing database, we * don't bother to return an error, we just clear the NEEDSWAP * bit. */ if (m.magic == BTREEMAGIC) F_CLR(t, B_NEEDSWAP); else { F_SET(t, B_NEEDSWAP); M_32_SWAP(m.magic); M_32_SWAP(m.version); M_32_SWAP(m.psize); M_32_SWAP(m.free); M_32_SWAP(m.nrecs); M_32_SWAP(m.flags); } if (m.magic != BTREEMAGIC || m.version != BTREEVERSION) goto eftype; if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 || m.psize & (sizeof(indx_t) - 1) ) goto eftype; if (m.flags & ~SAVEMETA) goto eftype; b.psize = m.psize; F_SET(t, m.flags); t->bt_free = m.free; t->bt_nrecs = m.nrecs; } else { /* * Set the page size to the best value for I/O to this file. * Don't overflow the page offset type. */ if (b.psize == 0) { b.psize = sb.st_blksize; if (b.psize < MINPSIZE) b.psize = MINPSIZE; if (b.psize > MAX_PAGE_OFFSET + 1) b.psize = MAX_PAGE_OFFSET + 1; } /* Set flag if duplicates permitted. */ if (!(b.flags & R_DUP)) F_SET(t, B_NODUPS); t->bt_free = P_INVALID; t->bt_nrecs = 0; F_SET(t, B_METADIRTY); } t->bt_psize = b.psize; /* Set the cache size; must be a multiple of the page size. */ if (b.cachesize && b.cachesize & (b.psize - 1) ) b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1; if (b.cachesize < b.psize * MINCACHE) b.cachesize = b.psize * MINCACHE; /* Calculate number of pages to cache. */ ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize; /* * The btree data structure requires that at least two keys can fit on * a page, but other than that there's no fixed requirement. The user * specified a minimum number per page, and we translated that into the * number of bytes a key/data pair can use before being placed on an * overflow page. This calculation includes the page header, the size * of the index referencing the leaf item and the size of the leaf item * structure. Also, don't let the user specify a minkeypage such that * a key/data pair won't fit even if both key and data are on overflow * pages. */ t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage - (sizeof(indx_t) + NBLEAFDBT(0, 0)); if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t)) t->bt_ovflsize = NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t); /* Initialize the buffer pool. */ if ((t->bt_mp = mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL) goto err; if (!F_ISSET(t, B_INMEM)) mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t); /* Create a root page if new tree. */ if (nroot(t) == RET_ERROR) goto err; /* Global flags. */ if (dflags & DB_LOCK) F_SET(t, B_DB_LOCK); if (dflags & DB_SHMEM) F_SET(t, B_DB_SHMEM); if (dflags & DB_TXN) F_SET(t, B_DB_TXN); return (dbp); einval: errno = EINVAL; goto err; eftype: errno = EFTYPE; goto err; err: saved_errno = errno; if (t) { if (t->bt_dbp) free(t->bt_dbp); if (t->bt_fd != -1) (void)_close(t->bt_fd); free(t); } errno = saved_errno; return (NULL); } /* * NROOT -- Create the root of a new tree. * * Parameters: * t: tree * * Returns: * RET_ERROR, RET_SUCCESS */ static int nroot(BTREE *t) { PAGE *meta, *root; pgno_t npg; if ((root = mpool_get(t->bt_mp, 1, 0)) != NULL) { if (root->lower == 0 && root->pgno == 0 && root->linp[0] == 0) { mpool_delete(t->bt_mp, root); errno = EINVAL; } else { mpool_put(t->bt_mp, root, 0); return (RET_SUCCESS); } } if (errno != EINVAL) /* It's OK to not exist. */ return (RET_ERROR); errno = 0; if ((meta = mpool_new(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL) return (RET_ERROR); if ((root = mpool_new(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL) return (RET_ERROR); if (npg != P_ROOT) return (RET_ERROR); root->pgno = npg; root->prevpg = root->nextpg = P_INVALID; root->lower = BTDATAOFF; root->upper = t->bt_psize; root->flags = P_BLEAF; memset(meta, 0, t->bt_psize); mpool_put(t->bt_mp, meta, MPOOL_DIRTY); mpool_put(t->bt_mp, root, MPOOL_DIRTY); return (RET_SUCCESS); } static int tmp(void) { sigset_t set, oset; int fd, len; char *envtmp = NULL; char path[MAXPATHLEN]; if (issetugid() == 0) envtmp = getenv("TMPDIR"); len = snprintf(path, sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp"); if (len < 0 || len >= (int)sizeof(path)) { errno = ENAMETOOLONG; return(-1); } (void)sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); if ((fd = mkostemp(path, O_CLOEXEC)) != -1) (void)unlink(path); - (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, NULL); return(fd); } static int byteorder(void) { u_int32_t x; u_char *p; x = 0x01020304; p = (u_char *)&x; switch (*p) { case 1: return (BIG_ENDIAN); case 4: return (LITTLE_ENDIAN); default: return (0); } } int __bt_fd(const DB *dbp) { BTREE *t; t = dbp->internal; /* Toss any page pinned across calls. */ if (t->bt_pinned != NULL) { mpool_put(t->bt_mp, t->bt_pinned, 0); t->bt_pinned = NULL; } /* In-memory database can't have a file descriptor. */ if (F_ISSET(t, B_INMEM)) { errno = ENOENT; return (-1); } return (t->bt_fd); } Index: stable/10/lib/libc/db/hash/hash_page.c =================================================================== --- stable/10/lib/libc/db/hash/hash_page.c (revision 287479) +++ stable/10/lib/libc/db/hash/hash_page.c (revision 287480) @@ -1,934 +1,935 @@ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Margo Seltzer. * * 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. * 4. 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[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * PACKAGE: hashing * * DESCRIPTION: * Page manipulation for hashing package. * * ROUTINES: * * External * __get_page * __add_ovflpage * Internal * overflow_page * open_temp */ #include "namespace.h" #include #include #include #include #include #include #include #include #ifdef DEBUG #include #endif #include "un-namespace.h" +#include "libc_private.h" #include #include "hash.h" #include "page.h" #include "extern.h" static u_int32_t *fetch_bitmap(HTAB *, int); static u_int32_t first_free(u_int32_t); static int open_temp(HTAB *); static u_int16_t overflow_page(HTAB *); static void putpair(char *, const DBT *, const DBT *); static void squeeze_key(u_int16_t *, const DBT *, const DBT *); static int ugly_split(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int); #define PAGE_INIT(P) { \ ((u_int16_t *)(P))[0] = 0; \ ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \ ((u_int16_t *)(P))[2] = hashp->BSIZE; \ } /* * This is called AFTER we have verified that there is room on the page for * the pair (PAIRFITS has returned true) so we go right ahead and start moving * stuff on. */ static void putpair(char *p, const DBT *key, const DBT *val) { u_int16_t *bp, n, off; bp = (u_int16_t *)p; /* Enter the key first. */ n = bp[0]; off = OFFSET(bp) - key->size; memmove(p + off, key->data, key->size); bp[++n] = off; /* Now the data. */ off -= val->size; memmove(p + off, val->data, val->size); bp[++n] = off; /* Adjust page info. */ bp[0] = n; bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t)); bp[n + 2] = off; } /* * Returns: * 0 OK * -1 error */ int __delpair(HTAB *hashp, BUFHEAD *bufp, int ndx) { u_int16_t *bp, newoff, pairlen; int n; bp = (u_int16_t *)bufp->page; n = bp[0]; if (bp[ndx + 1] < REAL_KEY) return (__big_delete(hashp, bufp)); if (ndx != 1) newoff = bp[ndx - 1]; else newoff = hashp->BSIZE; pairlen = newoff - bp[ndx + 1]; if (ndx != (n - 1)) { /* Hard Case -- need to shuffle keys */ int i; char *src = bufp->page + (int)OFFSET(bp); char *dst = src + (int)pairlen; memmove(dst, src, bp[ndx + 1] - OFFSET(bp)); /* Now adjust the pointers */ for (i = ndx + 2; i <= n; i += 2) { if (bp[i + 1] == OVFLPAGE) { bp[i - 2] = bp[i]; bp[i - 1] = bp[i + 1]; } else { bp[i - 2] = bp[i] + pairlen; bp[i - 1] = bp[i + 1] + pairlen; } } if (ndx == hashp->cndx) { /* * We just removed pair we were "pointing" to. * By moving back the cndx we ensure subsequent * hash_seq() calls won't skip over any entries. */ hashp->cndx -= 2; } } /* Finally adjust the page data */ bp[n] = OFFSET(bp) + pairlen; bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t); bp[0] = n - 2; hashp->NKEYS--; bufp->flags |= BUF_MOD; return (0); } /* * Returns: * 0 ==> OK * -1 ==> Error */ int __split_page(HTAB *hashp, u_int32_t obucket, u_int32_t nbucket) { BUFHEAD *new_bufp, *old_bufp; u_int16_t *ino; char *np; DBT key, val; int n, ndx, retval; u_int16_t copyto, diff, off, moved; char *op; copyto = (u_int16_t)hashp->BSIZE; off = (u_int16_t)hashp->BSIZE; old_bufp = __get_buf(hashp, obucket, NULL, 0); if (old_bufp == NULL) return (-1); new_bufp = __get_buf(hashp, nbucket, NULL, 0); if (new_bufp == NULL) return (-1); old_bufp->flags |= (BUF_MOD | BUF_PIN); new_bufp->flags |= (BUF_MOD | BUF_PIN); ino = (u_int16_t *)(op = old_bufp->page); np = new_bufp->page; moved = 0; for (n = 1, ndx = 1; n < ino[0]; n += 2) { if (ino[n + 1] < REAL_KEY) { retval = ugly_split(hashp, obucket, old_bufp, new_bufp, (int)copyto, (int)moved); old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (retval); } key.data = (u_char *)op + ino[n]; key.size = off - ino[n]; if (__call_hash(hashp, key.data, key.size) == obucket) { /* Don't switch page */ diff = copyto - off; if (diff) { copyto = ino[n + 1] + diff; memmove(op + copyto, op + ino[n + 1], off - ino[n + 1]); ino[ndx] = copyto + ino[n] - ino[n + 1]; ino[ndx + 1] = copyto; } else copyto = ino[n + 1]; ndx += 2; } else { /* Switch page */ val.data = (u_char *)op + ino[n + 1]; val.size = ino[n] - ino[n + 1]; putpair(np, &key, &val); moved += 2; } off = ino[n + 1]; } /* Now clean up the page */ ino[0] -= moved; FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3); OFFSET(ino) = copyto; #ifdef DEBUG3 (void)fprintf(stderr, "split %d/%d\n", ((u_int16_t *)np)[0] / 2, ((u_int16_t *)op)[0] / 2); #endif /* unpin both pages */ old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (0); } /* * Called when we encounter an overflow or big key/data page during split * handling. This is special cased since we have to begin checking whether * the key/data pairs fit on their respective pages and because we may need * overflow pages for both the old and new pages. * * The first page might be a page with regular key/data pairs in which case * we have a regular overflow condition and just need to go on to the next * page or it might be a big key/data pair in which case we need to fix the * big key/data pair. * * Returns: * 0 ==> success * -1 ==> failure */ static int ugly_split(HTAB *hashp, u_int32_t obucket, /* Same as __split_page. */ BUFHEAD *old_bufp, BUFHEAD *new_bufp, int copyto, /* First byte on page which contains key/data values. */ int moved) /* Number of pairs moved to new page. */ { BUFHEAD *bufp; /* Buffer header for ino */ u_int16_t *ino; /* Page keys come off of */ u_int16_t *np; /* New page */ u_int16_t *op; /* Page keys go on to if they aren't moving */ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */ DBT key, val; SPLIT_RETURN ret; u_int16_t n, off, ov_addr, scopyto; char *cino; /* Character value of ino */ bufp = old_bufp; ino = (u_int16_t *)old_bufp->page; np = (u_int16_t *)new_bufp->page; op = (u_int16_t *)old_bufp->page; last_bfp = NULL; scopyto = (u_int16_t)copyto; /* ANSI */ n = ino[0] - 1; while (n < ino[0]) { if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) { if (__big_split(hashp, old_bufp, new_bufp, bufp, bufp->addr, obucket, &ret)) return (-1); old_bufp = ret.oldp; if (!old_bufp) return (-1); op = (u_int16_t *)old_bufp->page; new_bufp = ret.newp; if (!new_bufp) return (-1); np = (u_int16_t *)new_bufp->page; bufp = ret.nextp; if (!bufp) return (0); cino = (char *)bufp->page; ino = (u_int16_t *)cino; last_bfp = ret.nextp; } else if (ino[n + 1] == OVFLPAGE) { ov_addr = ino[n]; /* * Fix up the old page -- the extra 2 are the fields * which contained the overflow information. */ ino[0] -= (moved + 2); FREESPACE(ino) = scopyto - sizeof(u_int16_t) * (ino[0] + 3); OFFSET(ino) = scopyto; bufp = __get_buf(hashp, ov_addr, bufp, 0); if (!bufp) return (-1); ino = (u_int16_t *)bufp->page; n = 1; scopyto = hashp->BSIZE; moved = 0; if (last_bfp) __free_ovflpage(hashp, last_bfp); last_bfp = bufp; } /* Move regular sized pairs of there are any */ off = hashp->BSIZE; for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) { cino = (char *)ino; key.data = (u_char *)cino + ino[n]; key.size = off - ino[n]; val.data = (u_char *)cino + ino[n + 1]; val.size = ino[n] - ino[n + 1]; off = ino[n + 1]; if (__call_hash(hashp, key.data, key.size) == obucket) { /* Keep on old page */ if (PAIRFITS(op, (&key), (&val))) putpair((char *)op, &key, &val); else { old_bufp = __add_ovflpage(hashp, old_bufp); if (!old_bufp) return (-1); op = (u_int16_t *)old_bufp->page; putpair((char *)op, &key, &val); } old_bufp->flags |= BUF_MOD; } else { /* Move to new page */ if (PAIRFITS(np, (&key), (&val))) putpair((char *)np, &key, &val); else { new_bufp = __add_ovflpage(hashp, new_bufp); if (!new_bufp) return (-1); np = (u_int16_t *)new_bufp->page; putpair((char *)np, &key, &val); } new_bufp->flags |= BUF_MOD; } } } if (last_bfp) __free_ovflpage(hashp, last_bfp); return (0); } /* * Add the given pair to the page * * Returns: * 0 ==> OK * 1 ==> failure */ int __addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) { u_int16_t *bp, *sop; int do_expand; bp = (u_int16_t *)bufp->page; do_expand = 0; while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY)) /* Exception case */ if (bp[2] == FULL_KEY_DATA && bp[0] == 2) /* This is the last page of a big key/data pair and we need to add another page */ break; else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) { bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; } else if (bp[bp[0]] != OVFLPAGE) { /* Short key/data pairs, no more pages */ break; } else { /* Try to squeeze key on this page */ if (bp[2] >= REAL_KEY && FREESPACE(bp) >= PAIRSIZE(key, val)) { squeeze_key(bp, key, val); goto stats; } else { bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); if (!bufp) return (-1); bp = (u_int16_t *)bufp->page; } } if (PAIRFITS(bp, key, val)) putpair(bufp->page, key, val); else { do_expand = 1; bufp = __add_ovflpage(hashp, bufp); if (!bufp) return (-1); sop = (u_int16_t *)bufp->page; if (PAIRFITS(sop, key, val)) putpair((char *)sop, key, val); else if (__big_insert(hashp, bufp, key, val)) return (-1); } stats: bufp->flags |= BUF_MOD; /* * If the average number of keys per bucket exceeds the fill factor, * expand the table. */ hashp->NKEYS++; if (do_expand || (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR)) return (__expand_table(hashp)); return (0); } /* * * Returns: * pointer on success * NULL on error */ BUFHEAD * __add_ovflpage(HTAB *hashp, BUFHEAD *bufp) { u_int16_t *sp, ndx, ovfl_num; #ifdef DEBUG1 int tmp1, tmp2; #endif sp = (u_int16_t *)bufp->page; /* Check if we are dynamically determining the fill factor */ if (hashp->FFACTOR == DEF_FFACTOR) { hashp->FFACTOR = sp[0] >> 1; if (hashp->FFACTOR < MIN_FFACTOR) hashp->FFACTOR = MIN_FFACTOR; } bufp->flags |= BUF_MOD; ovfl_num = overflow_page(hashp); #ifdef DEBUG1 tmp1 = bufp->addr; tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0; #endif if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1))) return (NULL); bufp->ovfl->flags |= BUF_MOD; #ifdef DEBUG1 (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n", tmp1, tmp2, bufp->ovfl->addr); #endif ndx = sp[0]; /* * Since a pair is allocated on a page only if there's room to add * an overflow page, we know that the OVFL information will fit on * the page. */ sp[ndx + 4] = OFFSET(sp); sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE; sp[ndx + 1] = ovfl_num; sp[ndx + 2] = OVFLPAGE; sp[0] = ndx + 2; #ifdef HASH_STATISTICS hash_overflows++; #endif return (bufp->ovfl); } /* * Returns: * 0 indicates SUCCESS * -1 indicates FAILURE */ int __get_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_disk, int is_bitmap) { int fd, page, size, rsize; u_int16_t *bp; fd = hashp->fp; size = hashp->BSIZE; if ((fd == -1) || !is_disk) { PAGE_INIT(p); return (0); } if (is_bucket) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); if ((rsize = pread(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) return (-1); bp = (u_int16_t *)p; if (!rsize) bp[0] = 0; /* We hit the EOF, so initialize a new page */ else if (rsize != size) { errno = EFTYPE; return (-1); } if (!is_bitmap && !bp[0]) { PAGE_INIT(p); } else if (hashp->LORDER != BYTE_ORDER) { int i, max; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ for (i = 0; i < max; i++) M_32_SWAP(((int *)p)[i]); } else { M_16_SWAP(bp[0]); max = bp[0] + 2; for (i = 1; i <= max; i++) M_16_SWAP(bp[i]); } } return (0); } /* * Write page p to disk * * Returns: * 0 ==> OK * -1 ==>failure */ int __put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap) { int fd, page, size, wsize; size = hashp->BSIZE; if ((hashp->fp == -1) && open_temp(hashp)) return (-1); fd = hashp->fp; if (hashp->LORDER != BYTE_ORDER) { int i, max; if (is_bitmap) { max = hashp->BSIZE >> 2; /* divide by 4 */ for (i = 0; i < max; i++) M_32_SWAP(((int *)p)[i]); } else { max = ((u_int16_t *)p)[0] + 2; for (i = 0; i <= max; i++) M_16_SWAP(((u_int16_t *)p)[i]); } } if (is_bucket) page = BUCKET_TO_PAGE(bucket); else page = OADDR_TO_PAGE(bucket); if ((wsize = pwrite(fd, p, size, (off_t)page << hashp->BSHIFT)) == -1) /* Errno is set */ return (-1); if (wsize != size) { errno = EFTYPE; return (-1); } return (0); } #define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1) /* * Initialize a new bitmap page. Bitmap pages are left in memory * once they are read in. */ int __ibitmap(HTAB *hashp, int pnum, int nbits, int ndx) { u_int32_t *ip; int clearbytes, clearints; if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) return (1); hashp->nmaps++; clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1; clearbytes = clearints << INT_TO_BYTE; (void)memset((char *)ip, 0, clearbytes); (void)memset(((char *)ip) + clearbytes, 0xFF, hashp->BSIZE - clearbytes); ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK); SETBIT(ip, 0); hashp->BITMAPS[ndx] = (u_int16_t)pnum; hashp->mapp[ndx] = ip; return (0); } static u_int32_t first_free(u_int32_t map) { u_int32_t i, mask; mask = 0x1; for (i = 0; i < BITS_PER_MAP; i++) { if (!(mask & map)) return (i); mask = mask << 1; } return (i); } static u_int16_t overflow_page(HTAB *hashp) { u_int32_t *freep; int max_free, offset, splitnum; u_int16_t addr; int bit, first_page, free_bit, free_page, i, in_use_bits, j; #ifdef DEBUG2 int tmp1, tmp2; #endif splitnum = hashp->OVFL_POINT; max_free = hashp->SPARES[splitnum]; free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT); free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1); /* Look through all the free maps to find the first free block */ first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT); for ( i = first_page; i <= free_page; i++ ) { if (!(freep = (u_int32_t *)hashp->mapp[i]) && !(freep = fetch_bitmap(hashp, i))) return (0); if (i == free_page) in_use_bits = free_bit; else in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1; if (i == first_page) { bit = hashp->LAST_FREED & ((hashp->BSIZE << BYTE_SHIFT) - 1); j = bit / BITS_PER_MAP; bit = bit & ~(BITS_PER_MAP - 1); } else { bit = 0; j = 0; } for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP) if (freep[j] != ALL_SET) goto found; } /* No Free Page Found */ hashp->LAST_FREED = hashp->SPARES[splitnum]; hashp->SPARES[splitnum]++; offset = hashp->SPARES[splitnum] - (splitnum ? hashp->SPARES[splitnum - 1] : 0); #define OVMSG "HASH: Out of overflow pages. Increase page size\n" if (offset > SPLITMASK) { if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; hashp->SPARES[splitnum-1]--; offset = 1; } /* Check if we need to allocate a new bitmap page */ if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) { free_page++; if (free_page >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); errno = EFBIG; return (0); } /* * This is tricky. The 1 indicates that you want the new page * allocated with 1 clear bit. Actually, you are going to * allocate 2 pages from this map. The first is going to be * the map page, the second is the overflow page we were * looking for. The init_bitmap routine automatically, sets * the first bit of itself to indicate that the bitmap itself * is in use. We would explicitly set the second bit, but * don't have to if we tell init_bitmap not to leave it clear * in the first place. */ if (__ibitmap(hashp, (int)OADDR_OF(splitnum, offset), 1, free_page)) return (0); hashp->SPARES[splitnum]++; #ifdef DEBUG2 free_bit = 2; #endif offset++; if (offset > SPLITMASK) { if (++splitnum >= NCACHED) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); errno = EFBIG; return (0); } hashp->OVFL_POINT = splitnum; hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1]; hashp->SPARES[splitnum-1]--; offset = 0; } } else { /* * Free_bit addresses the last used bit. Bump it to address * the first available bit. */ free_bit++; SETBIT(freep, free_bit); } /* Calculate address of the new overflow page */ addr = OADDR_OF(splitnum, offset); #ifdef DEBUG2 (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", addr, free_bit, free_page); #endif return (addr); found: bit = bit + first_free(freep[j]); SETBIT(freep, bit); #ifdef DEBUG2 tmp1 = bit; tmp2 = i; #endif /* * Bits are addressed starting with 0, but overflow pages are addressed * beginning at 1. Bit is a bit addressnumber, so we need to increment * it to convert it to a page number. */ bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT)); if (bit >= hashp->LAST_FREED) hashp->LAST_FREED = bit - 1; /* Calculate the split number for this page */ for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++); offset = (i ? bit - hashp->SPARES[i - 1] : bit); if (offset >= SPLITMASK) { (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1); errno = EFBIG; return (0); /* Out of overflow pages */ } addr = OADDR_OF(i, offset); #ifdef DEBUG2 (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n", addr, tmp1, tmp2); #endif /* Allocate and return the overflow page */ return (addr); } /* * Mark this overflow page as free. */ void __free_ovflpage(HTAB *hashp, BUFHEAD *obufp) { u_int16_t addr; u_int32_t *freep; int bit_address, free_page, free_bit; u_int16_t ndx; addr = obufp->addr; #ifdef DEBUG1 (void)fprintf(stderr, "Freeing %d\n", addr); #endif ndx = (((u_int16_t)addr) >> SPLITSHIFT); bit_address = (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1; if (bit_address < hashp->LAST_FREED) hashp->LAST_FREED = bit_address; free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT)); free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1); if (!(freep = hashp->mapp[free_page])) freep = fetch_bitmap(hashp, free_page); #ifdef DEBUG /* * This had better never happen. It means we tried to read a bitmap * that has already had overflow pages allocated off it, and we * failed to read it from the file. */ if (!freep) assert(0); #endif CLRBIT(freep, free_bit); #ifdef DEBUG2 (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n", obufp->addr, free_bit, free_page); #endif __reclaim_buf(hashp, obufp); } /* * Returns: * 0 success * -1 failure */ static int open_temp(HTAB *hashp) { sigset_t set, oset; int len; char *envtmp = NULL; char path[MAXPATHLEN]; if (issetugid() == 0) envtmp = getenv("TMPDIR"); len = snprintf(path, sizeof(path), "%s/_hash.XXXXXX", envtmp ? envtmp : "/tmp"); if (len < 0 || len >= (int)sizeof(path)) { errno = ENAMETOOLONG; return (-1); } /* Block signals; make sure file goes away at process exit. */ (void)sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); if ((hashp->fp = mkostemp(path, O_CLOEXEC)) != -1) (void)unlink(path); - (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL); return (hashp->fp != -1 ? 0 : -1); } /* * We have to know that the key will fit, but the last entry on the page is * an overflow pair, so we need to shift things. */ static void squeeze_key(u_int16_t *sp, const DBT *key, const DBT *val) { char *p; u_int16_t free_space, n, off, pageno; p = (char *)sp; n = sp[0]; free_space = FREESPACE(sp); off = OFFSET(sp); pageno = sp[n - 1]; off -= key->size; sp[n - 1] = off; memmove(p + off, key->data, key->size); off -= val->size; sp[n] = off; memmove(p + off, val->data, val->size); sp[0] = n + 2; sp[n + 1] = pageno; sp[n + 2] = OVFLPAGE; FREESPACE(sp) = free_space - PAIRSIZE(key, val); OFFSET(sp) = off; } static u_int32_t * fetch_bitmap(HTAB *hashp, int ndx) { if (ndx >= hashp->nmaps) return (NULL); if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL) return (NULL); if (__get_page(hashp, (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) { free(hashp->mapp[ndx]); return (NULL); } return (hashp->mapp[ndx]); } #ifdef DEBUG4 int print_chain(int addr) { BUFHEAD *bufp; short *bp, oaddr; (void)fprintf(stderr, "%d ", addr); bufp = __get_buf(hashp, addr, NULL, 0); bp = (short *)bufp->page; while (bp[0] && ((bp[bp[0]] == OVFLPAGE) || ((bp[0] > 2) && bp[2] < REAL_KEY))) { oaddr = bp[bp[0] - 1]; (void)fprintf(stderr, "%d ", (int)oaddr); bufp = __get_buf(hashp, (int)oaddr, bufp, 0); bp = (short *)bufp->page; } (void)fprintf(stderr, "\n"); } #endif Index: stable/10/lib/libc/gen/daemon.c =================================================================== --- stable/10/lib/libc/gen/daemon.c (revision 287479) +++ stable/10/lib/libc/gen/daemon.c (revision 287480) @@ -1,95 +1,95 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. * 4. 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[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" int -daemon(nochdir, noclose) - int nochdir, noclose; +daemon(int nochdir, int noclose) { struct sigaction osa, sa; int fd; pid_t newgrp; int oerrno; int osa_ok; /* A SIGHUP may be thrown when the parent exits below. */ sigemptyset(&sa.sa_mask); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; - osa_ok = _sigaction(SIGHUP, &sa, &osa); + osa_ok = __libc_sigaction(SIGHUP, &sa, &osa); switch (fork()) { case -1: return (-1); case 0: break; default: /* * A fine point: _exit(0), not exit(0), to avoid triggering * atexit(3) processing */ _exit(0); } newgrp = setsid(); oerrno = errno; if (osa_ok != -1) - _sigaction(SIGHUP, &osa, NULL); + __libc_sigaction(SIGHUP, &osa, NULL); if (newgrp == -1) { errno = oerrno; return (-1); } if (!nochdir) (void)chdir("/"); if (!noclose && (fd = _open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { (void)_dup2(fd, STDIN_FILENO); (void)_dup2(fd, STDOUT_FILENO); (void)_dup2(fd, STDERR_FILENO); if (fd > 2) (void)_close(fd); } return (0); } Index: stable/10/lib/libc/gen/posix_spawn.c =================================================================== --- stable/10/lib/libc/gen/posix_spawn.c (revision 287479) +++ stable/10/lib/libc/gen/posix_spawn.c (revision 287480) @@ -1,475 +1,478 @@ /*- * Copyright (c) 2008 Ed Schouten * 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 __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" extern char **environ; struct __posix_spawnattr { short sa_flags; pid_t sa_pgroup; struct sched_param sa_schedparam; int sa_schedpolicy; sigset_t sa_sigdefault; sigset_t sa_sigmask; }; struct __posix_spawn_file_actions { STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list; }; typedef struct __posix_spawn_file_actions_entry { STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action; int fae_fildes; union { struct { char *path; #define fae_path fae_data.open.path int oflag; #define fae_oflag fae_data.open.oflag mode_t mode; #define fae_mode fae_data.open.mode } open; struct { int newfildes; #define fae_newfildes fae_data.dup2.newfildes } dup2; } fae_data; } posix_spawn_file_actions_entry_t; /* * Spawn routines */ static int process_spawnattr(const posix_spawnattr_t sa) { struct sigaction sigact = { .sa_flags = 0, .sa_handler = SIG_DFL }; int i; /* * POSIX doesn't really describe in which order everything * should be set. We'll just set them in the order in which they * are mentioned. */ /* Set process group */ if (sa->sa_flags & POSIX_SPAWN_SETPGROUP) { if (setpgid(0, sa->sa_pgroup) != 0) return (errno); } /* Set scheduler policy */ if (sa->sa_flags & POSIX_SPAWN_SETSCHEDULER) { if (sched_setscheduler(0, sa->sa_schedpolicy, &sa->sa_schedparam) != 0) return (errno); } else if (sa->sa_flags & POSIX_SPAWN_SETSCHEDPARAM) { if (sched_setparam(0, &sa->sa_schedparam) != 0) return (errno); } /* Reset user ID's */ if (sa->sa_flags & POSIX_SPAWN_RESETIDS) { if (setegid(getgid()) != 0) return (errno); if (seteuid(getuid()) != 0) return (errno); } - /* Set signal masks/defaults */ + /* + * Set signal masks/defaults. + * Use unwrapped syscall, libthr is in undefined state after vfork(). + */ if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) { - _sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); + __sys_sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); } if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) { for (i = 1; i <= _SIG_MAXSIG; i++) { if (sigismember(&sa->sa_sigdefault, i)) - if (_sigaction(i, &sigact, NULL) != 0) + if (__sys_sigaction(i, &sigact, NULL) != 0) return (errno); } } return (0); } static int process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) { int fd; switch (fae->fae_action) { case FAE_OPEN: /* Perform an open(), make it use the right fd */ fd = _open(fae->fae_path, fae->fae_oflag, fae->fae_mode); if (fd < 0) return (errno); if (fd != fae->fae_fildes) { if (_dup2(fd, fae->fae_fildes) == -1) return (errno); if (_close(fd) != 0) { if (errno == EBADF) return (EBADF); } } if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1) return (errno); break; case FAE_DUP2: /* Perform a dup2() */ if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) return (errno); if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) return (errno); break; case FAE_CLOSE: /* Perform a close(), do not fail if already closed */ (void)_close(fae->fae_fildes); break; } return (0); } static int process_file_actions(const posix_spawn_file_actions_t fa) { posix_spawn_file_actions_entry_t *fae; int error; /* Replay all file descriptor modifications */ STAILQ_FOREACH(fae, &fa->fa_list, fae_list) { error = process_file_actions_entry(fae); if (error) return (error); } return (0); } static int do_posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *fa, const posix_spawnattr_t *sa, char * const argv[], char * const envp[], int use_env_path) { pid_t p; volatile int error = 0; p = vfork(); switch (p) { case -1: return (errno); case 0: if (sa != NULL) { error = process_spawnattr(*sa); if (error) _exit(127); } if (fa != NULL) { error = process_file_actions(*fa); if (error) _exit(127); } if (use_env_path) _execvpe(path, argv, envp != NULL ? envp : environ); else _execve(path, argv, envp != NULL ? envp : environ); error = errno; _exit(127); default: if (error != 0) _waitpid(p, NULL, WNOHANG); else if (pid != NULL) *pid = p; return (error); } } int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *fa, const posix_spawnattr_t *sa, char * const argv[], char * const envp[]) { return do_posix_spawn(pid, path, fa, sa, argv, envp, 0); } int posix_spawnp(pid_t *pid, const char *path, const posix_spawn_file_actions_t *fa, const posix_spawnattr_t *sa, char * const argv[], char * const envp[]) { return do_posix_spawn(pid, path, fa, sa, argv, envp, 1); } /* * File descriptor actions */ int posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret) { posix_spawn_file_actions_t fa; fa = malloc(sizeof(struct __posix_spawn_file_actions)); if (fa == NULL) return (-1); STAILQ_INIT(&fa->fa_list); *ret = fa; return (0); } int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa) { posix_spawn_file_actions_entry_t *fae; while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) { /* Remove file action entry from the queue */ STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); /* Deallocate file action entry */ if (fae->fae_action == FAE_OPEN) free(fae->fae_path); free(fae); } free(*fa); return (0); } int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa, int fildes, const char * __restrict path, int oflag, mode_t mode) { posix_spawn_file_actions_entry_t *fae; int error; if (fildes < 0) return (EBADF); /* Allocate object */ fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); if (fae == NULL) return (errno); /* Set values and store in queue */ fae->fae_action = FAE_OPEN; fae->fae_path = strdup(path); if (fae->fae_path == NULL) { error = errno; free(fae); return (error); } fae->fae_fildes = fildes; fae->fae_oflag = oflag; fae->fae_mode = mode; STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); return (0); } int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, int fildes, int newfildes) { posix_spawn_file_actions_entry_t *fae; if (fildes < 0 || newfildes < 0) return (EBADF); /* Allocate object */ fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); if (fae == NULL) return (errno); /* Set values and store in queue */ fae->fae_action = FAE_DUP2; fae->fae_fildes = fildes; fae->fae_newfildes = newfildes; STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); return (0); } int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, int fildes) { posix_spawn_file_actions_entry_t *fae; if (fildes < 0) return (EBADF); /* Allocate object */ fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); if (fae == NULL) return (errno); /* Set values and store in queue */ fae->fae_action = FAE_CLOSE; fae->fae_fildes = fildes; STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); return (0); } /* * Spawn attributes */ int posix_spawnattr_init(posix_spawnattr_t *ret) { posix_spawnattr_t sa; sa = calloc(1, sizeof(struct __posix_spawnattr)); if (sa == NULL) return (errno); /* Set defaults as specified by POSIX, cleared above */ *ret = sa; return (0); } int posix_spawnattr_destroy(posix_spawnattr_t *sa) { free(*sa); return (0); } int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict sa, short * __restrict flags) { *flags = (*sa)->sa_flags; return (0); } int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict sa, pid_t * __restrict pgroup) { *pgroup = (*sa)->sa_pgroup; return (0); } int posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict sa, struct sched_param * __restrict schedparam) { *schedparam = (*sa)->sa_schedparam; return (0); } int posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict sa, int * __restrict schedpolicy) { *schedpolicy = (*sa)->sa_schedpolicy; return (0); } int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict sa, sigset_t * __restrict sigdefault) { *sigdefault = (*sa)->sa_sigdefault; return (0); } int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa, sigset_t * __restrict sigmask) { *sigmask = (*sa)->sa_sigmask; return (0); } int posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags) { (*sa)->sa_flags = flags; return (0); } int posix_spawnattr_setpgroup(posix_spawnattr_t *sa, pid_t pgroup) { (*sa)->sa_pgroup = pgroup; return (0); } int posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict sa, const struct sched_param * __restrict schedparam) { (*sa)->sa_schedparam = *schedparam; return (0); } int posix_spawnattr_setschedpolicy(posix_spawnattr_t *sa, int schedpolicy) { (*sa)->sa_schedpolicy = schedpolicy; return (0); } int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict sa, const sigset_t * __restrict sigdefault) { (*sa)->sa_sigdefault = *sigdefault; return (0); } int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa, const sigset_t * __restrict sigmask) { (*sa)->sa_sigmask = *sigmask; return (0); } Index: stable/10/lib/libc/gen/readpassphrase.c =================================================================== --- stable/10/lib/libc/gen/readpassphrase.c (revision 287479) +++ stable/10/lib/libc/gen/readpassphrase.c (revision 287480) @@ -1,194 +1,195 @@ /* $OpenBSD: readpassphrase.c,v 1.24 2013/11/24 23:51:29 deraadt Exp $ */ /* * Copyright (c) 2000-2002, 2007, 2010 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" static volatile sig_atomic_t signo[NSIG]; static void handler(int); char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { ssize_t nr; int input, output, save_errno, i, need_restart; char ch, *p, *end; struct termios term, oterm; struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; struct sigaction savetstp, savettin, savettou, savepipe; /* I suppose we could alloc on demand in this case (XXX). */ if (bufsiz == 0) { errno = EINVAL; return(NULL); } restart: for (i = 0; i < NSIG; i++) signo[i] = 0; nr = -1; save_errno = 0; need_restart = 0; /* * Read and write to /dev/tty if available. If not, read from * stdin and write to stderr unless a tty is required. */ if ((flags & RPP_STDIN) || (input = output = _open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) { if (flags & RPP_REQUIRE_TTY) { errno = ENOTTY; return(NULL); } input = STDIN_FILENO; output = STDERR_FILENO; } /* * Turn off echo if possible. * If we are using a tty but are not the foreground pgrp this will * generate SIGTTOU, so do it *before* installing the signal handlers. */ if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { memcpy(&term, &oterm, sizeof(term)); if (!(flags & RPP_ECHO_ON)) term.c_lflag &= ~(ECHO | ECHONL); if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) term.c_cc[VSTATUS] = _POSIX_VDISABLE; (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); } else { memset(&term, 0, sizeof(term)); term.c_lflag |= ECHO; memset(&oterm, 0, sizeof(oterm)); oterm.c_lflag |= ECHO; } /* * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. Don't worry about * things like SIGXCPU and SIGVTALRM for now. */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* don't restart system calls */ sa.sa_handler = handler; - (void)_sigaction(SIGALRM, &sa, &savealrm); - (void)_sigaction(SIGHUP, &sa, &savehup); - (void)_sigaction(SIGINT, &sa, &saveint); - (void)_sigaction(SIGPIPE, &sa, &savepipe); - (void)_sigaction(SIGQUIT, &sa, &savequit); - (void)_sigaction(SIGTERM, &sa, &saveterm); - (void)_sigaction(SIGTSTP, &sa, &savetstp); - (void)_sigaction(SIGTTIN, &sa, &savettin); - (void)_sigaction(SIGTTOU, &sa, &savettou); + (void)__libc_sigaction(SIGALRM, &sa, &savealrm); + (void)__libc_sigaction(SIGHUP, &sa, &savehup); + (void)__libc_sigaction(SIGINT, &sa, &saveint); + (void)__libc_sigaction(SIGPIPE, &sa, &savepipe); + (void)__libc_sigaction(SIGQUIT, &sa, &savequit); + (void)__libc_sigaction(SIGTERM, &sa, &saveterm); + (void)__libc_sigaction(SIGTSTP, &sa, &savetstp); + (void)__libc_sigaction(SIGTTIN, &sa, &savettin); + (void)__libc_sigaction(SIGTTOU, &sa, &savettou); if (!(flags & RPP_STDIN)) (void)_write(output, prompt, strlen(prompt)); end = buf + bufsiz - 1; p = buf; while ((nr = _read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { if (p < end) { if ((flags & RPP_SEVENBIT)) ch &= 0x7f; if (isalpha((unsigned char)ch)) { if ((flags & RPP_FORCELOWER)) ch = (char)tolower((unsigned char)ch); if ((flags & RPP_FORCEUPPER)) ch = (char)toupper((unsigned char)ch); } *p++ = ch; } } *p = '\0'; save_errno = errno; if (!(term.c_lflag & ECHO)) (void)_write(output, "\n", 1); /* Restore old terminal settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) { while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && errno == EINTR && !signo[SIGTTOU]) continue; } - (void)_sigaction(SIGALRM, &savealrm, NULL); - (void)_sigaction(SIGHUP, &savehup, NULL); - (void)_sigaction(SIGINT, &saveint, NULL); - (void)_sigaction(SIGQUIT, &savequit, NULL); - (void)_sigaction(SIGPIPE, &savepipe, NULL); - (void)_sigaction(SIGTERM, &saveterm, NULL); - (void)_sigaction(SIGTSTP, &savetstp, NULL); - (void)_sigaction(SIGTTIN, &savettin, NULL); - (void)_sigaction(SIGTTOU, &savettou, NULL); + (void)__libc_sigaction(SIGALRM, &savealrm, NULL); + (void)__libc_sigaction(SIGHUP, &savehup, NULL); + (void)__libc_sigaction(SIGINT, &saveint, NULL); + (void)__libc_sigaction(SIGQUIT, &savequit, NULL); + (void)__libc_sigaction(SIGPIPE, &savepipe, NULL); + (void)__libc_sigaction(SIGTERM, &saveterm, NULL); + (void)__libc_sigaction(SIGTSTP, &savetstp, NULL); + (void)__libc_sigaction(SIGTTIN, &savettin, NULL); + (void)__libc_sigaction(SIGTTOU, &savettou, NULL); if (input != STDIN_FILENO) (void)_close(input); /* * If we were interrupted by a signal, resend it to ourselves * now that we have restored the signal handlers. */ for (i = 0; i < NSIG; i++) { if (signo[i]) { kill(getpid(), i); switch (i) { case SIGTSTP: case SIGTTIN: case SIGTTOU: need_restart = 1; } } } if (need_restart) goto restart; if (save_errno) errno = save_errno; return(nr == -1 ? NULL : buf); } char * getpass(const char *prompt) { static char buf[_PASSWORD_LEN + 1]; if (readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF) == NULL) buf[0] = '\0'; return(buf); } static void handler(int s) { signo[s] = 1; } Index: stable/10/lib/libc/gen/setmode.c =================================================================== --- stable/10/lib/libc/gen/setmode.c (revision 287479) +++ stable/10/lib/libc/gen/setmode.c (revision 287480) @@ -1,484 +1,485 @@ /* * 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 * Dave Borman at Cray Research, 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. * 4. 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[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #ifdef SETMODE_DEBUG #include #endif #include "un-namespace.h" +#include "libc_private.h" #define SET_LEN 6 /* initial # of bitcmd struct to malloc */ #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ typedef struct bitcmd { char cmd; char cmd2; mode_t bits; } BITCMD; #define CMD2_CLR 0x01 #define CMD2_SET 0x02 #define CMD2_GBITS 0x04 #define CMD2_OBITS 0x08 #define CMD2_UBITS 0x10 static mode_t getumask(void); static BITCMD *addcmd(BITCMD *, mode_t, mode_t, mode_t, mode_t); static void compress_mode(BITCMD *); #ifdef SETMODE_DEBUG static void dumpmode(BITCMD *); #endif /* * Given the old mode and an array of bitcmd structures, apply the operations * described in the bitcmd structures to the old mode, and return the new mode. * Note that there is no '=' command; a strict assignment is just a '-' (clear * bits) followed by a '+' (set bits). */ mode_t getmode(const void *bbox, mode_t omode) { const BITCMD *set; mode_t clrval, newmode, value; set = (const BITCMD *)bbox; newmode = omode; for (value = 0;; set++) switch(set->cmd) { /* * When copying the user, group or other bits around, we "know" * where the bits are in the mode so that we can do shifts to * copy them around. If we don't use shifts, it gets real * grundgy with lots of single bit checks and bit sets. */ case 'u': value = (newmode & S_IRWXU) >> 6; goto common; case 'g': value = (newmode & S_IRWXG) >> 3; goto common; case 'o': value = newmode & S_IRWXO; common: if (set->cmd2 & CMD2_CLR) { clrval = (set->cmd2 & CMD2_SET) ? S_IRWXO : value; if (set->cmd2 & CMD2_UBITS) newmode &= ~((clrval<<6) & set->bits); if (set->cmd2 & CMD2_GBITS) newmode &= ~((clrval<<3) & set->bits); if (set->cmd2 & CMD2_OBITS) newmode &= ~(clrval & set->bits); } if (set->cmd2 & CMD2_SET) { if (set->cmd2 & CMD2_UBITS) newmode |= (value<<6) & set->bits; if (set->cmd2 & CMD2_GBITS) newmode |= (value<<3) & set->bits; if (set->cmd2 & CMD2_OBITS) newmode |= value & set->bits; } break; case '+': newmode |= set->bits; break; case '-': newmode &= ~set->bits; break; case 'X': if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) newmode |= set->bits; break; case '\0': default: #ifdef SETMODE_DEBUG (void)printf("getmode:%04o -> %04o\n", omode, newmode); #endif return (newmode); } } #define ADDCMD(a, b, c, d) \ if (set >= endset) { \ BITCMD *newset; \ setlen += SET_LEN_INCR; \ newset = realloc(saveset, sizeof(BITCMD) * setlen); \ if (newset == NULL) \ goto out; \ set = newset + (set - saveset); \ saveset = newset; \ endset = newset + (setlen - 2); \ } \ set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d)) #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) void * setmode(const char *p) { int serrno; char op, *ep; BITCMD *set, *saveset, *endset; mode_t mask, perm, permXbits, who; long perml; int equalopdone; int setlen; if (!*p) { errno = EINVAL; return (NULL); } /* * Get a copy of the mask for the permissions that are mask relative. * Flip the bits, we want what's not set. */ mask = ~getumask(); setlen = SET_LEN + 2; if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) return (NULL); saveset = set; endset = set + (setlen - 2); /* * If an absolute number, get it and return; disallow non-octal digits * or illegal bits. */ if (isdigit((unsigned char)*p)) { errno = 0; perml = strtol(p, &ep, 8); if (*ep) { errno = EINVAL; goto out; } if (errno == ERANGE && (perml == LONG_MAX || perml == LONG_MIN)) goto out; if (perml & ~(STANDARD_BITS|S_ISTXT)) { errno = EINVAL; goto out; } perm = (mode_t)perml; ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); set->cmd = 0; return (saveset); } /* * Build list of structures to set/clear/copy bits as described by * each clause of the symbolic mode. */ equalopdone = 0; for (;;) { /* First, find out which bits might be modified. */ for (who = 0;; ++p) { switch (*p) { case 'a': who |= STANDARD_BITS; break; case 'u': who |= S_ISUID|S_IRWXU; break; case 'g': who |= S_ISGID|S_IRWXG; break; case 'o': who |= S_IRWXO; break; default: goto getop; } } getop: if ((op = *p++) != '+' && op != '-' && op != '=') { errno = EINVAL; goto out; } if (op == '=') equalopdone = 0; who &= ~S_ISTXT; for (perm = 0, permXbits = 0;; ++p) { switch (*p) { case 'r': perm |= S_IRUSR|S_IRGRP|S_IROTH; break; case 's': /* If only "other" bits ignore set-id. */ if (!who || who & ~S_IRWXO) perm |= S_ISUID|S_ISGID; break; case 't': /* If only "other" bits ignore sticky. */ if (!who || who & ~S_IRWXO) { who |= S_ISTXT; perm |= S_ISTXT; } break; case 'w': perm |= S_IWUSR|S_IWGRP|S_IWOTH; break; case 'X': permXbits = S_IXUSR|S_IXGRP|S_IXOTH; break; case 'x': perm |= S_IXUSR|S_IXGRP|S_IXOTH; break; case 'u': case 'g': case 'o': /* * When ever we hit 'u', 'g', or 'o', we have * to flush out any partial mode that we have, * and then do the copying of the mode bits. */ if (perm) { ADDCMD(op, who, perm, mask); perm = 0; } if (op == '=') equalopdone = 1; if (op == '+' && permXbits) { ADDCMD('X', who, permXbits, mask); permXbits = 0; } ADDCMD(*p, who, op, mask); break; default: /* * Add any permissions that we haven't already * done. */ if (perm || (op == '=' && !equalopdone)) { if (op == '=') equalopdone = 1; ADDCMD(op, who, perm, mask); perm = 0; } if (permXbits) { ADDCMD('X', who, permXbits, mask); permXbits = 0; } goto apply; } } apply: if (!*p) break; if (*p != ',') goto getop; ++p; } set->cmd = 0; #ifdef SETMODE_DEBUG (void)printf("Before compress_mode()\n"); dumpmode(saveset); #endif compress_mode(saveset); #ifdef SETMODE_DEBUG (void)printf("After compress_mode()\n"); dumpmode(saveset); #endif return (saveset); out: serrno = errno; free(saveset); errno = serrno; return NULL; } static mode_t getumask(void) { sigset_t sigset, sigoset; size_t len; mode_t mask; u_short smask; /* * First try requesting the umask without temporarily modifying it. * Note that this does not work if the sysctl * security.bsd.unprivileged_proc_debug is set to 0. */ len = sizeof(smask); if (sysctl((int[4]){ CTL_KERN, KERN_PROC, KERN_PROC_UMASK, getpid() }, 4, &smask, &len, NULL, 0) == 0) return (smask); /* * Since it's possible that the caller is opening files inside a signal * handler, protect them as best we can. */ sigfillset(&sigset); - (void)_sigprocmask(SIG_BLOCK, &sigset, &sigoset); + (void)__libc_sigprocmask(SIG_BLOCK, &sigset, &sigoset); (void)umask(mask = umask(0)); - (void)_sigprocmask(SIG_SETMASK, &sigoset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &sigoset, NULL); return (mask); } static BITCMD * addcmd(BITCMD *set, mode_t op, mode_t who, mode_t oparg, mode_t mask) { switch (op) { case '=': set->cmd = '-'; set->bits = who ? who : STANDARD_BITS; set++; op = '+'; /* FALLTHROUGH */ case '+': case '-': case 'X': set->cmd = op; set->bits = (who ? who : mask) & oparg; break; case 'u': case 'g': case 'o': set->cmd = op; if (who) { set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | ((who & S_IRGRP) ? CMD2_GBITS : 0) | ((who & S_IROTH) ? CMD2_OBITS : 0); set->bits = (mode_t)~0; } else { set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; set->bits = mask; } if (oparg == '+') set->cmd2 |= CMD2_SET; else if (oparg == '-') set->cmd2 |= CMD2_CLR; else if (oparg == '=') set->cmd2 |= CMD2_SET|CMD2_CLR; break; } return (set + 1); } #ifdef SETMODE_DEBUG static void dumpmode(BITCMD *set) { for (; set->cmd; ++set) (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", set->cmd2 & CMD2_CLR ? " CLR" : "", set->cmd2 & CMD2_SET ? " SET" : "", set->cmd2 & CMD2_UBITS ? " UBITS" : "", set->cmd2 & CMD2_GBITS ? " GBITS" : "", set->cmd2 & CMD2_OBITS ? " OBITS" : ""); } #endif /* * Given an array of bitcmd structures, compress by compacting consecutive * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', * 'g' and 'o' commands continue to be separate. They could probably be * compacted, but it's not worth the effort. */ static void compress_mode(BITCMD *set) { BITCMD *nset; int setbits, clrbits, Xbits, op; for (nset = set;;) { /* Copy over any 'u', 'g' and 'o' commands. */ while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { *set++ = *nset++; if (!op) return; } for (setbits = clrbits = Xbits = 0;; nset++) { if ((op = nset->cmd) == '-') { clrbits |= nset->bits; setbits &= ~nset->bits; Xbits &= ~nset->bits; } else if (op == '+') { setbits |= nset->bits; clrbits &= ~nset->bits; Xbits &= ~nset->bits; } else if (op == 'X') Xbits |= nset->bits & ~setbits; else break; } if (clrbits) { set->cmd = '-'; set->cmd2 = 0; set->bits = clrbits; set++; } if (setbits) { set->cmd = '+'; set->cmd2 = 0; set->bits = setbits; set++; } if (Xbits) { set->cmd = 'X'; set->cmd2 = 0; set->bits = Xbits; set++; } } } Index: stable/10/lib/libc/gen/siginterrupt.c =================================================================== --- stable/10/lib/libc/gen/siginterrupt.c (revision 287479) +++ stable/10/lib/libc/gen/siginterrupt.c (revision 287480) @@ -1,63 +1,62 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. 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. * 4. 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[] = "@(#)siginterrupt.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" /* * Set signal state to prevent restart of system calls * after an instance of the indicated signal. */ int -siginterrupt(sig, flag) - int sig, flag; +siginterrupt(int sig, int flag) { extern sigset_t _sigintr __hidden; struct sigaction sa; int ret; - if ((ret = _sigaction(sig, (struct sigaction *)0, &sa)) < 0) + if ((ret = __libc_sigaction(sig, (struct sigaction *)0, &sa)) < 0) return (ret); if (flag) { sigaddset(&_sigintr, sig); sa.sa_flags &= ~SA_RESTART; } else { sigdelset(&_sigintr, sig); sa.sa_flags |= SA_RESTART; } - return (_sigaction(sig, &sa, (struct sigaction *)0)); + return (__libc_sigaction(sig, &sa, (struct sigaction *)0)); } Index: stable/10/lib/libc/gen/signal.c =================================================================== --- stable/10/lib/libc/gen/signal.c (revision 287479) +++ stable/10/lib/libc/gen/signal.c (revision 287480) @@ -1,61 +1,59 @@ /* * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. 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. * 4. 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[] = "@(#)signal.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * Almost backwards compatible signal. */ #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" sigset_t _sigintr __hidden; /* shared with siginterrupt */ sig_t -signal(s, a) - int s; - sig_t a; +signal(int s, sig_t a) { struct sigaction sa, osa; sa.sa_handler = a; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (!sigismember(&_sigintr, s)) sa.sa_flags |= SA_RESTART; - if (_sigaction(s, &sa, &osa) < 0) + if (__libc_sigaction(s, &sa, &osa) < 0) return (SIG_ERR); return (osa.sa_handler); } Index: stable/10/lib/libc/gen/wordexp.c =================================================================== --- stable/10/lib/libc/gen/wordexp.c (revision 287479) +++ stable/10/lib/libc/gen/wordexp.c (revision 287480) @@ -1,345 +1,346 @@ /*- * Copyright (c) 2002 Tim J. Robbins. * 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 "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" __FBSDID("$FreeBSD$"); static int we_askshell(const char *, wordexp_t *, int); static int we_check(const char *, int); /* * wordexp -- * Perform shell word expansion on `words' and place the resulting list * of words in `we'. See wordexp(3). * * Specified by IEEE Std. 1003.1-2001. */ int wordexp(const char * __restrict words, wordexp_t * __restrict we, int flags) { int error; if (flags & WRDE_REUSE) wordfree(we); if ((flags & WRDE_APPEND) == 0) { we->we_wordc = 0; we->we_wordv = NULL; we->we_strings = NULL; we->we_nbytes = 0; } if ((error = we_check(words, flags)) != 0) { wordfree(we); return (error); } if ((error = we_askshell(words, we, flags)) != 0) { wordfree(we); return (error); } return (0); } static size_t we_read_fully(int fd, char *buffer, size_t len) { size_t done; ssize_t nread; done = 0; do { nread = _read(fd, buffer + done, len - done); if (nread == -1 && errno == EINTR) continue; if (nread <= 0) break; done += nread; } while (done != len); return done; } /* * we_askshell -- * Use the `wordexp' /bin/sh builtin function to do most of the work * in expanding the word string. This function is complicated by * memory management. */ static int we_askshell(const char *words, wordexp_t *we, int flags) { int pdes[2]; /* Pipe to child */ char bbuf[9]; /* Buffer for byte count */ char wbuf[9]; /* Buffer for word count */ long nwords, nbytes; /* Number of words, bytes from child */ long i; /* Handy integer */ size_t sofs; /* Offset into we->we_strings */ size_t vofs; /* Offset into we->we_wordv */ pid_t pid; /* Process ID of child */ pid_t wpid; /* waitpid return value */ int status; /* Child exit status */ int error; /* Our return value */ int serrno; /* errno to return */ char *np, *p; /* Handy pointers */ char *nstrings; /* Temporary for realloc() */ char **nwv; /* Temporary for realloc() */ sigset_t newsigblock, oldsigblock; const char *ifs; serrno = errno; ifs = getenv("IFS"); if (pipe2(pdes, O_CLOEXEC) < 0) return (WRDE_NOSPACE); /* XXX */ (void)sigemptyset(&newsigblock); (void)sigaddset(&newsigblock, SIGCHLD); - (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); + (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); if ((pid = fork()) < 0) { serrno = errno; _close(pdes[0]); _close(pdes[1]); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); errno = serrno; return (WRDE_NOSPACE); /* XXX */ } else if (pid == 0) { /* * We are the child; just get /bin/sh to run the wordexp * builtin on `words'. */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); if ((pdes[1] != STDOUT_FILENO ? _dup2(pdes[1], STDOUT_FILENO) : _fcntl(pdes[1], F_SETFD, 0)) < 0) _exit(1); execl(_PATH_BSHELL, "sh", flags & WRDE_UNDEF ? "-u" : "+u", "-c", "IFS=$1;eval \"$2\";eval \"wordexp $3\"", "", ifs != NULL ? ifs : " \t\n", flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", words, (char *)NULL); _exit(1); } /* * We are the parent; read the output of the shell wordexp function, * which is a 32-bit hexadecimal word count, a 32-bit hexadecimal * byte count (not including terminating null bytes), followed by * the expanded words separated by nulls. */ _close(pdes[1]); if (we_read_fully(pdes[0], wbuf, 8) != 8 || we_read_fully(pdes[0], bbuf, 8) != 8) { error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; serrno = errno; goto cleanup; } wbuf[8] = bbuf[8] = '\0'; nwords = strtol(wbuf, NULL, 16); nbytes = strtol(bbuf, NULL, 16) + nwords; /* * Allocate or reallocate (when flags & WRDE_APPEND) the word vector * and string storage buffers for the expanded words we're about to * read from the child. */ sofs = we->we_nbytes; vofs = we->we_wordc; if ((flags & (WRDE_DOOFFS|WRDE_APPEND)) == (WRDE_DOOFFS|WRDE_APPEND)) vofs += we->we_offs; we->we_wordc += nwords; we->we_nbytes += nbytes; if ((nwv = realloc(we->we_wordv, (we->we_wordc + 1 + (flags & WRDE_DOOFFS ? we->we_offs : 0)) * sizeof(char *))) == NULL) { error = WRDE_NOSPACE; goto cleanup; } we->we_wordv = nwv; if ((nstrings = realloc(we->we_strings, we->we_nbytes)) == NULL) { error = WRDE_NOSPACE; goto cleanup; } for (i = 0; i < vofs; i++) if (we->we_wordv[i] != NULL) we->we_wordv[i] += nstrings - we->we_strings; we->we_strings = nstrings; if (we_read_fully(pdes[0], we->we_strings + sofs, nbytes) != nbytes) { error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; serrno = errno; goto cleanup; } error = 0; cleanup: _close(pdes[0]); do wpid = _waitpid(pid, &status, 0); while (wpid < 0 && errno == EINTR); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); if (error != 0) { errno = serrno; return (error); } if (wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX); /* * Break the null-terminated expanded word strings out into * the vector. */ if (vofs == 0 && flags & WRDE_DOOFFS) while (vofs < we->we_offs) we->we_wordv[vofs++] = NULL; p = we->we_strings + sofs; while (nwords-- != 0) { we->we_wordv[vofs++] = p; if ((np = memchr(p, '\0', nbytes)) == NULL) return (WRDE_NOSPACE); /* XXX */ nbytes -= np - p + 1; p = np + 1; } we->we_wordv[vofs] = NULL; return (0); } /* * we_check -- * Check that the string contains none of the following unquoted * special characters: |&;<>(){} * or command substitutions when WRDE_NOCMD is set in flags. */ static int we_check(const char *words, int flags) { char c; int dquote, level, quote, squote; quote = squote = dquote = 0; while ((c = *words++) != '\0') { switch (c) { case '\\': if (squote == 0) quote ^= 1; continue; case '\'': if (quote + dquote == 0) squote ^= 1; break; case '"': if (quote + squote == 0) dquote ^= 1; break; case '`': if (quote + squote == 0 && flags & WRDE_NOCMD) return (WRDE_CMDSUB); while ((c = *words++) != '\0' && c != '`') if (c == '\\' && (c = *words++) == '\0') break; if (c == '\0') return (WRDE_SYNTAX); break; case '|': case '&': case ';': case '<': case '>': case '{': case '}': case '(': case ')': case '\n': if (quote + squote + dquote == 0) return (WRDE_BADCHAR); break; case '$': if ((c = *words++) == '\0') break; else if (quote + squote == 0 && c == '(') { if (flags & WRDE_NOCMD && *words != '(') return (WRDE_CMDSUB); level = 1; while ((c = *words++) != '\0') { if (c == '\\') { if ((c = *words++) == '\0') break; } else if (c == '(') level++; else if (c == ')' && --level == 0) break; } if (c == '\0' || level != 0) return (WRDE_SYNTAX); } else if (quote + squote == 0 && c == '{') { level = 1; while ((c = *words++) != '\0') { if (c == '\\') { if ((c = *words++) == '\0') break; } else if (c == '{') level++; else if (c == '}' && --level == 0) break; } if (c == '\0' || level != 0) return (WRDE_SYNTAX); } else --words; break; default: break; } quote = 0; } if (quote + squote + dquote != 0) return (WRDE_SYNTAX); return (0); } /* * wordfree -- * Free the result of wordexp(). See wordexp(3). * * Specified by IEEE Std. 1003.1-2001. */ void wordfree(wordexp_t *we) { if (we == NULL) return; free(we->we_wordv); free(we->we_strings); we->we_wordv = NULL; we->we_strings = NULL; we->we_nbytes = 0; we->we_wordc = 0; } Index: stable/10/lib/libc/i386/gen/setjmp.S =================================================================== --- stable/10/lib/libc/i386/gen/setjmp.S (revision 287479) +++ stable/10/lib/libc/i386/gen/setjmp.S (revision 287480) @@ -1,116 +1,98 @@ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. 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) .asciz "@(#)setjmp.s 5.1 (Berkeley) 4/23/90" #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * C library -- _setjmp, _longjmp * * longjmp(a,v) * will generate a "return(v)" from the last call to * setjmp(a) * by restoring registers from the environment 'a'. * The previous signal state is restored. */ #include "SYS.h" ENTRY(setjmp) movl 4(%esp),%ecx - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif leal 28(%ecx), %eax pushl %eax /* (sigset_t*)oset */ pushl $0 /* (sigset_t*)set */ pushl $1 /* SIG_BLOCK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%ecx movl 0(%esp),%edx movl %edx, 0(%ecx) movl %ebx, 4(%ecx) movl %esp, 8(%ecx) movl %ebp,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) fnstcw 24(%ecx) xorl %eax,%eax ret END(setjmp) .weak CNAME(longjmp) .set CNAME(longjmp),CNAME(__longjmp) ENTRY(__longjmp) movl 4(%esp),%edx - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif pushl $0 /* (sigset_t*)oset */ leal 28(%edx), %eax pushl %eax /* (sigset_t*)set */ pushl $3 /* SIG_SETMASK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%edx movl 8(%esp),%eax movl 0(%edx),%ecx movl 4(%edx),%ebx movl 8(%edx),%esp movl 12(%edx),%ebp movl 16(%edx),%esi movl 20(%edx),%edi fldcw 24(%edx) testl %eax,%eax jnz 1f incl %eax 1: movl %ecx,0(%esp) ret END(__longjmp) .section .note.GNU-stack,"",%progbits Index: stable/10/lib/libc/i386/gen/sigsetjmp.S =================================================================== --- stable/10/lib/libc/i386/gen/sigsetjmp.S (revision 287479) +++ stable/10/lib/libc/i386/gen/sigsetjmp.S (revision 287480) @@ -1,128 +1,110 @@ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * 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. * 4. 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. * * @(#)setjmp.s 5.1 (Berkeley) 4/23/90" */ #if defined(LIBC_SCCS) && !defined(lint) .text .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $" #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "SYS.h" /*- * TODO: * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp, * remove the other *jmp functions and define everything in terms * of the renamed functions. This requires compiler support for * the renamed functions (introduced in gcc-2.5.3; previous versions * only supported *jmp with 0 or 1 leading underscores). * * Restore _all_ the registers and the signal mask atomically. Can * use sigreturn() if sigreturn() works. */ ENTRY(sigsetjmp) movl 8(%esp),%eax movl 4(%esp),%ecx movl %eax,44(%ecx) testl %eax,%eax jz 2f - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif leal 28(%ecx), %eax pushl %eax /* (sigset_t*)oset */ pushl $0 /* (sigset_t*)set */ pushl $1 /* SIG_BLOCK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%ecx 2: movl 0(%esp),%edx movl %edx, 0(%ecx) movl %ebx, 4(%ecx) movl %esp, 8(%ecx) movl %ebp,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) fnstcw 24(%ecx) xorl %eax,%eax ret END(sigsetjmp) .weak CNAME(siglongjmp); .set CNAME(siglongjmp),CNAME(__siglongjmp) ENTRY(__siglongjmp) movl 4(%esp),%edx cmpl $0,44(%edx) jz 2f - PIC_PROLOGUE -#ifdef PIC - subl $12,%esp /* make the stack 16-byte aligned */ -#endif pushl $0 /* (sigset_t*)oset */ leal 28(%edx), %eax pushl %eax /* (sigset_t*)set */ pushl $3 /* SIG_SETMASK */ - call PIC_PLT(CNAME(_sigprocmask)) -#ifdef PIC - addl $24,%esp -#else + call __libc_sigprocmask addl $12,%esp -#endif - PIC_EPILOGUE movl 4(%esp),%edx 2: movl 8(%esp),%eax movl 0(%edx),%ecx movl 4(%edx),%ebx movl 8(%edx),%esp movl 12(%edx),%ebp movl 16(%edx),%esi movl 20(%edx),%edi fninit fldcw 24(%edx) testl %eax,%eax jnz 1f incl %eax 1: movl %ecx,0(%esp) ret END(__siglongjmp) .section .note.GNU-stack,"",%progbits Index: stable/10/lib/libc/include/libc_private.h =================================================================== --- stable/10/lib/libc/include/libc_private.h (revision 287479) +++ stable/10/lib/libc/include/libc_private.h (revision 287480) @@ -1,388 +1,393 @@ /* * Copyright (c) 1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. * * $FreeBSD$ * * Private definitions for libc, libc_r and libpthread. * */ #ifndef _LIBC_PRIVATE_H_ #define _LIBC_PRIVATE_H_ #include #include /* * This global flag is non-zero when a process has created one * or more threads. It is used to avoid calling locking functions * when they are not required. */ extern int __isthreaded; /* * Elf_Auxinfo *__elf_aux_vector, the pointer to the ELF aux vector * provided by kernel. Either set for us by rtld, or found at runtime * on stack for static binaries. * * Type is void to avoid polluting whole libc with ELF types. */ extern void *__elf_aux_vector; /* * libc should use libc_dlopen internally, which respects a global * flag where loading of new shared objects can be restricted. */ void *libc_dlopen(const char *, int); /* * For dynamic linker. */ void _rtld_error(const char *fmt, ...); /* * File lock contention is difficult to diagnose without knowing * where locks were set. Allow a debug library to be built which * records the source file and line number of each lock call. */ #ifdef _FLOCK_DEBUG #define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) #else #define _FLOCKFILE(x) _flockfile(x) #endif /* * Macros for locking and unlocking FILEs. These test if the * process is threaded to avoid locking when not required. */ #define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp) #define FUNLOCKFILE(fp) if (__isthreaded) _funlockfile(fp) struct _spinlock; extern struct _spinlock __stdio_thread_lock __hidden; #define STDIO_THREAD_LOCK() \ do { \ if (__isthreaded) \ _SPINLOCK(&__stdio_thread_lock); \ } while (0) #define STDIO_THREAD_UNLOCK() \ do { \ if (__isthreaded) \ _SPINUNLOCK(&__stdio_thread_lock); \ } while (0) void __libc_spinlock_stub(struct _spinlock *); void __libc_spinunlock_stub(struct _spinlock *); /* * Indexes into the pthread jump table. * * Warning! If you change this type, you must also change the threads * libraries that reference it (libc_r, libpthread). */ typedef enum { PJT_ATFORK, PJT_ATTR_DESTROY, PJT_ATTR_GETDETACHSTATE, PJT_ATTR_GETGUARDSIZE, PJT_ATTR_GETINHERITSCHED, PJT_ATTR_GETSCHEDPARAM, PJT_ATTR_GETSCHEDPOLICY, PJT_ATTR_GETSCOPE, PJT_ATTR_GETSTACKADDR, PJT_ATTR_GETSTACKSIZE, PJT_ATTR_INIT, PJT_ATTR_SETDETACHSTATE, PJT_ATTR_SETGUARDSIZE, PJT_ATTR_SETINHERITSCHED, PJT_ATTR_SETSCHEDPARAM, PJT_ATTR_SETSCHEDPOLICY, PJT_ATTR_SETSCOPE, PJT_ATTR_SETSTACKADDR, PJT_ATTR_SETSTACKSIZE, PJT_CANCEL, PJT_CLEANUP_POP, PJT_CLEANUP_PUSH, PJT_COND_BROADCAST, PJT_COND_DESTROY, PJT_COND_INIT, PJT_COND_SIGNAL, PJT_COND_TIMEDWAIT, PJT_COND_WAIT, PJT_DETACH, PJT_EQUAL, PJT_EXIT, PJT_GETSPECIFIC, PJT_JOIN, PJT_KEY_CREATE, PJT_KEY_DELETE, PJT_KILL, PJT_MAIN_NP, PJT_MUTEXATTR_DESTROY, PJT_MUTEXATTR_INIT, PJT_MUTEXATTR_SETTYPE, PJT_MUTEX_DESTROY, PJT_MUTEX_INIT, PJT_MUTEX_LOCK, PJT_MUTEX_TRYLOCK, PJT_MUTEX_UNLOCK, PJT_ONCE, PJT_RWLOCK_DESTROY, PJT_RWLOCK_INIT, PJT_RWLOCK_RDLOCK, PJT_RWLOCK_TRYRDLOCK, PJT_RWLOCK_TRYWRLOCK, PJT_RWLOCK_UNLOCK, PJT_RWLOCK_WRLOCK, PJT_SELF, PJT_SETCANCELSTATE, PJT_SETCANCELTYPE, PJT_SETSPECIFIC, PJT_SIGMASK, PJT_TESTCANCEL, PJT_CLEANUP_POP_IMP, PJT_CLEANUP_PUSH_IMP, PJT_CANCEL_ENTER, PJT_CANCEL_LEAVE, PJT_MAX } pjt_index_t; typedef int (*pthread_func_t)(void); typedef pthread_func_t pthread_func_entry_t[2]; extern pthread_func_entry_t __thr_jtable[]; void __set_error_selector(int *(*arg)(void)); int _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, void *(calloc_cb)(__size_t, __size_t)); typedef int (*interpos_func_t)(void); interpos_func_t *__libc_interposing_slot(int interposno); extern interpos_func_t __libc_interposing[] __hidden; enum { INTERPOS_accept, INTERPOS_accept4, INTERPOS_aio_suspend, INTERPOS_close, INTERPOS_connect, INTERPOS_fcntl, INTERPOS_fsync, INTERPOS_fork, INTERPOS_msync, INTERPOS_nanosleep, INTERPOS_openat, INTERPOS_poll, INTERPOS_pselect, INTERPOS_recvfrom, INTERPOS_recvmsg, INTERPOS_select, INTERPOS_sendmsg, INTERPOS_sendto, INTERPOS_setcontext, INTERPOS_sigaction, INTERPOS_sigprocmask, INTERPOS_sigsuspend, INTERPOS_sigwait, INTERPOS_sigtimedwait, INTERPOS_sigwaitinfo, INTERPOS_swapcontext, INTERPOS_system, INTERPOS_tcdrain, INTERPOS_read, INTERPOS_readv, INTERPOS_wait4, INTERPOS_write, INTERPOS_writev, INTERPOS__pthread_mutex_init_calloc_cb, INTERPOS_spinlock, INTERPOS_spinunlock, INTERPOS_kevent, INTERPOS_wait6, INTERPOS_ppoll, INTERPOS_MAX }; /* * yplib internal interfaces */ #ifdef YP int _yp_check(char **); #endif /* * Initialise TLS for static programs */ void _init_tls(void); /* * Provides pthread_once()-like functionality for both single-threaded * and multi-threaded applications. */ int _once(pthread_once_t *, void (*)(void)); /* * Set the TLS thread pointer */ void _set_tp(void *tp); /* * This is a pointer in the C run-time startup code. It is used * by getprogname() and setprogname(). */ extern const char *__progname; /* * This function is used by the threading libraries to notify malloc that a * thread is exiting. */ void _malloc_thread_cleanup(void); /* * These functions are used by the threading libraries in order to protect * malloc across fork(). */ void _malloc_prefork(void); void _malloc_postfork(void); void _malloc_first_thread(void); /* * Function to clean up streams, called from abort() and exit(). */ extern void (*__cleanup)(void) __hidden; /* * Get kern.osreldate to detect ABI revisions. Explicitly * ignores value of $OSVERSION and caches result. Prototypes * for the wrapped "new" pad-less syscalls are here for now. */ int __getosreldate(void); #include #include /* With pad */ __off_t __sys_freebsd6_lseek(int, int, __off_t, int); int __sys_freebsd6_ftruncate(int, int, __off_t); int __sys_freebsd6_truncate(const char *, int, __off_t); __ssize_t __sys_freebsd6_pread(int, void *, __size_t, int, __off_t); __ssize_t __sys_freebsd6_pwrite(int, const void *, __size_t, int, __off_t); void * __sys_freebsd6_mmap(void *, __size_t, int, int, int, int, __off_t); struct aiocb; struct fd_set; struct iovec; struct kevent; struct msghdr; struct pollfd; struct rusage; struct sigaction; struct sockaddr; struct timespec; struct timeval; struct timezone; struct __siginfo; struct __ucontext; struct __wrusage; enum idtype; int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); int __sys_accept(int, struct sockaddr *, __socklen_t *); int __sys_accept4(int, struct sockaddr *, __socklen_t *, int); int __sys_clock_gettime(__clockid_t, struct timespec *ts); int __sys_close(int); int __sys_connect(int, const struct sockaddr *, __socklen_t); int __sys_fcntl(int, int, ...); int __sys_fsync(int); __pid_t __sys_fork(void); int __sys_ftruncate(int, __off_t); int __sys_gettimeofday(struct timeval *, struct timezone *); int __sys_kevent(int, const struct kevent *, int, struct kevent *, int, const struct timespec *); __off_t __sys_lseek(int, __off_t, int); void *__sys_mmap(void *, __size_t, int, int, int, __off_t); int __sys_msync(void *, __size_t, int); int __sys_nanosleep(const struct timespec *, struct timespec *); int __sys_open(const char *, int, ...); int __sys_openat(int, const char *, int, ...); int __sys_pselect(int, struct fd_set *, struct fd_set *, struct fd_set *, const struct timespec *, const __sigset_t *); int __sys_poll(struct pollfd *, unsigned, int); int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *, const __sigset_t *); __ssize_t __sys_pread(int, void *, __size_t, __off_t); __ssize_t __sys_pwrite(int, const void *, __size_t, __off_t); __ssize_t __sys_read(int, void *, __size_t); __ssize_t __sys_readv(int, const struct iovec *, int); __ssize_t __sys_recv(int, void *, __size_t, int); __ssize_t __sys_recvfrom(int, void *, __size_t, int, struct sockaddr *, __socklen_t *); __ssize_t __sys_recvmsg(int, struct msghdr *, int); int __sys_select(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *); __ssize_t __sys_sendmsg(int, const struct msghdr *, int); __ssize_t __sys_sendto(int, const void *, __size_t, int, const struct sockaddr *, __socklen_t); int __sys_setcontext(const struct __ucontext *); int __sys_sigaction(int, const struct sigaction *, struct sigaction *); int __sys_sigprocmask(int, const __sigset_t *, __sigset_t *); int __sys_sigsuspend(const __sigset_t *); int __sys_sigtimedwait(const __sigset_t *, struct __siginfo *, const struct timespec *); int __sys_sigwait(const __sigset_t *, int *); int __sys_sigwaitinfo(const __sigset_t *, struct __siginfo *); int __sys_swapcontext(struct __ucontext *, const struct __ucontext *); int __sys_thr_kill(long, int); int __sys_thr_self(long *); int __sys_truncate(const char *, __off_t); __pid_t __sys_wait4(__pid_t, int *, int, struct rusage *); __pid_t __sys_wait6(enum idtype, __id_t, int *, int, struct __wrusage *, struct __siginfo *); __ssize_t __sys_write(int, const void *, __size_t); __ssize_t __sys_writev(int, const struct iovec *, int); +int __libc_sigaction(int, const struct sigaction *, + struct sigaction *) __hidden; +int __libc_sigprocmask(int, const __sigset_t *, __sigset_t *) + __hidden; +int __libc_sigsuspend(const __sigset_t *) __hidden; int __libc_sigwait(const __sigset_t * __restrict, int * restrict sig); int __libc_system(const char *); int __libc_tcdrain(int); int __fcntl_compat(int fd, int cmd, ...); /* execve() with PATH processing to implement posix_spawnp() */ int _execvpe(const char *, char * const *, char * const *); int _elf_aux_info(int aux, void *buf, int buflen); struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); #endif /* _LIBC_PRIVATE_H_ */ Index: stable/10/lib/libc/net/rcmd.c =================================================================== --- stable/10/lib/libc/net/rcmd.c (revision 287479) +++ stable/10/lib/libc/net/rcmd.c (revision 287480) @@ -1,761 +1,762 @@ /* * Copyright (c) 1983, 1993, 1994 * The Regents of the University of California. 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. * 4. 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[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef YP #include #include #endif #include #include "un-namespace.h" +#include "libc_private.h" extern int innetgr( const char *, const char *, const char *, const char * ); #define max(a, b) ((a > b) ? a : b) int __ivaliduser(FILE *, u_int32_t, const char *, const char *); int __ivaliduser_af(FILE *,const void *, const char *, const char *, int, int); int __ivaliduser_sa(FILE *, const struct sockaddr *, socklen_t, const char *, const char *); static int __icheckhost(const struct sockaddr *, socklen_t, const char *); char paddr[NI_MAXHOST]; int rcmd(ahost, rport, locuser, remuser, cmd, fd2p) char **ahost; u_short rport; const char *locuser, *remuser, *cmd; int *fd2p; { return rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, AF_INET); } int rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) char **ahost; u_short rport; const char *locuser, *remuser, *cmd; int *fd2p; int af; { struct addrinfo hints, *res, *ai; struct sockaddr_storage from; fd_set reads; sigset_t oldmask, newmask; pid_t pid; int s, aport, lport, timo, error; char c, *p; int refused, nres; char num[8]; static char canonnamebuf[MAXDNAME]; /* is it proper here? */ /* call rcmdsh() with specified remote shell if appropriate. */ if (!issetugid() && (p = getenv("RSH"))) { struct servent *sp = getservbyname("shell", "tcp"); if (sp && sp->s_port == rport) return (rcmdsh(ahost, rport, locuser, remuser, cmd, p)); } /* use rsh(1) if non-root and remote port is shell. */ if (geteuid()) { struct servent *sp = getservbyname("shell", "tcp"); if (sp && sp->s_port == rport) return (rcmdsh(ahost, rport, locuser, remuser, cmd, NULL)); } pid = getpid(); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; (void)snprintf(num, sizeof(num), "%d", ntohs(rport)); error = getaddrinfo(*ahost, num, &hints, &res); if (error) { fprintf(stderr, "rcmd: getaddrinfo: %s\n", gai_strerror(error)); if (error == EAI_SYSTEM) fprintf(stderr, "rcmd: getaddrinfo: %s\n", strerror(errno)); return (-1); } if (res->ai_canonname && strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) { strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf)); *ahost = canonnamebuf; } nres = 0; for (ai = res; ai; ai = ai->ai_next) nres++; ai = res; refused = 0; sigemptyset(&newmask); sigaddset(&newmask, SIGURG); - _sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); + __libc_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); for (timo = 1, lport = IPPORT_RESERVED - 1;;) { s = rresvport_af(&lport, ai->ai_family); if (s < 0) { if (errno != EAGAIN && ai->ai_next) { ai = ai->ai_next; continue; } if (errno == EAGAIN) (void)fprintf(stderr, "rcmd: socket: All ports in use\n"); else (void)fprintf(stderr, "rcmd: socket: %s\n", strerror(errno)); freeaddrinfo(res); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } _fcntl(s, F_SETOWN, pid); if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0) break; (void)_close(s); if (errno == EADDRINUSE) { lport--; continue; } if (errno == ECONNREFUSED) refused = 1; if (ai->ai_next == NULL && (!refused || timo > 16)) { (void)fprintf(stderr, "%s: %s\n", *ahost, strerror(errno)); freeaddrinfo(res); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } if (nres > 1) { int oerrno = errno; getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, sizeof(paddr), NULL, 0, NI_NUMERICHOST); (void)fprintf(stderr, "connect to address %s: ", paddr); errno = oerrno; perror(0); } if ((ai = ai->ai_next) == NULL) { /* refused && timo <= 16 */ struct timespec time_to_sleep, time_remaining; time_to_sleep.tv_sec = timo; time_to_sleep.tv_nsec = 0; (void)_nanosleep(&time_to_sleep, &time_remaining); timo *= 2; ai = res; refused = 0; } if (nres > 1) { getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, sizeof(paddr), NULL, 0, NI_NUMERICHOST); fprintf(stderr, "Trying %s...\n", paddr); } } lport--; if (fd2p == 0) { _write(s, "", 1); lport = 0; } else { int s2 = rresvport_af(&lport, ai->ai_family), s3; socklen_t len = ai->ai_addrlen; int nfds; if (s2 < 0) goto bad; _listen(s2, 1); (void)snprintf(num, sizeof(num), "%d", lport); if (_write(s, num, strlen(num)+1) != strlen(num)+1) { (void)fprintf(stderr, "rcmd: write (setting up stderr): %s\n", strerror(errno)); (void)_close(s2); goto bad; } nfds = max(s, s2)+1; if(nfds > FD_SETSIZE) { fprintf(stderr, "rcmd: too many files\n"); (void)_close(s2); goto bad; } again: FD_ZERO(&reads); FD_SET(s, &reads); FD_SET(s2, &reads); errno = 0; if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){ if (errno != 0) (void)fprintf(stderr, "rcmd: select (setting up stderr): %s\n", strerror(errno)); else (void)fprintf(stderr, "select: protocol failure in circuit setup\n"); (void)_close(s2); goto bad; } s3 = _accept(s2, (struct sockaddr *)&from, &len); switch (from.ss_family) { case AF_INET: aport = ntohs(((struct sockaddr_in *)&from)->sin_port); break; #ifdef INET6 case AF_INET6: aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port); break; #endif default: aport = 0; /* error */ break; } /* * XXX careful for ftp bounce attacks. If discovered, shut them * down and check for the real auxiliary channel to connect. */ if (aport == 20) { _close(s3); goto again; } (void)_close(s2); if (s3 < 0) { (void)fprintf(stderr, "rcmd: accept: %s\n", strerror(errno)); lport = 0; goto bad; } *fd2p = s3; if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) { (void)fprintf(stderr, "socket: protocol failure in circuit setup.\n"); goto bad2; } } (void)_write(s, locuser, strlen(locuser)+1); (void)_write(s, remuser, strlen(remuser)+1); (void)_write(s, cmd, strlen(cmd)+1); if (_read(s, &c, 1) != 1) { (void)fprintf(stderr, "rcmd: %s: %s\n", *ahost, strerror(errno)); goto bad2; } if (c != 0) { while (_read(s, &c, 1) == 1) { (void)_write(STDERR_FILENO, &c, 1); if (c == '\n') break; } goto bad2; } - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (s); bad2: if (lport) (void)_close(*fd2p); bad: (void)_close(s); - _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); + __libc_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (-1); } int rresvport(port) int *port; { return rresvport_af(port, AF_INET); } int rresvport_af(alport, family) int *alport, family; { int s; struct sockaddr_storage ss; u_short *sport; memset(&ss, 0, sizeof(ss)); ss.ss_family = family; switch (family) { case AF_INET: ((struct sockaddr *)&ss)->sa_len = sizeof(struct sockaddr_in); sport = &((struct sockaddr_in *)&ss)->sin_port; ((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY; break; #ifdef INET6 case AF_INET6: ((struct sockaddr *)&ss)->sa_len = sizeof(struct sockaddr_in6); sport = &((struct sockaddr_in6 *)&ss)->sin6_port; ((struct sockaddr_in6 *)&ss)->sin6_addr = in6addr_any; break; #endif default: errno = EAFNOSUPPORT; return -1; } s = _socket(ss.ss_family, SOCK_STREAM, 0); if (s < 0) return (-1); #if 0 /* compat_exact_traditional_rresvport_semantics */ sin.sin_port = htons((u_short)*alport); if (_bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) return (s); if (errno != EADDRINUSE) { (void)_close(s); return (-1); } #endif *sport = 0; if (bindresvport_sa(s, (struct sockaddr *)&ss) == -1) { (void)_close(s); return (-1); } *alport = (int)ntohs(*sport); return (s); } int __check_rhosts_file = 1; char *__rcmd_errstr; int ruserok(rhost, superuser, ruser, luser) const char *rhost, *ruser, *luser; int superuser; { struct addrinfo hints, *res, *r; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; /*dummy*/ error = getaddrinfo(rhost, "0", &hints, &res); if (error) return (-1); for (r = res; r; r = r->ai_next) { if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, luser) == 0) { freeaddrinfo(res); return (0); } } freeaddrinfo(res); return (-1); } /* * New .rhosts strategy: We are passed an ip address. We spin through * hosts.equiv and .rhosts looking for a match. When the .rhosts only * has ip addresses, we don't have to trust a nameserver. When it * contains hostnames, we spin through the list of addresses the nameserver * gives us and look for a match. * * Returns 0 if ok, -1 if not ok. */ int iruserok(raddr, superuser, ruser, luser) unsigned long raddr; int superuser; const char *ruser, *luser; { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(struct sockaddr_in); memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); return iruserok_sa((struct sockaddr *)&sin, sin.sin_len, superuser, ruser, luser); } /* * AF independent extension of iruserok. * * Returns 0 if ok, -1 if not ok. */ int iruserok_sa(ra, rlen, superuser, ruser, luser) const void *ra; int rlen; int superuser; const char *ruser, *luser; { char *cp; struct stat sbuf; struct passwd *pwd; FILE *hostf; uid_t uid; int first; char pbuf[MAXPATHLEN]; const struct sockaddr *raddr; struct sockaddr_storage ss; /* avoid alignment issue */ if (rlen > sizeof(ss)) return(-1); memcpy(&ss, ra, rlen); raddr = (struct sockaddr *)&ss; first = 1; hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "re"); again: if (hostf) { if (__ivaliduser_sa(hostf, raddr, rlen, luser, ruser) == 0) { (void)fclose(hostf); return (0); } (void)fclose(hostf); } if (first == 1 && (__check_rhosts_file || superuser)) { first = 0; if ((pwd = getpwnam(luser)) == NULL) return (-1); (void)strcpy(pbuf, pwd->pw_dir); (void)strcat(pbuf, "/.rhosts"); /* * Change effective uid while opening .rhosts. If root and * reading an NFS mounted file system, can't read files that * are protected read/write owner only. */ uid = geteuid(); (void)seteuid(pwd->pw_uid); hostf = fopen(pbuf, "re"); (void)seteuid(uid); if (hostf == NULL) return (-1); /* * If not a regular file, or is owned by someone other than * user or root or if writeable by anyone but the owner, quit. */ cp = NULL; if (lstat(pbuf, &sbuf) < 0) cp = ".rhosts lstat failed"; else if (!S_ISREG(sbuf.st_mode)) cp = ".rhosts not regular file"; else if (_fstat(fileno(hostf), &sbuf) < 0) cp = ".rhosts fstat failed"; else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) cp = "bad .rhosts owner"; else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) cp = ".rhosts writeable by other than owner"; /* If there were any problems, quit. */ if (cp) { __rcmd_errstr = cp; (void)fclose(hostf); return (-1); } goto again; } return (-1); } /* * XXX * Don't make static, used by lpd(8). * * Returns 0 if ok, -1 if not ok. */ int __ivaliduser(hostf, raddr, luser, ruser) FILE *hostf; u_int32_t raddr; const char *luser, *ruser; { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(struct sockaddr_in); memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, sin.sin_len, luser, ruser); } /* * Returns 0 if ok, -1 if not ok. * * XXX obsolete API. */ int __ivaliduser_af(hostf, raddr, luser, ruser, af, len) FILE *hostf; const void *raddr; const char *luser, *ruser; int af, len; { struct sockaddr *sa = NULL; struct sockaddr_in *sin = NULL; #ifdef INET6 struct sockaddr_in6 *sin6 = NULL; #endif struct sockaddr_storage ss; memset(&ss, 0, sizeof(ss)); switch (af) { case AF_INET: if (len != sizeof(sin->sin_addr)) return -1; sin = (struct sockaddr_in *)&ss; sin->sin_family = AF_INET; sin->sin_len = sizeof(struct sockaddr_in); memcpy(&sin->sin_addr, raddr, sizeof(sin->sin_addr)); break; #ifdef INET6 case AF_INET6: if (len != sizeof(sin6->sin6_addr)) return -1; /* you will lose scope info */ sin6 = (struct sockaddr_in6 *)&ss; sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); memcpy(&sin6->sin6_addr, raddr, sizeof(sin6->sin6_addr)); break; #endif default: return -1; } sa = (struct sockaddr *)&ss; return __ivaliduser_sa(hostf, sa, sa->sa_len, luser, ruser); } int __ivaliduser_sa(hostf, raddr, salen, luser, ruser) FILE *hostf; const struct sockaddr *raddr; socklen_t salen; const char *luser, *ruser; { char *user, *p; int ch; char buf[MAXHOSTNAMELEN + 128]; /* host + login */ char hname[MAXHOSTNAMELEN]; /* Presumed guilty until proven innocent. */ int userok = 0, hostok = 0; #ifdef YP char *ypdomain; if (yp_get_default_domain(&ypdomain)) ypdomain = NULL; #else #define ypdomain NULL #endif /* We need to get the damn hostname back for netgroup matching. */ if (getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0, NI_NAMEREQD) != 0) hname[0] = '\0'; while (fgets(buf, sizeof(buf), hostf)) { p = buf; /* Skip lines that are too long. */ if (strchr(p, '\n') == NULL) { while ((ch = getc(hostf)) != '\n' && ch != EOF); continue; } if (*p == '\n' || *p == '#') { /* comment... */ continue; } while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { *p = isupper((unsigned char)*p) ? tolower((unsigned char)*p) : *p; p++; } if (*p == ' ' || *p == '\t') { *p++ = '\0'; while (*p == ' ' || *p == '\t') p++; user = p; while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') p++; } else user = p; *p = '\0'; /* * Do +/- and +@/-@ checking. This looks really nasty, * but it matches SunOS's behavior so far as I can tell. */ switch(buf[0]) { case '+': if (!buf[1]) { /* '+' matches all hosts */ hostok = 1; break; } if (buf[1] == '@') /* match a host by netgroup */ hostok = hname[0] != '\0' && innetgr(&buf[2], hname, NULL, ypdomain); else /* match a host by addr */ hostok = __icheckhost(raddr, salen, (char *)&buf[1]); break; case '-': /* reject '-' hosts and all their users */ if (buf[1] == '@') { if (hname[0] == '\0' || innetgr(&buf[2], hname, NULL, ypdomain)) return(-1); } else { if (__icheckhost(raddr, salen, (char *)&buf[1])) return(-1); } break; default: /* if no '+' or '-', do a simple match */ hostok = __icheckhost(raddr, salen, buf); break; } switch(*user) { case '+': if (!*(user+1)) { /* '+' matches all users */ userok = 1; break; } if (*(user+1) == '@') /* match a user by netgroup */ userok = innetgr(user+2, NULL, ruser, ypdomain); else /* match a user by direct specification */ userok = !(strcmp(ruser, user+1)); break; case '-': /* if we matched a hostname, */ if (hostok) { /* check for user field rejections */ if (!*(user+1)) return(-1); if (*(user+1) == '@') { if (innetgr(user+2, NULL, ruser, ypdomain)) return(-1); } else { if (!strcmp(ruser, user+1)) return(-1); } } break; default: /* no rejections: try to match the user */ if (hostok) userok = !(strcmp(ruser,*user ? user : luser)); break; } if (hostok && userok) return(0); } return (-1); } /* * Returns "true" if match, 0 if no match. */ static int __icheckhost(raddr, salen, lhost) const struct sockaddr *raddr; socklen_t salen; const char *lhost; { struct sockaddr_in sin; struct sockaddr_in6 *sin6; struct addrinfo hints, *res, *r; int error; char h1[NI_MAXHOST], h2[NI_MAXHOST]; if (raddr->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *)raddr; if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(struct sockaddr_in); memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], sizeof(sin.sin_addr)); raddr = (struct sockaddr *)&sin; salen = sin.sin_len; } } h1[0] = '\0'; if (getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0, NI_NUMERICHOST) != 0) return (0); /* Resolve laddr into sockaddr */ memset(&hints, 0, sizeof(hints)); hints.ai_family = raddr->sa_family; hints.ai_socktype = SOCK_DGRAM; /*XXX dummy*/ res = NULL; error = getaddrinfo(lhost, "0", &hints, &res); if (error) return (0); for (r = res; r ; r = r->ai_next) { h2[0] = '\0'; if (getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2), NULL, 0, NI_NUMERICHOST) != 0) continue; if (strcmp(h1, h2) == 0) { freeaddrinfo(res); return (1); } } /* No match. */ freeaddrinfo(res); return (0); } Index: stable/10/lib/libc/stdio/tmpfile.c =================================================================== --- stable/10/lib/libc/stdio/tmpfile.c (revision 287479) +++ stable/10/lib/libc/stdio/tmpfile.c (revision 287480) @@ -1,92 +1,93 @@ /*- * 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. * * 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[] = "@(#)tmpfile.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include "un-namespace.h" +#include "libc_private.h" FILE * -tmpfile() +tmpfile(void) { sigset_t set, oset; FILE *fp; int fd, sverrno; #define TRAILER "tmp.XXXXXX" char *buf; const char *tmpdir; tmpdir = NULL; if (issetugid() == 0) tmpdir = getenv("TMPDIR"); if (tmpdir == NULL) tmpdir = _PATH_TMP; (void)asprintf(&buf, "%s%s%s", tmpdir, (tmpdir[strlen(tmpdir) - 1] == '/') ? "" : "/", TRAILER); if (buf == NULL) return (NULL); sigfillset(&set); - (void)_sigprocmask(SIG_BLOCK, &set, &oset); + (void)__libc_sigprocmask(SIG_BLOCK, &set, &oset); fd = mkstemp(buf); if (fd != -1) (void)unlink(buf); free(buf); - (void)_sigprocmask(SIG_SETMASK, &oset, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oset, NULL); if (fd == -1) return (NULL); if ((fp = fdopen(fd, "w+")) == NULL) { sverrno = errno; (void)_close(fd); errno = sverrno; return (NULL); } return (fp); } Index: stable/10/lib/libc/stdlib/abort.c =================================================================== --- stable/10/lib/libc/stdlib/abort.c (revision 287479) +++ stable/10/lib/libc/stdlib/abort.c (revision 287480) @@ -1,79 +1,79 @@ /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. 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[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" void abort() { struct sigaction act; /* * POSIX requires we flush stdio buffers on abort. * XXX ISO C requires that abort() be async-signal-safe. */ if (__cleanup) (*__cleanup)(); sigfillset(&act.sa_mask); /* * Don't block SIGABRT to give any handler a chance; we ignore * any errors -- ISO C doesn't allow abort to return anyway. */ sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); (void)raise(SIGABRT); /* * If SIGABRT was ignored, or caught and the handler returns, do * it again, only harder. */ act.sa_handler = SIG_DFL; act.sa_flags = 0; sigfillset(&act.sa_mask); - (void)_sigaction(SIGABRT, &act, NULL); + (void)__libc_sigaction(SIGABRT, &act, NULL); sigdelset(&act.sa_mask, SIGABRT); - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); (void)raise(SIGABRT); exit(1); } Index: stable/10/lib/libc/stdlib/system.c =================================================================== --- stable/10/lib/libc/stdlib/system.c (revision 287479) +++ stable/10/lib/libc/stdlib/system.c (revision 287480) @@ -1,108 +1,112 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. 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[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #pragma weak system int system(const char *command) { return (((int (*)(const char *)) __libc_interposing[INTERPOS_system])(command)); } int __libc_system(const char *command) { pid_t pid, savedpid; int pstat; struct sigaction ign, intact, quitact; sigset_t newsigblock, oldsigblock; if (!command) /* just checking... */ return(1); (void)sigemptyset(&newsigblock); (void)sigaddset(&newsigblock, SIGCHLD); (void)sigaddset(&newsigblock, SIGINT); (void)sigaddset(&newsigblock, SIGQUIT); - (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); + (void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); switch(pid = vfork()) { + /* + * In the child, use unwrapped syscalls. libthr is in + * undefined state after vfork(). + */ case -1: /* error */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); return (-1); case 0: /* child */ /* * Restore original signal dispositions and exec the command. */ - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + (void)__sys_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); _exit(127); } /* * If we are running means that the child has either completed * its execve, or has failed. * Block SIGINT/QUIT because sh -c handles it and wait for * it to clean up. */ memset(&ign, 0, sizeof(ign)); ign.sa_handler = SIG_IGN; (void)sigemptyset(&ign.sa_mask); - (void)_sigaction(SIGINT, &ign, &intact); - (void)_sigaction(SIGQUIT, &ign, &quitact); + (void)__libc_sigaction(SIGINT, &ign, &intact); + (void)__libc_sigaction(SIGQUIT, &ign, &quitact); savedpid = pid; do { pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); - (void)_sigaction(SIGINT, &intact, NULL); - (void)_sigaction(SIGQUIT, &quitact, NULL); - (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); - return(pid == -1 ? -1 : pstat); + (void)__libc_sigaction(SIGINT, &intact, NULL); + (void)__libc_sigaction(SIGQUIT, &quitact, NULL); + (void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + return (pid == -1 ? -1 : pstat); } __weak_reference(__libc_system, __system); __weak_reference(__libc_system, _system); Index: stable/10/lib/libc/sys/sigaction.c =================================================================== --- stable/10/lib/libc/sys/sigaction.c (revision 287479) +++ stable/10/lib/libc/sys/sigaction.c (revision 287480) @@ -1,49 +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 __FBSDID("$FreeBSD$"); #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)); } Index: stable/10/lib/libc/sys/sigprocmask.c =================================================================== --- stable/10/lib/libc/sys/sigprocmask.c (revision 287479) +++ stable/10/lib/libc/sys/sigprocmask.c (revision 287480) @@ -1,49 +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 __FBSDID("$FreeBSD$"); #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)); } Index: stable/10/lib/libc/sys/sigsuspend.c =================================================================== --- stable/10/lib/libc/sys/sigsuspend.c (revision 287479) +++ stable/10/lib/libc/sys/sigsuspend.c (revision 287480) @@ -1,49 +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 __FBSDID("$FreeBSD$"); #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)); } Index: stable/10 =================================================================== --- stable/10 (revision 287479) +++ stable/10 (revision 287480) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r287292,287300