From 7641c5eab2e15e87eafc318a09f2bd5c6f968607 Mon Sep 17 00:00:00 2001 From: Yuri Pankov Date: Fri, 2 Jun 2017 23:49:01 +0300 Subject: 8354 sync regcomp(3C) with upstream Reviewed by: Robert Mustacchi Approved by: Hans Rosenfeld --- usr/src/lib/libc/amd64/Makefile | 8 +- usr/src/lib/libc/i386/Makefile.com | 8 +- usr/src/lib/libc/port/locale/cname.h | 135 --- usr/src/lib/libc/port/locale/engine.c | 1140 -------------------- usr/src/lib/libc/port/locale/regcomp.c | 1761 ------------------------------ usr/src/lib/libc/port/locale/regerror.c | 112 -- usr/src/lib/libc/port/locale/regex2.h | 192 ---- usr/src/lib/libc/port/locale/regexec.c | 230 ---- usr/src/lib/libc/port/locale/regfree.c | 88 -- usr/src/lib/libc/port/locale/utils.h | 47 - usr/src/lib/libc/port/regex/cname.h | 135 +++ usr/src/lib/libc/port/regex/engine.c | 1135 ++++++++++++++++++++ usr/src/lib/libc/port/regex/regcomp.c | 1784 +++++++++++++++++++++++++++++++ usr/src/lib/libc/port/regex/regerror.c | 112 ++ usr/src/lib/libc/port/regex/regex2.h | 189 ++++ usr/src/lib/libc/port/regex/regexec.c | 229 ++++ usr/src/lib/libc/port/regex/regfree.c | 88 ++ usr/src/lib/libc/port/regex/utils.h | 47 + usr/src/lib/libc/sparc/Makefile.com | 8 +- usr/src/lib/libc/sparcv9/Makefile.com | 20 +- 20 files changed, 3741 insertions(+), 3727 deletions(-) delete mode 100644 usr/src/lib/libc/port/locale/cname.h delete mode 100644 usr/src/lib/libc/port/locale/engine.c delete mode 100644 usr/src/lib/libc/port/locale/regcomp.c delete mode 100644 usr/src/lib/libc/port/locale/regerror.c delete mode 100644 usr/src/lib/libc/port/locale/regex2.h delete mode 100644 usr/src/lib/libc/port/locale/regexec.c delete mode 100644 usr/src/lib/libc/port/locale/regfree.c delete mode 100644 usr/src/lib/libc/port/locale/utils.h create mode 100644 usr/src/lib/libc/port/regex/cname.h create mode 100644 usr/src/lib/libc/port/regex/engine.c create mode 100644 usr/src/lib/libc/port/regex/regcomp.c create mode 100644 usr/src/lib/libc/port/regex/regerror.c create mode 100644 usr/src/lib/libc/port/regex/regex2.h create mode 100644 usr/src/lib/libc/port/regex/regexec.c create mode 100644 usr/src/lib/libc/port/regex/regfree.c create mode 100644 usr/src/lib/libc/port/regex/utils.h (limited to 'usr/src') diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index fedf3fd8f0..e77dd63255 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -762,10 +762,6 @@ PORTLOCALE= \ nextwctype.o \ nl_langinfo.o \ none.o \ - regcomp.o \ - regfree.o \ - regerror.o \ - regexec.o \ rune.o \ runetype.o \ setlocale.o \ @@ -935,7 +931,11 @@ PORTSYS= \ PORTREGEX= \ glob.o \ regcmp.o \ + regcomp.o \ + regerror.o \ regex.o \ + regexec.o \ + regfree.o \ wordexp.o VALUES= \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 12e88fc4ae..4d24e7f176 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -808,10 +808,6 @@ PORTLOCALE= \ nextwctype.o \ nl_langinfo.o \ none.o \ - regcomp.o \ - regfree.o \ - regerror.o \ - regexec.o \ rune.o \ runetype.o \ setlocale.o \ @@ -974,7 +970,11 @@ PORTSYS= \ PORTREGEX= \ glob.o \ regcmp.o \ + regcomp.o \ + regerror.o \ regex.o \ + regexec.o \ + regfree.o \ wordexp.o PORTREGEX64= \ diff --git a/usr/src/lib/libc/port/locale/cname.h b/usr/src/lib/libc/port/locale/cname.h deleted file mode 100644 index 070683a989..0000000000 --- a/usr/src/lib/libc/port/locale/cname.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -/* character-name table */ -static struct cname { - char *name; - char code; -} cnames[] = { - {"NUL", '\0'}, - {"SOH", '\001'}, - {"STX", '\002'}, - {"ETX", '\003'}, - {"EOT", '\004'}, - {"ENQ", '\005'}, - {"ACK", '\006'}, - {"BEL", '\007'}, - {"alert", '\007'}, - {"BS", '\010'}, - {"backspace", '\b'}, - {"HT", '\011'}, - {"tab", '\t'}, - {"LF", '\012'}, - {"newline", '\n'}, - {"VT", '\013'}, - {"vertical-tab", '\v'}, - {"FF", '\014'}, - {"form-feed", '\f'}, - {"CR", '\015'}, - {"carriage-return", '\r'}, - {"SO", '\016'}, - {"SI", '\017'}, - {"DLE", '\020'}, - {"DC1", '\021'}, - {"DC2", '\022'}, - {"DC3", '\023'}, - {"DC4", '\024'}, - {"NAK", '\025'}, - {"SYN", '\026'}, - {"ETB", '\027'}, - {"CAN", '\030'}, - {"EM", '\031'}, - {"SUB", '\032'}, - {"ESC", '\033'}, - {"IS4", '\034'}, - {"FS", '\034'}, - {"IS3", '\035'}, - {"GS", '\035'}, - {"IS2", '\036'}, - {"RS", '\036'}, - {"IS1", '\037'}, - {"US", '\037'}, - {"space", ' '}, - {"exclamation-mark", '!'}, - {"quotation-mark", '"'}, - {"number-sign", '#'}, - {"dollar-sign", '$'}, - {"percent-sign", '%'}, - {"ampersand", '&'}, - {"apostrophe", '\''}, - {"left-parenthesis", '('}, - {"right-parenthesis", ')'}, - {"asterisk", '*'}, - {"plus-sign", '+'}, - {"comma", ','}, - {"hyphen", '-'}, - {"hyphen-minus", '-'}, - {"period", '.'}, - {"full-stop", '.'}, - {"slash", '/'}, - {"solidus", '/'}, - {"zero", '0'}, - {"one", '1'}, - {"two", '2'}, - {"three", '3'}, - {"four", '4'}, - {"five", '5'}, - {"six", '6'}, - {"seven", '7'}, - {"eight", '8'}, - {"nine", '9'}, - {"colon", ':'}, - {"semicolon", ';'}, - {"less-than-sign", '<'}, - {"equals-sign", '='}, - {"greater-than-sign", '>'}, - {"question-mark", '?'}, - {"commercial-at", '@'}, - {"left-square-bracket", '['}, - {"backslash", '\\'}, - {"reverse-solidus", '\\'}, - {"right-square-bracket", ']'}, - {"circumflex", '^'}, - {"circumflex-accent", '^'}, - {"underscore", '_'}, - {"low-line", '_'}, - {"grave-accent", '`'}, - {"left-brace", '{'}, - {"left-curly-bracket", '{'}, - {"vertical-line", '|'}, - {"right-brace", '}'}, - {"right-curly-bracket", '}'}, - {"tilde", '~'}, - {"DEL", '\177'}, - {NULL, 0} -}; diff --git a/usr/src/lib/libc/port/locale/engine.c b/usr/src/lib/libc/port/locale/engine.c deleted file mode 100644 index 8dab65c5b4..0000000000 --- a/usr/src/lib/libc/port/locale/engine.c +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Copyright 2012 Milan Jurik. All rights reserved. - * Copyright (c) 2016 by Delphix. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -/* - * The matching engine and friends. This file is #included by regexec.c - * after suitable #defines of a variety of macros used herein, so that - * different state representations can be used without duplicating masses - * of code. - */ - -#ifdef SNAMES -#define matcher smatcher -#define fast sfast -#define slow sslow -#define dissect sdissect -#define backref sbackref -#define step sstep -#define print sprint -#define at sat -#define match smat -#endif -#ifdef LNAMES -#define matcher lmatcher -#define fast lfast -#define slow lslow -#define dissect ldissect -#define backref lbackref -#define step lstep -#define print lprint -#define at lat -#define match lmat -#endif -#ifdef MNAMES -#define matcher mmatcher -#define fast mfast -#define slow mslow -#define dissect mdissect -#define backref mbackref -#define step mstep -#define print mprint -#define at mat -#define match mmat -#endif - -/* another structure passed up and down to avoid zillions of parameters */ -struct match { - struct re_guts *g; - int eflags; - regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ - const char *offp; /* offsets work from here */ - const char *beginp; /* start of string -- virtual NUL precedes */ - const char *endp; /* end of string -- virtual NUL here */ - const char *coldp; /* can be no match starting before here */ - const char **lastpos; /* [nplus+1] */ - STATEVARS; - states st; /* current states */ - states fresh; /* states for a fresh start */ - states tmp; /* temporary */ - states empty; /* empty set of states */ - mbstate_t mbs; /* multibyte conversion state */ -}; - -/* ========= begin header generated by ./mkh ========= */ -#ifdef __cplusplus -extern "C" { -#endif - -/* === engine.c === */ -static int matcher(struct re_guts *, const char *, size_t, regmatch_t[], int); -static const char *dissect(struct match *, const char *, const char *, - sopno, sopno); -static const char *backref(struct match *, const char *, const char *, sopno, - sopno, sopno, int); -static const char *fast(struct match *, const char *, const char *, sopno, - sopno); -static const char *slow(struct match *, const char *, const char *, sopno, - sopno); -static states step(struct re_guts *, sopno, sopno, states, wint_t, states); -#define MAX_RECURSION 100 -#define BOL (OUT-1) -#define EOL (BOL-1) -#define BOLEOL (BOL-2) -#define NOTHING (BOL-3) -#define BOW (BOL-4) -#define EOW (BOL-5) -#define BADCHAR (BOL-6) -#define NONCHAR(c) ((c) <= OUT) -#ifdef REDEBUG -static void print(struct match *, const char *, states, int, FILE *); -#endif -#ifdef REDEBUG -static void at(struct match *, const char *, const char *, const char *, - sopno, sopno); -#endif -#ifdef REDEBUG -static const char *pchar(int ch); -#endif - -#ifdef __cplusplus -} -#endif -/* ========= end header generated by ./mkh ========= */ - -#ifdef REDEBUG -#define SP(t, s, c) print(m, t, s, c, stdout) -#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) -#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } -#else -#define SP(t, s, c) /* nothing */ -#define AT(t, p1, p2, s1, s2) /* nothing */ -#define NOTE(s) /* nothing */ -#endif - -/* - * matcher - the actual matching engine - */ -static int /* 0 success, REG_NOMATCH failure */ -matcher(struct re_guts *g, - const char *string, - size_t nmatch, - regmatch_t pmatch[], - int eflags) -{ - const char *endp; - int i; - struct match mv; - struct match *m = &mv; - const char *dp; - const sopno gf = g->firststate+1; /* +1 for OEND */ - const sopno gl = g->laststate; - const char *start; - const char *stop; - /* Boyer-Moore algorithms variables */ - const char *pp; - int cj, mj; - const char *mustfirst; - const char *mustlast; - int *matchjump; - int *charjump; - - /* simplify the situation where possible */ - if (g->cflags®_NOSUB) - nmatch = 0; - - if (eflags®_STARTEND) { - start = string + pmatch[0].rm_so; - stop = string + pmatch[0].rm_eo; - } else { - start = string; - stop = start + strlen(start); - } - - if (stop < start) - return (REG_EFATAL); - - /* prescreening; this does wonders for this rather slow code */ - if (g->must != NULL) { - if (g->charjump != NULL && g->matchjump != NULL) { - mustfirst = g->must; - mustlast = g->must + g->mlen - 1; - charjump = g->charjump; - matchjump = g->matchjump; - pp = mustlast; - for (dp = start+g->mlen-1; dp < stop; ) { - /* Fast skip non-matches */ - while (dp < stop && charjump[(int)*dp]) - dp += charjump[(int)*dp]; - - if (dp >= stop) - break; - - /* Greedy matcher */ - /* - * We depend on not being used for - * for strings of length 1 - */ - while (*--dp == *--pp && pp != mustfirst) - ; - - if (*dp == *pp) - break; - - /* Jump to next possible match */ - mj = matchjump[pp - mustfirst]; - cj = charjump[(int)*dp]; - dp += (cj < mj ? mj : cj); - pp = mustlast; - } - if (pp != mustfirst) - return (REG_NOMATCH); - } else { - for (dp = start; dp < stop; dp++) - if (*dp == g->must[0] && - stop - dp >= g->mlen && - memcmp(dp, g->must, (size_t)g->mlen) == 0) - break; - if (dp == stop) /* we didn't find g->must */ - return (REG_NOMATCH); - } - } - - /* match struct setup */ - m->g = g; - m->eflags = eflags; - m->pmatch = NULL; - m->lastpos = NULL; - m->offp = string; - m->beginp = start; - m->endp = stop; - STATESETUP(m, 4); - SETUP(m->st); - SETUP(m->fresh); - SETUP(m->tmp); - SETUP(m->empty); - CLEAR(m->empty); - ZAPSTATE(&m->mbs); - - /* Adjust start according to moffset, to speed things up */ - if (g->moffset > -1) - start = ((dp - g->moffset) < start) ? start : dp - g->moffset; - - SP("mloop", m->st, *start); - - /* this loop does only one repetition except for backrefs */ - for (;;) { - endp = fast(m, start, stop, gf, gl); - if (endp == NULL) { /* a miss */ - if (m->pmatch != NULL) - free((char *)m->pmatch); - if (m->lastpos != NULL) - free((char *)m->lastpos); - STATETEARDOWN(m); - return (REG_NOMATCH); - } - if (nmatch == 0 && !g->backrefs) - break; /* no further info needed */ - - /* where? */ - assert(m->coldp != NULL); - for (;;) { - NOTE("finding start"); - endp = slow(m, m->coldp, stop, gf, gl); - if (endp != NULL) - break; - assert(m->coldp < m->endp); - m->coldp += XMBRTOWC(NULL, m->coldp, - m->endp - m->coldp, &m->mbs, 0); - } - if (nmatch == 1 && !g->backrefs) - break; /* no further info needed */ - - /* oh my, it wants the subexpressions... */ - if (m->pmatch == NULL) - m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * - sizeof (regmatch_t)); - if (m->pmatch == NULL) { - STATETEARDOWN(m); - return (REG_ESPACE); - } - for (i = 1; i <= m->g->nsub; i++) - m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; - /* NB: FreeBSD has REG_BACKR, we do not */ - if (!g->backrefs /* && !(m->eflags®_BACKR) */) { - NOTE("dissecting"); - dp = dissect(m, m->coldp, endp, gf, gl); - } else { - if (g->nplus > 0 && m->lastpos == NULL) - m->lastpos = malloc((g->nplus+1) * - sizeof (const char *)); - if (g->nplus > 0 && m->lastpos == NULL) { - free(m->pmatch); - STATETEARDOWN(m); - return (REG_ESPACE); - } - NOTE("backref dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); - } - if (dp != NULL) - break; - - /* uh-oh... we couldn't find a subexpression-level match */ - assert(g->backrefs); /* must be back references doing it */ - assert(g->nplus == 0 || m->lastpos != NULL); - for (;;) { - if (dp != NULL || endp <= m->coldp) - break; /* defeat */ - NOTE("backoff"); - endp = slow(m, m->coldp, endp-1, gf, gl); - if (endp == NULL) - break; /* defeat */ - /* try it on a shorter possibility */ -#ifndef NDEBUG - for (i = 1; i <= m->g->nsub; i++) { - assert(m->pmatch[i].rm_so == -1); - assert(m->pmatch[i].rm_eo == -1); - } -#endif - NOTE("backoff dissect"); - dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); - } - assert(dp == NULL || dp == endp); - if (dp != NULL) /* found a shorter one */ - break; - - /* despite initial appearances, there is no match here */ - NOTE("false alarm"); - /* recycle starting later */ - start = m->coldp + XMBRTOWC(NULL, m->coldp, - stop - m->coldp, &m->mbs, 0); - assert(start <= stop); - } - - /* fill in the details if requested */ - if (nmatch > 0) { - pmatch[0].rm_so = m->coldp - m->offp; - pmatch[0].rm_eo = endp - m->offp; - } - if (nmatch > 1) { - assert(m->pmatch != NULL); - for (i = 1; i < nmatch; i++) - if (i <= m->g->nsub) - pmatch[i] = m->pmatch[i]; - else { - pmatch[i].rm_so = -1; - pmatch[i].rm_eo = -1; - } - } - - if (m->pmatch != NULL) - free((char *)m->pmatch); - if (m->lastpos != NULL) - free((char *)m->lastpos); - STATETEARDOWN(m); - return (0); -} - -/* - * dissect - figure out what matched what, no back references - */ -static const char * -dissect(struct match *m, const char *start, const char *stop, sopno startst, - sopno stopst) -{ - int i; - sopno ss; /* start sop of current subRE */ - sopno es; /* end sop of current subRE */ - const char *sp; /* start of string matched by it */ - const char *stp; /* string matched by it cannot pass here */ - const char *rest; /* start of rest of string */ - const char *tail; /* string unmatched by rest of RE */ - sopno ssub; /* start sop of subsubRE */ - sopno esub; /* end sop of subsubRE */ - const char *ssp; /* start of string matched by subsubRE */ - const char *sep; /* end of string matched by subsubRE */ - const char *oldssp; /* previous ssp */ - const char *dp; - - AT("diss", start, stop, startst, stopst); - sp = start; - for (ss = startst; ss < stopst; ss = es) { - /* identify end of subRE */ - es = ss; - switch (OP(m->g->strip[es])) { - case OPLUS_: - case OQUEST_: - es += OPND(m->g->strip[es]); - break; - case OCH_: - while (OP(m->g->strip[es]) != O_CH) - es += OPND(m->g->strip[es]); - break; - } - es++; - - /* figure out what it matched */ - switch (OP(m->g->strip[ss])) { - case OEND: - assert(0); - break; - case OCHAR: - sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0); - break; - case OBOL: - case OEOL: - case OBOW: - case OEOW: - break; - case OANY: - case OANYOF: - sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0); - break; - case OBACK_: - case O_BACK: - assert(0); - break; - /* cases where length of match is hard to find */ - case OQUEST_: - stp = stop; - for (;;) { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = es - 1; - /* did innards match? */ - if (slow(m, sp, rest, ssub, esub) != NULL) { - dp = dissect(m, sp, rest, ssub, esub); - assert(dp == rest); -#if defined(__lint) - (void) dp; -#endif - } else /* no */ - assert(sp == rest); - sp = rest; - break; - case OPLUS_: - stp = stop; - for (;;) { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = es - 1; - ssp = sp; - oldssp = ssp; - for (;;) { /* find last match of innards */ - sep = slow(m, ssp, rest, ssub, esub); - if (sep == NULL || sep == ssp) - break; /* failed or matched null */ - oldssp = ssp; /* on to next try */ - ssp = sep; - } - if (sep == NULL) { - /* last successful match */ - sep = ssp; - ssp = oldssp; - } - assert(sep == rest); /* must exhaust substring */ - assert(slow(m, ssp, sep, ssub, esub) == rest); - dp = dissect(m, ssp, sep, ssub, esub); - assert(dp == sep); - sp = rest; - break; - case OCH_: - stp = stop; - for (;;) { - /* how long could this one be? */ - rest = slow(m, sp, stp, ss, es); - assert(rest != NULL); /* it did match */ - /* could the rest match the rest? */ - tail = slow(m, rest, stop, es, stopst); - if (tail == stop) - break; /* yes! */ - /* no -- try a shorter match for this one */ - stp = rest - 1; - assert(stp >= sp); /* it did work */ - } - ssub = ss + 1; - esub = ss + OPND(m->g->strip[ss]) - 1; - assert(OP(m->g->strip[esub]) == OOR1); - for (;;) { /* find first matching branch */ - if (slow(m, sp, rest, ssub, esub) == rest) - break; /* it matched all of it */ - /* that one missed, try next one */ - assert(OP(m->g->strip[esub]) == OOR1); - esub++; - assert(OP(m->g->strip[esub]) == OOR2); - ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) - esub--; - else - assert(OP(m->g->strip[esub]) == O_CH); - } - dp = dissect(m, sp, rest, ssub, esub); - assert(dp == rest); - sp = rest; - break; - case O_PLUS: - case O_QUEST: - case OOR1: - case OOR2: - case O_CH: - assert(0); - break; - case OLPAREN: - i = OPND(m->g->strip[ss]); - assert(0 < i && i <= m->g->nsub); - m->pmatch[i].rm_so = sp - m->offp; - break; - case ORPAREN: - i = OPND(m->g->strip[ss]); - assert(0 < i && i <= m->g->nsub); - m->pmatch[i].rm_eo = sp - m->offp; - break; - default: /* uh oh */ - assert(0); - break; - } - } - - assert(sp == stop); - return (sp); -} - -/* - * backref - figure out what matched what, figuring in back references - */ -static const char * -backref(struct match *m, const char *start, const char *stop, sopno startst, - sopno stopst, sopno lev, /* PLUS nesting level */ - int rec) -{ - int i; - sopno ss; /* start sop of current subRE */ - const char *sp; /* start of string matched by it */ - sopno ssub; /* start sop of subsubRE */ - sopno esub; /* end sop of subsubRE */ - const char *ssp; /* start of string matched by subsubRE */ - const char *dp; - size_t len; - int hard; - sop s; - regoff_t offsave; - cset *cs; - wint_t wc; - - AT("back", start, stop, startst, stopst); - sp = start; - - /* get as far as we can with easy stuff */ - hard = 0; - for (ss = startst; !hard && ss < stopst; ss++) - switch (OP(s = m->g->strip[ss])) { - case OCHAR: - if (sp == stop) - return (NULL); - sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); - if (wc != OPND(s)) - return (NULL); - break; - case OANY: - if (sp == stop) - return (NULL); - sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); - if (wc == BADCHAR) - return (NULL); - break; - case OANYOF: - if (sp == stop) - return (NULL); - cs = &m->g->sets[OPND(s)]; - sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); - if (wc == BADCHAR || !CHIN(cs, wc)) - return (NULL); - break; - case OBOL: - if ((sp == m->beginp && !(m->eflags®_NOTBOL)) || - (sp < m->endp && *(sp-1) == '\n' && - (m->g->cflags®_NEWLINE))) { - break; - } - return (NULL); - case OEOL: - if ((sp == m->endp && !(m->eflags®_NOTEOL)) || - (sp < m->endp && *sp == '\n' && - (m->g->cflags®_NEWLINE))) { - break; - } - return (NULL); - case OBOW: - if (((sp == m->beginp && !(m->eflags®_NOTBOL)) || - (sp < m->endp && *(sp-1) == '\n' && - (m->g->cflags®_NEWLINE)) || - (sp > m->beginp && !ISWORD(*(sp-1)))) && - (sp < m->endp && ISWORD(*sp))) { - break; - } - return (NULL); - case OEOW: - if (((sp == m->endp && !(m->eflags®_NOTEOL)) || - (sp < m->endp && *sp == '\n' && - (m->g->cflags®_NEWLINE)) || - (sp < m->endp && !ISWORD(*sp))) && - (sp > m->beginp && ISWORD(*(sp-1)))) { - break; - } - return (NULL); - case O_QUEST: - break; - case OOR1: /* matches null but needs to skip */ - ss++; - s = m->g->strip[ss]; - do { - assert(OP(s) == OOR2); - ss += OPND(s); - } while (OP(s = m->g->strip[ss]) != O_CH); - /* note that the ss++ gets us past the O_CH */ - break; - default: /* have to make a choice */ - hard = 1; - break; - } - if (!hard) { /* that was it! */ - if (sp != stop) - return (NULL); - return (sp); - } - ss--; /* adjust for the for's final increment */ - - /* the hard stuff */ - AT("hard", sp, stop, ss, stopst); - s = m->g->strip[ss]; - switch (OP(s)) { - case OBACK_: /* the vilest depths */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - if (m->pmatch[i].rm_eo == -1) - return (NULL); - assert(m->pmatch[i].rm_so != -1); - len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; - if (len == 0 && rec++ > MAX_RECURSION) - return (NULL); - assert(stop - m->beginp >= len); - if (sp > stop - len) - return (NULL); /* not enough left to match */ - ssp = m->offp + m->pmatch[i].rm_so; - if (memcmp(sp, ssp, len) != 0) - return (NULL); - while (m->g->strip[ss] != SOP(O_BACK, i)) - ss++; - return (backref(m, sp+len, stop, ss+1, stopst, lev, rec)); - case OQUEST_: /* to null or not */ - dp = backref(m, sp, stop, ss+1, stopst, lev, rec); - if (dp != NULL) - return (dp); /* not */ - return (backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec)); - case OPLUS_: - assert(m->lastpos != NULL); - assert(lev+1 <= m->g->nplus); - m->lastpos[lev+1] = sp; - return (backref(m, sp, stop, ss+1, stopst, lev+1, rec)); - case O_PLUS: - if (sp == m->lastpos[lev]) /* last pass matched null */ - return (backref(m, sp, stop, ss+1, stopst, lev-1, rec)); - /* try another pass */ - m->lastpos[lev] = sp; - dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec); - if (dp == NULL) - return (backref(m, sp, stop, ss+1, stopst, lev-1, rec)); - return (dp); - case OCH_: /* find the right one, if any */ - ssub = ss + 1; - esub = ss + OPND(s) - 1; - assert(OP(m->g->strip[esub]) == OOR1); - for (;;) { /* find first matching branch */ - dp = backref(m, sp, stop, ssub, esub, lev, rec); - if (dp != NULL) - return (dp); - /* that one missed, try next one */ - if (OP(m->g->strip[esub]) == O_CH) - return (NULL); /* there is none */ - esub++; - assert(OP(m->g->strip[esub]) == OOR2); - ssub = esub + 1; - esub += OPND(m->g->strip[esub]); - if (OP(m->g->strip[esub]) == OOR2) - esub--; - else - assert(OP(m->g->strip[esub]) == O_CH); - } - /* NOTREACHED */ - break; - case OLPAREN: /* must undo assignment if rest fails */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - offsave = m->pmatch[i].rm_so; - m->pmatch[i].rm_so = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev, rec); - if (dp != NULL) - return (dp); - m->pmatch[i].rm_so = offsave; - return (NULL); - case ORPAREN: /* must undo assignment if rest fails */ - i = OPND(s); - assert(0 < i && i <= m->g->nsub); - offsave = m->pmatch[i].rm_eo; - m->pmatch[i].rm_eo = sp - m->offp; - dp = backref(m, sp, stop, ss+1, stopst, lev, rec); - if (dp != NULL) - return (dp); - m->pmatch[i].rm_eo = offsave; - return (NULL); - default: /* uh oh */ - assert(0); - break; - } - - /* "can't happen" */ - assert(0); - return (NULL); -} - -/* - * fast - step through the string at top speed - */ -static const char * -fast(struct match *m, const char *start, const char *stop, sopno startst, - sopno stopst) -{ - states st = m->st; - states fresh = m->fresh; - states tmp = m->tmp; - const char *p = start; - wint_t c; - wint_t lastc; /* previous c */ - wint_t flagch; - int i; - const char *coldp; /* last p after which no match was underway */ - size_t clen; - - CLEAR(st); - SET1(st, startst); - SP("fast", st, *p); - st = step(m->g, startst, stopst, st, NOTHING, st); - ASSIGN(fresh, st); - SP("start", st, *p); - coldp = NULL; - if (start == m->beginp) - c = OUT; - else { - /* - * XXX Wrong if the previous character was multi-byte. - * Newline never is (in encodings supported by FreeBSD), - * so this only breaks the ISWORD tests below. - */ - c = (uch)*(start - 1); - } - for (;;) { - /* next character */ - lastc = c; - if (p == m->endp) { - clen = 0; - c = OUT; - } else - clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); - if (EQ(st, fresh)) - coldp = p; - - /* is there an EOL and/or BOL between lastc and c? */ - flagch = '\0'; - i = 0; - if ((lastc == '\n' && m->g->cflags®_NEWLINE) || - (lastc == OUT && !(m->eflags®_NOTBOL))) { - flagch = BOL; - i = m->g->nbol; - } - if ((c == '\n' && m->g->cflags®_NEWLINE) || - (c == OUT && !(m->eflags®_NOTEOL))) { - flagch = (flagch == BOL) ? BOLEOL : EOL; - i += m->g->neol; - } - if (i != 0) { - for (; i > 0; i--) - st = step(m->g, startst, stopst, st, - flagch, st); - SP("boleol", st, c); - } - - /* how about a word boundary? */ - if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && - (c != OUT && ISWORD(c))) { - flagch = BOW; - } - if ((lastc != OUT && ISWORD(lastc)) && - (flagch == EOL || (c != OUT && !ISWORD(c)))) { - flagch = EOW; - } - if (flagch == BOW || flagch == EOW) { - st = step(m->g, startst, stopst, st, flagch, st); - SP("boweow", st, c); - } - - /* are we done? */ - if (ISSET(st, stopst) || p == stop || clen > stop - p) - break; /* NOTE BREAK OUT */ - - /* no, we must deal with this character */ - ASSIGN(tmp, st); - ASSIGN(st, fresh); - assert(c != OUT); - st = step(m->g, startst, stopst, tmp, c, st); - SP("aft", st, c); - assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); - p += clen; - } - - assert(coldp != NULL); - m->coldp = coldp; - if (ISSET(st, stopst)) - return (p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0)); - else - return (NULL); -} - -/* - * slow - step through the string more deliberately - */ -static const char * -slow(struct match *m, const char *start, const char *stop, sopno startst, - sopno stopst) -{ - states st = m->st; - states empty = m->empty; - states tmp = m->tmp; - const char *p = start; - wint_t c; - wint_t lastc; /* previous c */ - wint_t flagch; - int i; - const char *matchp; /* last p at which a match ended */ - size_t clen; - - AT("slow", start, stop, startst, stopst); - CLEAR(st); - SET1(st, startst); - SP("sstart", st, *p); - st = step(m->g, startst, stopst, st, NOTHING, st); - matchp = NULL; - if (start == m->beginp) - c = OUT; - else { - /* - * XXX Wrong if the previous character was multi-byte. - * Newline never is (in encodings supported by FreeBSD), - * so this only breaks the ISWORD tests below. - */ - c = (uch)*(start - 1); - } - for (;;) { - /* next character */ - lastc = c; - if (p == m->endp) { - c = OUT; - clen = 0; - } else - clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); - - /* is there an EOL and/or BOL between lastc and c? */ - flagch = '\0'; - i = 0; - if ((lastc == '\n' && m->g->cflags®_NEWLINE) || - (lastc == OUT && !(m->eflags®_NOTBOL))) { - flagch = BOL; - i = m->g->nbol; - } - if ((c == '\n' && m->g->cflags®_NEWLINE) || - (c == OUT && !(m->eflags®_NOTEOL))) { - flagch = (flagch == BOL) ? BOLEOL : EOL; - i += m->g->neol; - } - if (i != 0) { - for (; i > 0; i--) - st = step(m->g, startst, stopst, st, - flagch, st); - SP("sboleol", st, c); - } - - /* how about a word boundary? */ - if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && - (c != OUT && ISWORD(c))) { - flagch = BOW; - } - if ((lastc != OUT && ISWORD(lastc)) && - (flagch == EOL || (c != OUT && !ISWORD(c)))) { - flagch = EOW; - } - if (flagch == BOW || flagch == EOW) { - st = step(m->g, startst, stopst, st, flagch, st); - SP("sboweow", st, c); - } - - /* are we done? */ - if (ISSET(st, stopst)) - matchp = p; - if (EQ(st, empty) || p == stop || clen > stop - p) - break; /* NOTE BREAK OUT */ - - /* no, we must deal with this character */ - ASSIGN(tmp, st); - ASSIGN(st, empty); - assert(c != OUT); - st = step(m->g, startst, stopst, tmp, c, st); - SP("saft", st, c); - assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); - p += clen; - } - - return (matchp); -} - - -/* - * step - map set of states reachable before char to set reachable after - */ -static states -step(struct re_guts *g, - sopno start, /* start state within strip */ - sopno stop, /* state after stop state within strip */ - states bef, /* states reachable before */ - wint_t ch, /* character or NONCHAR code */ - states aft) /* states already known reachable after */ -{ - cset *cs; - sop s; - sopno pc; - onestate here; /* note, macros know this name */ - sopno look; - int i; - - for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { - s = g->strip[pc]; - switch (OP(s)) { - case OEND: - assert(pc == stop-1); - break; - case OCHAR: - /* only characters can match */ - assert(!NONCHAR(ch) || ch != OPND(s)); - if (ch == OPND(s)) - FWD(aft, bef, 1); - break; - case OBOL: - if (ch == BOL || ch == BOLEOL) - FWD(aft, bef, 1); - break; - case OEOL: - if (ch == EOL || ch == BOLEOL) - FWD(aft, bef, 1); - break; - case OBOW: - if (ch == BOW) - FWD(aft, bef, 1); - break; - case OEOW: - if (ch == EOW) - FWD(aft, bef, 1); - break; - case OANY: - if (!NONCHAR(ch)) - FWD(aft, bef, 1); - break; - case OANYOF: - cs = &g->sets[OPND(s)]; - if (!NONCHAR(ch) && CHIN(cs, ch)) - FWD(aft, bef, 1); - break; - case OBACK_: /* ignored here */ - case O_BACK: - FWD(aft, aft, 1); - break; - case OPLUS_: /* forward, this is just an empty */ - FWD(aft, aft, 1); - break; - case O_PLUS: /* both forward and back */ - FWD(aft, aft, 1); - i = ISSETBACK(aft, OPND(s)); - BACK(aft, aft, OPND(s)); - if (!i && ISSETBACK(aft, OPND(s))) { - /* oho, must reconsider loop body */ - pc -= OPND(s) + 1; - INIT(here, pc); - } - break; - case OQUEST_: /* two branches, both forward */ - FWD(aft, aft, 1); - FWD(aft, aft, OPND(s)); - break; - case O_QUEST: /* just an empty */ - FWD(aft, aft, 1); - break; - case OLPAREN: /* not significant here */ - case ORPAREN: - FWD(aft, aft, 1); - break; - case OCH_: /* mark the first two branches */ - FWD(aft, aft, 1); - assert(OP(g->strip[pc+OPND(s)]) == OOR2); - FWD(aft, aft, OPND(s)); - break; - case OOR1: /* done a branch, find the O_CH */ - if (ISSTATEIN(aft, here)) { - for (look = 1; - OP(s = g->strip[pc+look]) != O_CH; - look += OPND(s)) - assert(OP(s) == OOR2); - FWD(aft, aft, look + 1); - } - break; - case OOR2: /* propagate OCH_'s marking */ - FWD(aft, aft, 1); - if (OP(g->strip[pc+OPND(s)]) != O_CH) { - assert(OP(g->strip[pc+OPND(s)]) == OOR2); - FWD(aft, aft, OPND(s)); - } - break; - case O_CH: /* just empty */ - FWD(aft, aft, 1); - break; - default: /* ooooops... */ - assert(0); - break; - } - } - - return (aft); -} - -#ifdef REDEBUG -/* - * print - print a set of states - */ -static void -print(struct match *m, const char *caption, states st, int ch, FILE *d) -{ - struct re_guts *g = m->g; - int i; - int first = 1; - - if (!(m->eflags®_TRACE)) - return; - - (void) fprintf(d, "%s", caption); - if (ch != '\0') - (void) fprintf(d, " %s", pchar(ch)); - for (i = 0; i < g->nstates; i++) - if (ISSET(st, i)) { - (void) fprintf(d, "%s%d", (first) ? "\t" : ", ", i); - first = 0; - } - (void) fprintf(d, "\n"); -} - -/* - * at - print current situation - */ -static void -at(struct match *m, const char *title, const char *start, const char *stop, - sopno startst, sopno stopst) -{ - if (!(m->eflags®_TRACE)) - return; - - (void) printf("%s %s-", title, pchar(*start)); - (void) printf("%s ", pchar(*stop)); - (void) printf("%ld-%ld\n", (long)startst, (long)stopst); -} - -#ifndef PCHARDONE -#define PCHARDONE /* never again */ -/* - * pchar - make a character printable - * - * Is this identical to regchar() over in debug.c? Well, yes. But a - * duplicate here avoids having a debugging-capable regexec.o tied to - * a matching debug.o, and this is convenient. It all disappears in - * the non-debug compilation anyway, so it doesn't matter much. - */ -static const char * -pchar(int ch) -{ - static char pbuf[10]; - - if (isprint((uch)ch) || ch == ' ') - (void) sprintf(pbuf, "%c", ch); - else - (void) sprintf(pbuf, "\\%o", ch); - return (pbuf); -} -#endif -#endif - -#undef matcher -#undef fast -#undef slow -#undef dissect -#undef backref -#undef step -#undef print -#undef at -#undef match diff --git a/usr/src/lib/libc/port/locale/regcomp.c b/usr/src/lib/libc/port/locale/regcomp.c deleted file mode 100644 index f3027d8a02..0000000000 --- a/usr/src/lib/libc/port/locale/regcomp.c +++ /dev/null @@ -1,1761 +0,0 @@ -/* - * Copyright 2013 Garrett D'Amore - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Copyright 2012 Milan Jurik. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -#include "lint.h" -#include "file64.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "runetype.h" -#include "collate.h" - -#include "utils.h" -#include "regex2.h" - -#include "cname.h" -#include "mblocal.h" - -/* - * parse structure, passed up and down to avoid global variables and - * other clumsinesses - */ -struct parse { - char *next; /* next character in RE */ - char *end; /* end of string (-> NUL normally) */ - int error; /* has an error been seen? */ - sop *strip; /* malloced strip */ - sopno ssize; /* malloced strip size (allocated) */ - sopno slen; /* malloced strip length (used) */ - int ncsalloc; /* number of csets allocated */ - struct re_guts *g; -#define NPAREN 10 /* we need to remember () 1-9 for back refs */ - sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ - sopno pend[NPAREN]; /* -> ) ([0] unused) */ -}; - -/* ========= begin header generated by ./mkh ========= */ -#ifdef __cplusplus -extern "C" { -#endif - -/* === regcomp.c === */ -static void p_ere(struct parse *p, wint_t stop); -static void p_ere_exp(struct parse *p); -static void p_str(struct parse *p); -static void p_bre(struct parse *p, wint_t end1, wint_t end2); -static int p_simp_re(struct parse *p, int starordinary); -static int p_count(struct parse *p); -static void p_bracket(struct parse *p); -static void p_b_term(struct parse *p, cset *cs); -static void p_b_cclass(struct parse *p, cset *cs); -static void p_b_eclass(struct parse *p, cset *cs); -static wint_t p_b_symbol(struct parse *p); -static wint_t p_b_coll_elem(struct parse *p, wint_t endc); -static wint_t othercase(wint_t ch); -static void bothcases(struct parse *p, wint_t ch); -static void ordinary(struct parse *p, wint_t ch); -static void nonnewline(struct parse *p); -static void repeat(struct parse *p, sopno start, int from, int to); -static int seterr(struct parse *p, int e); -static cset *allocset(struct parse *p); -static void freeset(struct parse *p, cset *cs); -static void CHadd(struct parse *p, cset *cs, wint_t ch); -static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max); -static void CHaddtype(struct parse *p, cset *cs, wctype_t wct); -static wint_t singleton(cset *cs); -static sopno dupl(struct parse *p, sopno start, sopno finish); -static void doemit(struct parse *p, sop op, size_t opnd); -static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); -static void dofwd(struct parse *p, sopno pos, sop value); -static void enlarge(struct parse *p, sopno size); -static void stripsnug(struct parse *p, struct re_guts *g); -static void findmust(struct parse *p, struct re_guts *g); -static int altoffset(sop *scan, int offset); -static void computejumps(struct parse *p, struct re_guts *g); -static void computematchjumps(struct parse *p, struct re_guts *g); -static sopno pluscount(struct parse *p, struct re_guts *g); -static wint_t wgetnext(struct parse *p); - -#ifdef __cplusplus -} -#endif -/* ========= end header generated by ./mkh ========= */ - -static char nuls[10]; /* place to point scanner in event of error */ - -/* - * macros for use with parse structure - * BEWARE: these know that the parse structure is named `p' !!! - */ -#define PEEK() (*p->next) -#define PEEK2() (*(p->next+1)) -#define MORE() (p->next < p->end) -#define MORE2() (p->next+1 < p->end) -#define SEE(c) (MORE() && PEEK() == (c)) -#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) -#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) -#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) -#define NEXT() (p->next++) -#define NEXT2() (p->next += 2) -#define NEXTn(n) (p->next += (n)) -#define GETNEXT() (*p->next++) -#define WGETNEXT() wgetnext(p) -#define SETERROR(e) ((void)seterr(p, (e))) -#define REQUIRE(co, e) ((co) || seterr(p, e)) -#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) -#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) -#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) -#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) -#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) -#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) -#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) -#define HERE() (p->slen) -#define THERE() (p->slen - 1) -#define THERETHERE() (p->slen - 2) -#define DROP(n) (p->slen -= (n)) - -#ifndef NDEBUG -static int never = 0; /* for use in asserts; shuts lint up */ -#else -#define never 0 /* some s have bugs too */ -#endif - -/* - * regcomp - interface for parser and compilation - */ -int /* 0 success, otherwise REG_something */ -regcomp(regex_t *_RESTRICT_KYWD preg, - const char *_RESTRICT_KYWD pattern, - int cflags) -{ - struct parse pa; - struct re_guts *g; - struct parse *p = &pa; - int i; - size_t len; -#ifdef REDEBUG -#define GOODFLAGS(f) (f) -#else -#define GOODFLAGS(f) ((f)&~REG_DUMP) -#endif - - /* We had REG_INVARG, but we don't have that on Solaris. */ - cflags = GOODFLAGS(cflags); - if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) - return (REG_EFATAL); - - if (cflags®_PEND) { - if (preg->re_endp < pattern) - return (REG_EFATAL); - len = preg->re_endp - pattern; - } else - len = strlen((char *)pattern); - - /* do the mallocs early so failure handling is easy */ - g = (struct re_guts *)malloc(sizeof (struct re_guts)); - if (g == NULL) - return (REG_ESPACE); - p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ - p->strip = (sop *)malloc(p->ssize * sizeof (sop)); - p->slen = 0; - if (p->strip == NULL) { - free((char *)g); - return (REG_ESPACE); - } - - /* set things up */ - p->g = g; - p->next = (char *)pattern; /* convenience; we do not modify it */ - p->end = p->next + len; - p->error = 0; - p->ncsalloc = 0; - for (i = 0; i < NPAREN; i++) { - p->pbegin[i] = 0; - p->pend[i] = 0; - } - g->sets = NULL; - g->ncsets = 0; - g->cflags = cflags; - g->iflags = 0; - g->nbol = 0; - g->neol = 0; - g->must = NULL; - g->moffset = -1; - g->charjump = NULL; - g->matchjump = NULL; - g->mlen = 0; - g->nsub = 0; - g->backrefs = 0; - - /* do it */ - EMIT(OEND, 0); - g->firststate = THERE(); - if (cflags®_EXTENDED) - p_ere(p, OUT); - else if (cflags®_NOSPEC) - p_str(p); - else - p_bre(p, OUT, OUT); - EMIT(OEND, 0); - g->laststate = THERE(); - - /* tidy up loose ends and fill things in */ - stripsnug(p, g); - findmust(p, g); - /* - * only use Boyer-Moore algorithm if the pattern is bigger - * than three characters - */ - if (g->mlen > 3) { - computejumps(p, g); - computematchjumps(p, g); - if (g->matchjump == NULL && g->charjump != NULL) { - free(g->charjump); - g->charjump = NULL; - } - } - g->nplus = pluscount(p, g); - g->magic = MAGIC2; - preg->re_nsub = g->nsub; - preg->re_g = g; - preg->re_magic = MAGIC1; -#ifndef REDEBUG - /* not debugging, so can't rely on the assert() in regexec() */ - if (g->iflags&BAD) - SETERROR(REG_EFATAL); -#endif - - /* win or lose, we're done */ - if (p->error != 0) /* lose */ - regfree(preg); - return (p->error); -} - -/* - * p_ere - ERE parser top level, concatenation and alternation - */ -static void -p_ere(struct parse *p, - wint_t stop) /* character this ERE should end at */ -{ - char c; - sopno prevback; - sopno prevfwd; - sopno conc; - int first = 1; /* is this the first alternative? */ - - for (;;) { - /* do a bunch of concatenated expressions */ - conc = HERE(); - while (MORE() && (c = PEEK()) != '|' && c != stop) - p_ere_exp(p); - /* require nonempty */ - (void) REQUIRE(HERE() != conc, REG_BADPAT); - - if (!EAT('|')) - break; /* NOTE BREAK OUT */ - - if (first) { - INSERT(OCH_, conc); /* offset is wrong */ - prevfwd = conc; - prevback = conc; - first = 0; - } - ASTERN(OOR1, prevback); - prevback = THERE(); - AHEAD(prevfwd); /* fix previous offset */ - prevfwd = HERE(); - EMIT(OOR2, 0); /* offset is very wrong */ - } - - if (!first) { /* tail-end fixups */ - AHEAD(prevfwd); - ASTERN(O_CH, prevback); - } - - assert(!MORE() || SEE(stop)); -} - -/* - * p_ere_exp - parse one subERE, an atom possibly followed by a repetition op - */ -static void -p_ere_exp(struct parse *p) -{ - char c; - wint_t wc; - sopno pos; - int count; - int count2; - sopno subno; - int wascaret = 0; - - assert(MORE()); /* caller should have ensured this */ - c = GETNEXT(); - - pos = HERE(); - switch (c) { - case '(': - (void) REQUIRE(MORE(), REG_EPAREN); - p->g->nsub++; - subno = p->g->nsub; - if (subno < NPAREN) - p->pbegin[subno] = HERE(); - EMIT(OLPAREN, subno); - if (!SEE(')')) - p_ere(p, ')'); - if (subno < NPAREN) { - p->pend[subno] = HERE(); - assert(p->pend[subno] != 0); - } - EMIT(ORPAREN, subno); - (void) MUSTEAT(')', REG_EPAREN); - break; -#ifndef POSIX_MISTAKE - case ')': /* happens only if no current unmatched ( */ - /* - * You may ask, why the ifndef? Because I didn't notice - * this until slightly too late for 1003.2, and none of the - * other 1003.2 regular-expression reviewers noticed it at - * all. So an unmatched ) is legal POSIX, at least until - * we can get it fixed. - */ - SETERROR(REG_EPAREN); - break; -#endif - case '^': - EMIT(OBOL, 0); - p->g->iflags |= USEBOL; - p->g->nbol++; - wascaret = 1; - break; - case '$': - EMIT(OEOL, 0); - p->g->iflags |= USEEOL; - p->g->neol++; - break; - case '|': - SETERROR(REG_BADPAT); - break; - case '*': - case '+': - case '?': - SETERROR(REG_BADRPT); - break; - case '.': - if (p->g->cflags®_NEWLINE) - nonnewline(p); - else - EMIT(OANY, 0); - break; - case '[': - p_bracket(p); - break; - case '\\': - (void) REQUIRE(MORE(), REG_EESCAPE); - wc = WGETNEXT(); - switch (wc) { - case '<': - EMIT(OBOW, 0); - break; - case '>': - EMIT(OEOW, 0); - break; - default: - ordinary(p, wc); - break; - } - break; - case '{': /* okay as ordinary except if digit follows */ - (void) REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); - /* FALLTHROUGH */ - default: - p->next--; - wc = WGETNEXT(); - ordinary(p, wc); - break; - } - - if (!MORE()) - return; - c = PEEK(); - /* we call { a repetition if followed by a digit */ - if (!(c == '*' || c == '+' || c == '?' || - (c == '{' && MORE2() && isdigit((uch)PEEK2())))) - return; /* no repetition, we're done */ - NEXT(); - - (void) REQUIRE(!wascaret, REG_BADRPT); - switch (c) { - case '*': /* implemented as +? */ - /* this case does not require the (y|) trick, noKLUDGE */ - INSERT(OPLUS_, pos); - ASTERN(O_PLUS, pos); - INSERT(OQUEST_, pos); - ASTERN(O_QUEST, pos); - break; - case '+': - INSERT(OPLUS_, pos); - ASTERN(O_PLUS, pos); - break; - case '?': - /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ - INSERT(OCH_, pos); /* offset slightly wrong */ - ASTERN(OOR1, pos); /* this one's right */ - AHEAD(pos); /* fix the OCH_ */ - EMIT(OOR2, 0); /* offset very wrong... */ - AHEAD(THERE()); /* ...so fix it */ - ASTERN(O_CH, THERETHERE()); - break; - case '{': - count = p_count(p); - if (EAT(',')) { - if (isdigit((uch)PEEK())) { - count2 = p_count(p); - (void) REQUIRE(count <= count2, REG_BADBR); - } else /* single number with comma */ - count2 = INFINITY; - } else /* just a single number */ - count2 = count; - repeat(p, pos, count, count2); - if (!EAT('}')) { /* error heuristics */ - while (MORE() && PEEK() != '}') - NEXT(); - (void) REQUIRE(MORE(), REG_EBRACE); - SETERROR(REG_BADBR); - } - break; - } - - if (!MORE()) - return; - c = PEEK(); - if (!(c == '*' || c == '+' || c == '?' || - (c == '{' && MORE2() && isdigit((uch)PEEK2())))) - return; - SETERROR(REG_BADRPT); -} - -/* - * p_str - string (no metacharacters) "parser" - */ -static void -p_str(struct parse *p) -{ - (void) REQUIRE(MORE(), REG_BADPAT); - while (MORE()) - ordinary(p, WGETNEXT()); -} - -/* - * p_bre - BRE parser top level, anchoring and concatenation - * Giving end1 as OUT essentially eliminates the end1/end2 check. - * - * This implementation is a bit of a kludge, in that a trailing $ is first - * taken as an ordinary character and then revised to be an anchor. - * The amount of lookahead needed to avoid this kludge is excessive. - */ -static void -p_bre(struct parse *p, - wint_t end1, /* first terminating character */ - wint_t end2) /* second terminating character */ -{ - sopno start = HERE(); - int first = 1; /* first subexpression? */ - int wasdollar = 0; - - if (EAT('^')) { - EMIT(OBOL, 0); - p->g->iflags |= USEBOL; - p->g->nbol++; - } - while (MORE() && !SEETWO(end1, end2)) { - wasdollar = p_simp_re(p, first); - first = 0; - } - if (wasdollar) { /* oops, that was a trailing anchor */ - DROP(1); - EMIT(OEOL, 0); - p->g->iflags |= USEEOL; - p->g->neol++; - } - - (void) REQUIRE(HERE() != start, REG_BADPAT); /* require nonempty */ -} - -/* - * p_simp_re - parse a simple RE, an atom possibly followed by a repetition - */ -static int /* was the simple RE an unbackslashed $? */ -p_simp_re(struct parse *p, - int starordinary) /* is a leading * an ordinary character? */ -{ - int c; - int count; - int count2; - sopno pos; - int i; - wint_t wc; - sopno subno; -#define BACKSL (1<g->cflags®_NEWLINE) - nonnewline(p); - else - EMIT(OANY, 0); - break; - case '[': - p_bracket(p); - break; - case BACKSL|'<': - EMIT(OBOW, 0); - break; - case BACKSL|'>': - EMIT(OEOW, 0); - break; - case BACKSL|'{': - SETERROR(REG_BADRPT); - break; - case BACKSL|'(': - p->g->nsub++; - subno = p->g->nsub; - if (subno < NPAREN) - p->pbegin[subno] = HERE(); - EMIT(OLPAREN, subno); - /* the MORE here is an error heuristic */ - if (MORE() && !SEETWO('\\', ')')) - p_bre(p, '\\', ')'); - if (subno < NPAREN) { - p->pend[subno] = HERE(); - assert(p->pend[subno] != 0); - } - EMIT(ORPAREN, subno); - (void) REQUIRE(EATTWO('\\', ')'), REG_EPAREN); - break; - case BACKSL|')': /* should not get here -- must be user */ - case BACKSL|'}': - SETERROR(REG_EPAREN); - break; - case BACKSL|'1': - case BACKSL|'2': - case BACKSL|'3': - case BACKSL|'4': - case BACKSL|'5': - case BACKSL|'6': - case BACKSL|'7': - case BACKSL|'8': - case BACKSL|'9': - i = (c&~BACKSL) - '0'; - assert(i < NPAREN); - if (p->pend[i] != 0) { - assert(i <= p->g->nsub); - EMIT(OBACK_, i); - assert(p->pbegin[i] != 0); - assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); - assert(OP(p->strip[p->pend[i]]) == ORPAREN); - (void) dupl(p, p->pbegin[i]+1, p->pend[i]); - EMIT(O_BACK, i); - } else - SETERROR(REG_ESUBREG); - p->g->backrefs = 1; - break; - case '*': - (void) REQUIRE(starordinary, REG_BADRPT); - /* FALLTHROUGH */ - default: - p->next--; - wc = WGETNEXT(); - ordinary(p, wc); - break; - } - - if (EAT('*')) { /* implemented as +? */ - /* this case does not require the (y|) trick, noKLUDGE */ - INSERT(OPLUS_, pos); - ASTERN(O_PLUS, pos); - INSERT(OQUEST_, pos); - ASTERN(O_QUEST, pos); - } else if (EATTWO('\\', '{')) { - count = p_count(p); - if (EAT(',')) { - if (MORE() && isdigit((uch)PEEK())) { - count2 = p_count(p); - (void) REQUIRE(count <= count2, REG_BADBR); - } else /* single number with comma */ - count2 = INFINITY; - } else /* just a single number */ - count2 = count; - repeat(p, pos, count, count2); - if (!EATTWO('\\', '}')) { /* error heuristics */ - while (MORE() && !SEETWO('\\', '}')) - NEXT(); - (void) REQUIRE(MORE(), REG_EBRACE); - SETERROR(REG_BADBR); - } - } else if (c == '$') /* $ (but not \$) ends it */ - return (1); - - return (0); -} - -/* - * p_count - parse a repetition count - */ -static int /* the value */ -p_count(struct parse *p) -{ - int count = 0; - int ndigits = 0; - - while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { - count = count*10 + (GETNEXT() - '0'); - ndigits++; - } - - (void) REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); - return (count); -} - -/* - * p_bracket - parse a bracketed character list - */ -static void -p_bracket(struct parse *p) -{ - cset *cs; - wint_t ch; - - /* Dept of Truly Sickening Special-Case Kludges */ - if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { - EMIT(OBOW, 0); - NEXTn(6); - return; - } - if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { - EMIT(OEOW, 0); - NEXTn(6); - return; - } - - if ((cs = allocset(p)) == NULL) - return; - - if (p->g->cflags®_ICASE) - cs->icase = 1; - if (EAT('^')) - cs->invert = 1; - if (EAT(']')) - CHadd(p, cs, ']'); - else if (EAT('-')) - CHadd(p, cs, '-'); - while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) - p_b_term(p, cs); - if (EAT('-')) - CHadd(p, cs, '-'); - (void) MUSTEAT(']', REG_EBRACK); - - if (p->error != 0) /* don't mess things up further */ - return; - - if (cs->invert && p->g->cflags®_NEWLINE) - cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); - - if ((ch = singleton(cs)) != OUT) { /* optimize singleton sets */ - ordinary(p, ch); - freeset(p, cs); - } else - EMIT(OANYOF, (int)(cs - p->g->sets)); -} - -/* - * p_b_term - parse one term of a bracketed character list - */ -static void -p_b_term(struct parse *p, cset *cs) -{ - char c; - wint_t start, finish; - wint_t i; - locale_t loc = uselocale(NULL); - - /* classify what we've got */ - switch ((MORE()) ? PEEK() : '\0') { - case '[': - c = (MORE2()) ? PEEK2() : '\0'; - break; - case '-': - SETERROR(REG_ERANGE); - return; /* NOTE RETURN */ - default: - c = '\0'; - break; - } - - switch (c) { - case ':': /* character class */ - NEXT2(); - (void) REQUIRE(MORE(), REG_EBRACK); - c = PEEK(); - (void) REQUIRE(c != '-' && c != ']', REG_ECTYPE); - p_b_cclass(p, cs); - (void) REQUIRE(MORE(), REG_EBRACK); - (void) REQUIRE(EATTWO(':', ']'), REG_ECTYPE); - break; - case '=': /* equivalence class */ - NEXT2(); - (void) REQUIRE(MORE(), REG_EBRACK); - c = PEEK(); - (void) REQUIRE(c != '-' && c != ']', REG_ECOLLATE); - p_b_eclass(p, cs); - (void) REQUIRE(MORE(), REG_EBRACK); - (void) REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); - break; - default: /* symbol, ordinary character, or range */ - start = p_b_symbol(p); - if (SEE('-') && MORE2() && PEEK2() != ']') { - /* range */ - NEXT(); - if (EAT('-')) - finish = '-'; - else - finish = p_b_symbol(p); - } else - finish = start; - if (start == finish) - CHadd(p, cs, start); - else { - if (loc->collate->lc_is_posix) { - (void) REQUIRE((uch)start <= (uch)finish, - REG_ERANGE); - CHaddrange(p, cs, start, finish); - } else { - (void) REQUIRE(_collate_range_cmp(start, - finish, loc) <= 0, REG_ERANGE); - for (i = 0; i <= UCHAR_MAX; i++) { - if (_collate_range_cmp(start, i, loc) - <= 0 && - _collate_range_cmp(i, finish, loc) - <= 0) - CHadd(p, cs, i); - } - } - } - break; - } -} - -/* - * p_b_cclass - parse a character-class name and deal with it - */ -static void -p_b_cclass(struct parse *p, cset *cs) -{ - char *sp = p->next; - size_t len; - wctype_t wct; - char clname[16]; - - while (MORE() && isalpha((uch)PEEK())) - NEXT(); - len = p->next - sp; - if (len >= sizeof (clname) - 1) { - SETERROR(REG_ECTYPE); - return; - } - (void) memcpy(clname, sp, len); - clname[len] = '\0'; - if ((wct = wctype(clname)) == 0) { - SETERROR(REG_ECTYPE); - return; - } - CHaddtype(p, cs, wct); -} - -/* - * p_b_eclass - parse an equivalence-class name and deal with it - * - * This implementation is incomplete. xxx - */ -static void -p_b_eclass(struct parse *p, cset *cs) -{ - wint_t c; - - c = p_b_coll_elem(p, '='); - CHadd(p, cs, c); -} - -/* - * p_b_symbol - parse a character or [..]ed multicharacter collating symbol - */ -static wint_t /* value of symbol */ -p_b_symbol(struct parse *p) -{ - wint_t value; - - (void) REQUIRE(MORE(), REG_EBRACK); - if (!EATTWO('[', '.')) - return (WGETNEXT()); - - /* collating symbol */ - value = p_b_coll_elem(p, '.'); - (void) REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); - return (value); -} - -/* - * p_b_coll_elem - parse a collating-element name and look it up - */ -static wint_t /* value of collating element */ -p_b_coll_elem(struct parse *p, - wint_t endc) /* name ended by endc,']' */ -{ - char *sp = p->next; - struct cname *cp; - int len; - mbstate_t mbs; - wchar_t wc; - size_t clen; - - while (MORE() && !SEETWO(endc, ']')) - NEXT(); - if (!MORE()) { - SETERROR(REG_EBRACK); - return (0); - } - len = p->next - sp; - for (cp = cnames; cp->name != NULL; cp++) - if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') - return (cp->code); /* known name */ - (void) memset(&mbs, 0, sizeof (mbs)); - if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) - return (wc); /* single character */ - else if (clen == (size_t)-1 || clen == (size_t)-2) - SETERROR(REG_ECHAR); - else - SETERROR(REG_ECOLLATE); /* neither */ - return (0); -} - -/* - * othercase - return the case counterpart of an alphabetic - */ -static wint_t /* if no counterpart, return ch */ -othercase(wint_t ch) -{ - assert(iswalpha(ch)); - if (iswupper(ch)) - return (towlower(ch)); - else if (iswlower(ch)) - return (towupper(ch)); - else /* peculiar, but could happen */ - return (ch); -} - -/* - * bothcases - emit a dualcase version of a two-case character - * - * Boy, is this implementation ever a kludge... - */ -static void -bothcases(struct parse *p, wint_t ch) -{ - char *oldnext = p->next; - char *oldend = p->end; - char bracket[3 + MB_LEN_MAX]; - size_t n; - mbstate_t mbs; - - assert(othercase(ch) != ch); /* p_bracket() would recurse */ - p->next = bracket; - (void) memset(&mbs, 0, sizeof (mbs)); - n = wcrtomb(bracket, ch, &mbs); - assert(n != (size_t)-1); - bracket[n] = ']'; - bracket[n + 1] = '\0'; - p->end = bracket+n+1; - p_bracket(p); - assert(p->next == p->end); - p->next = oldnext; - p->end = oldend; -} - -/* - * ordinary - emit an ordinary character - */ -static void -ordinary(struct parse *p, wint_t ch) -{ - cset *cs; - - if ((p->g->cflags®_ICASE) && iswalpha(ch) && othercase(ch) != ch) - bothcases(p, ch); - else if ((ch & OPDMASK) == ch) - EMIT(OCHAR, ch); - else { - /* - * Kludge: character is too big to fit into an OCHAR operand. - * Emit a singleton set. - */ - if ((cs = allocset(p)) == NULL) - return; - CHadd(p, cs, ch); - EMIT(OANYOF, (int)(cs - p->g->sets)); - } -} - -/* - * nonnewline - emit REG_NEWLINE version of OANY - * - * Boy, is this implementation ever a kludge... - */ -static void -nonnewline(struct parse *p) -{ - char *oldnext = p->next; - char *oldend = p->end; - char bracket[4]; - - p->next = bracket; - p->end = bracket+3; - bracket[0] = '^'; - bracket[1] = '\n'; - bracket[2] = ']'; - bracket[3] = '\0'; - p_bracket(p); - assert(p->next == bracket+3); - p->next = oldnext; - p->end = oldend; -} - -/* - * repeat - generate code for a bounded repetition, recursively if needed - */ -static void -repeat(struct parse *p, - sopno start, /* operand from here to end of strip */ - int from, /* repeated from this number */ - int to) /* to this number of times (maybe INFINITY) */ -{ - sopno finish = HERE(); -#define N 2 -#define INF 3 -#define REP(f, t) ((f)*8 + (t)) -#define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) - sopno copy; - - if (p->error != 0) /* head off possible runaway recursion */ - return; - - assert(from <= to); - - switch (REP(MAP(from), MAP(to))) { - case REP(0, 0): /* must be user doing this */ - DROP(finish-start); /* drop the operand */ - break; - case REP(0, 1): /* as x{1,1}? */ - case REP(0, N): /* as x{1,n}? */ - case REP(0, INF): /* as x{1,}? */ - /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ - INSERT(OCH_, start); /* offset is wrong... */ - repeat(p, start+1, 1, to); - ASTERN(OOR1, start); - AHEAD(start); /* ... fix it */ - EMIT(OOR2, 0); - AHEAD(THERE()); - ASTERN(O_CH, THERETHERE()); - break; - case REP(1, 1): /* trivial case */ - /* done */ - break; - case REP(1, N): /* as x?x{1,n-1} */ - /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ - INSERT(OCH_, start); - ASTERN(OOR1, start); - AHEAD(start); - EMIT(OOR2, 0); /* offset very wrong... */ - AHEAD(THERE()); /* ...so fix it */ - ASTERN(O_CH, THERETHERE()); - copy = dupl(p, start+1, finish+1); - assert(copy == finish+4); - repeat(p, copy, 1, to-1); - break; - case REP(1, INF): /* as x+ */ - INSERT(OPLUS_, start); - ASTERN(O_PLUS, start); - break; - case REP(N, N): /* as xx{m-1,n-1} */ - copy = dupl(p, start, finish); - repeat(p, copy, from-1, to-1); - break; - case REP(N, INF): /* as xx{n-1,INF} */ - copy = dupl(p, start, finish); - repeat(p, copy, from-1, to); - break; - default: /* "can't happen" */ - SETERROR(REG_EFATAL); /* just in case */ - break; - } -} - -/* - * wgetnext - helper function for WGETNEXT() macro. Gets the next wide - * character from the parse struct, signals a REG_ILLSEQ error if the - * character can't be converted. Returns the number of bytes consumed. - */ -static wint_t -wgetnext(struct parse *p) -{ - mbstate_t mbs; - wchar_t wc; - size_t n; - - (void) memset(&mbs, 0, sizeof (mbs)); - n = mbrtowc(&wc, p->next, p->end - p->next, &mbs); - if (n == (size_t)-1 || n == (size_t)-2) { - SETERROR(REG_ECHAR); - return (0); - } - if (n == 0) - n = 1; - p->next += n; - return (wc); -} - -/* - * seterr - set an error condition - */ -static int /* useless but makes type checking happy */ -seterr(struct parse *p, int e) -{ - if (p->error == 0) /* keep earliest error condition */ - p->error = e; - p->next = nuls; /* try to bring things to a halt */ - p->end = nuls; - return (0); /* make the return value well-defined */ -} - -/* - * allocset - allocate a set of characters for [] - */ -static cset * -allocset(struct parse *p) -{ - cset *cs, *ncs; - - ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof (*ncs)); - if (ncs == NULL) { - SETERROR(REG_ESPACE); - return (NULL); - } - p->g->sets = ncs; - cs = &p->g->sets[p->g->ncsets++]; - (void) memset(cs, 0, sizeof (*cs)); - - return (cs); -} - -/* - * freeset - free a now-unused set - */ -static void -freeset(struct parse *p, cset *cs) -{ - cset *top = &p->g->sets[p->g->ncsets]; - - free(cs->wides); - free(cs->ranges); - free(cs->types); - (void) memset(cs, 0, sizeof (*cs)); - if (cs == top-1) /* recover only the easy case */ - p->g->ncsets--; -} - -/* - * singleton - Determine whether a set contains only one character, - * returning it if so, otherwise returning OUT. - */ -static wint_t -singleton(cset *cs) -{ - wint_t i, s, n; - - for (i = n = 0; i < NC; i++) - if (CHIN(cs, i)) { - n++; - s = i; - } - if (n == 1) - return (s); - if (cs->nwides == 1 && cs->nranges == 0 && cs->ntypes == 0 && - cs->icase == 0) - return (cs->wides[0]); - /* Don't bother handling the other cases. */ - return (OUT); -} - -/* - * CHadd - add character to character set. - */ -static void -CHadd(struct parse *p, cset *cs, wint_t ch) -{ - wint_t nch, *newwides; - assert(ch >= 0); - if (ch < NC) - cs->bmp[ch >> 3] |= 1 << (ch & 7); - else { - newwides = realloc(cs->wides, (cs->nwides + 1) * - sizeof (*cs->wides)); - if (newwides == NULL) { - SETERROR(REG_ESPACE); - return; - } - cs->wides = newwides; - cs->wides[cs->nwides++] = ch; - } - if (cs->icase) { - if ((nch = towlower(ch)) < NC) - cs->bmp[nch >> 3] |= 1 << (nch & 7); - if ((nch = towupper(ch)) < NC) - cs->bmp[nch >> 3] |= 1 << (nch & 7); - } -} - -/* - * CHaddrange - add all characters in the range [min,max] to a character set. - */ -static void -CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) -{ - crange *newranges; - - for (; min < NC && min <= max; min++) - CHadd(p, cs, min); - if (min >= max) - return; - newranges = realloc(cs->ranges, (cs->nranges + 1) * - sizeof (*cs->ranges)); - if (newranges == NULL) { - SETERROR(REG_ESPACE); - return; - } - cs->ranges = newranges; - cs->ranges[cs->nranges].min = min; - cs->ranges[cs->nranges].min = max; - cs->nranges++; -} - -/* - * CHaddtype - add all characters of a certain type to a character set. - */ -static void -CHaddtype(struct parse *p, cset *cs, wctype_t wct) -{ - wint_t i; - wctype_t *newtypes; - - for (i = 0; i < NC; i++) - if (iswctype(i, wct)) - CHadd(p, cs, i); - newtypes = realloc(cs->types, (cs->ntypes + 1) * - sizeof (*cs->types)); - if (newtypes == NULL) { - SETERROR(REG_ESPACE); - return; - } - cs->types = newtypes; - cs->types[cs->ntypes++] = wct; -} - -/* - * dupl - emit a duplicate of a bunch of sops - */ -static sopno /* start of duplicate */ -dupl(struct parse *p, - sopno start, /* from here */ - sopno finish) /* to this less one */ -{ - sopno ret = HERE(); - sopno len = finish - start; - - assert(finish >= start); - if (len == 0) - return (ret); - enlarge(p, p->ssize + len); /* this many unexpected additions */ - assert(p->ssize >= p->slen + len); - (void) memcpy((char *)(p->strip + p->slen), - (char *)(p->strip + start), (size_t)len*sizeof (sop)); - p->slen += len; - return (ret); -} - -/* - * doemit - emit a strip operator - * - * It might seem better to implement this as a macro with a function as - * hard-case backup, but it's just too big and messy unless there are - * some changes to the data structures. Maybe later. - */ -static void -doemit(struct parse *p, sop op, size_t opnd) -{ - /* avoid making error situations worse */ - if (p->error != 0) - return; - - /* deal with oversize operands ("can't happen", more or less) */ - assert(opnd < 1<slen >= p->ssize) - enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */ - assert(p->slen < p->ssize); - - /* finally, it's all reduced to the easy case */ - p->strip[p->slen++] = SOP(op, opnd); -} - -/* - * doinsert - insert a sop into the strip - */ -static void -doinsert(struct parse *p, sop op, size_t opnd, sopno pos) -{ - sopno sn; - sop s; - int i; - - /* avoid making error situations worse */ - if (p->error != 0) - return; - - sn = HERE(); - EMIT(op, opnd); /* do checks, ensure space */ - assert(HERE() == sn+1); - s = p->strip[sn]; - - /* adjust paren pointers */ - assert(pos > 0); - for (i = 1; i < NPAREN; i++) { - if (p->pbegin[i] >= pos) { - p->pbegin[i]++; - } - if (p->pend[i] >= pos) { - p->pend[i]++; - } - } - - (void) memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], - (HERE()-pos-1)*sizeof (sop)); - p->strip[pos] = s; -} - -/* - * dofwd - complete a forward reference - */ -static void -dofwd(struct parse *p, sopno pos, sop value) -{ - /* avoid making error situations worse */ - if (p->error != 0) - return; - - assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; -} - -/* - * enlarge - enlarge the strip - */ -static void -enlarge(struct parse *p, sopno size) -{ - sop *sp; - - if (p->ssize >= size) - return; - - sp = (sop *)realloc(p->strip, size*sizeof (sop)); - if (sp == NULL) { - SETERROR(REG_ESPACE); - return; - } - p->strip = sp; - p->ssize = size; -} - -/* - * stripsnug - compact the strip - */ -static void -stripsnug(struct parse *p, struct re_guts *g) -{ - g->nstates = p->slen; - g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof (sop)); - if (g->strip == NULL) { - SETERROR(REG_ESPACE); - g->strip = p->strip; - } -} - -/* - * findmust - fill in must and mlen with longest mandatory literal string - * - * This algorithm could do fancy things like analyzing the operands of | - * for common subsequences. Someday. This code is simple and finds most - * of the interesting cases. - * - * Note that must and mlen got initialized during setup. - */ -static void -findmust(struct parse *p, struct re_guts *g) -{ - sop *scan; - sop *start; - sop *newstart; - sopno newlen; - sop s; - char *cp; - int offset; - char buf[MB_LEN_MAX]; - size_t clen; - mbstate_t mbs; - locale_t loc = uselocale(NULL); - - /* avoid making error situations worse */ - if (p->error != 0) - return; - - /* - * It's not generally safe to do a ``char'' substring search on - * multibyte character strings, but it's safe for at least - * UTF-8 (see RFC 3629). - */ - if (MB_CUR_MAX > 1 && - strcmp(loc->runelocale->__encoding, "UTF-8") != 0) - return; - - /* find the longest OCHAR sequence in strip */ - newlen = 0; - offset = 0; - g->moffset = 0; - scan = g->strip + 1; - do { - s = *scan++; - switch (OP(s)) { - case OCHAR: /* sequence member */ - if (newlen == 0) { /* new sequence */ - (void) memset(&mbs, 0, sizeof (mbs)); - newstart = scan - 1; - } - clen = wcrtomb(buf, OPND(s), &mbs); - if (clen == (size_t)-1) - goto toohard; - newlen += clen; - break; - case OPLUS_: /* things that don't break one */ - case OLPAREN: - case ORPAREN: - break; - case OQUEST_: /* things that must be skipped */ - case OCH_: - offset = altoffset(scan, offset); - scan--; - do { - scan += OPND(s); - s = *scan; - /* assert() interferes w debug printouts */ - if (OP(s) != O_QUEST && OP(s) != O_CH && - OP(s) != OOR2) { - g->iflags |= BAD; - return; - } - } while (OP(s) != O_QUEST && OP(s) != O_CH); - /* FALLTHROUGH */ - case OBOW: /* things that break a sequence */ - case OEOW: - case OBOL: - case OEOL: - case O_QUEST: - case O_CH: - case OEND: - if (newlen > g->mlen) { /* ends one */ - start = newstart; - g->mlen = newlen; - if (offset > -1) { - g->moffset += offset; - offset = newlen; - } else - g->moffset = offset; - } else { - if (offset > -1) - offset += newlen; - } - newlen = 0; - break; - case OANY: - if (newlen > g->mlen) { /* ends one */ - start = newstart; - g->mlen = newlen; - if (offset > -1) { - g->moffset += offset; - offset = newlen; - } else - g->moffset = offset; - } else { - if (offset > -1) - offset += newlen; - } - if (offset > -1) - offset++; - newlen = 0; - break; - case OANYOF: /* may or may not invalidate offset */ - /* First, everything as OANY */ - if (newlen > g->mlen) { /* ends one */ - start = newstart; - g->mlen = newlen; - if (offset > -1) { - g->moffset += offset; - offset = newlen; - } else - g->moffset = offset; - } else { - if (offset > -1) - offset += newlen; - } - if (offset > -1) - offset++; - newlen = 0; - break; - toohard: - default: - /* - * Anything here makes it impossible or too hard - * to calculate the offset -- so we give up; - * save the last known good offset, in case the - * must sequence doesn't occur later. - */ - if (newlen > g->mlen) { /* ends one */ - start = newstart; - g->mlen = newlen; - if (offset > -1) - g->moffset += offset; - else - g->moffset = offset; - } - offset = -1; - newlen = 0; - break; - } - } while (OP(s) != OEND); - - if (g->mlen == 0) { /* there isn't one */ - g->moffset = -1; - return; - } - - /* turn it into a character string */ - g->must = malloc((size_t)g->mlen + 1); - if (g->must == NULL) { /* argh; just forget it */ - g->mlen = 0; - g->moffset = -1; - return; - } - cp = g->must; - scan = start; - (void) memset(&mbs, 0, sizeof (mbs)); - while (cp < g->must + g->mlen) { - while (OP(s = *scan++) != OCHAR) - continue; - clen = wcrtomb(cp, OPND(s), &mbs); - assert(clen != (size_t)-1); - cp += clen; - } - assert(cp == g->must + g->mlen); - *cp++ = '\0'; /* just on general principles */ -} - -/* - * altoffset - choose biggest offset among multiple choices - * - * Compute, recursively if necessary, the largest offset among multiple - * re paths. - */ -static int -altoffset(sop *scan, int offset) -{ - int largest; - int try; - sop s; - - /* If we gave up already on offsets, return */ - if (offset == -1) - return (-1); - - largest = 0; - try = 0; - s = *scan++; - while (OP(s) != O_QUEST && OP(s) != O_CH) { - switch (OP(s)) { - case OOR1: - if (try > largest) - largest = try; - try = 0; - break; - case OQUEST_: - case OCH_: - try = altoffset(scan, try); - if (try == -1) - return (-1); - scan--; - do { - scan += OPND(s); - s = *scan; - if (OP(s) != O_QUEST && OP(s) != O_CH && - OP(s) != OOR2) - return (-1); - } while (OP(s) != O_QUEST && OP(s) != O_CH); - /* - * We must skip to the next position, or we'll - * leave altoffset() too early. - */ - scan++; - break; - case OANYOF: - case OCHAR: - case OANY: - try++; - /*FALLTHRU*/ - case OBOW: - case OEOW: - case OLPAREN: - case ORPAREN: - case OOR2: - break; - default: - try = -1; - break; - } - if (try == -1) - return (-1); - s = *scan++; - } - - if (try > largest) - largest = try; - - return (largest+offset); -} - -/* - * computejumps - compute char jumps for BM scan - * - * This algorithm assumes g->must exists and is has size greater than - * zero. It's based on the algorithm found on Computer Algorithms by - * Sara Baase. - * - * A char jump is the number of characters one needs to jump based on - * the value of the character from the text that was mismatched. - */ -static void -computejumps(struct parse *p, struct re_guts *g) -{ - int ch; - int mindex; - - /* Avoid making errors worse */ - if (p->error != 0) - return; - - g->charjump = (int *)malloc((NC + 1) * sizeof (int)); - if (g->charjump == NULL) /* Not a fatal error */ - return; - /* Adjust for signed chars, if necessary */ - g->charjump = &g->charjump[-(CHAR_MIN)]; - - /* - * If the character does not exist in the pattern, the jump - * is equal to the number of characters in the pattern. - */ - for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++) - g->charjump[ch] = g->mlen; - - /* - * If the character does exist, compute the jump that would - * take us to the last character in the pattern equal to it - * (notice that we match right to left, so that last character - * is the first one that would be matched). - */ - for (mindex = 0; mindex < g->mlen; mindex++) - g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1; -} - -/* - * computematchjumps - compute match jumps for BM scan - * - * This algorithm assumes g->must exists and is has size greater than - * zero. It's based on the algorithm found on Computer Algorithms by - * Sara Baase. - * - * A match jump is the number of characters one needs to advance based - * on the already-matched suffix. - * Notice that all values here are minus (g->mlen-1), because of the way - * the search algorithm works. - */ -static void -computematchjumps(struct parse *p, struct re_guts *g) -{ - int mindex; /* General "must" iterator */ - int suffix; /* Keeps track of matching suffix */ - int ssuffix; /* Keeps track of suffixes' suffix */ - int *pmatches; - /* - * pmatches[k] points to the next i - * such that i+1...mlen is a substring - * of k+1...k+mlen-i-1 - */ - - /* Avoid making errors worse */ - if (p->error != 0) - return; - - pmatches = (int *)malloc(g->mlen * sizeof (unsigned int)); - if (pmatches == NULL) { - g->matchjump = NULL; - return; - } - - g->matchjump = (int *)malloc(g->mlen * sizeof (unsigned int)); - if (g->matchjump == NULL) /* Not a fatal error */ - return; - - /* Set maximum possible jump for each character in the pattern */ - for (mindex = 0; mindex < g->mlen; mindex++) - g->matchjump[mindex] = 2*g->mlen - mindex - 1; - - /* Compute pmatches[] */ - for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0; - mindex--, suffix--) { - pmatches[mindex] = suffix; - - /* - * If a mismatch is found, interrupting the substring, - * compute the matchjump for that position. If no - * mismatch is found, then a text substring mismatched - * against the suffix will also mismatch against the - * substring. - */ - while (suffix < g->mlen && g->must[mindex] != g->must[suffix]) { - g->matchjump[suffix] = MIN(g->matchjump[suffix], - g->mlen - mindex - 1); - suffix = pmatches[suffix]; - } - } - - /* - * Compute the matchjump up to the last substring found to jump - * to the beginning of the largest must pattern prefix matching - * it's own suffix. - */ - for (mindex = 0; mindex <= suffix; mindex++) - g->matchjump[mindex] = MIN(g->matchjump[mindex], - g->mlen + suffix - mindex); - - ssuffix = pmatches[suffix]; - while (suffix < g->mlen) { - while (suffix <= ssuffix && suffix < g->mlen) { - g->matchjump[suffix] = MIN(g->matchjump[suffix], - g->mlen + ssuffix - suffix); - suffix++; - } - if (suffix < g->mlen) - ssuffix = pmatches[ssuffix]; - } - - free(pmatches); -} - -/* - * pluscount - count + nesting - */ -static sopno /* nesting depth */ -pluscount(struct parse *p, struct re_guts *g) -{ - sop *scan; - sop s; - sopno plusnest = 0; - sopno maxnest = 0; - - if (p->error != 0) - return (0); /* there may not be an OEND */ - - scan = g->strip + 1; - do { - s = *scan++; - switch (OP(s)) { - case OPLUS_: - plusnest++; - break; - case O_PLUS: - if (plusnest > maxnest) - maxnest = plusnest; - plusnest--; - break; - } - } while (OP(s) != OEND); - if (plusnest != 0) - g->iflags |= BAD; - return (maxnest); -} diff --git a/usr/src/lib/libc/port/locale/regerror.c b/usr/src/lib/libc/port/locale/regerror.c deleted file mode 100644 index 9f7a495bff..0000000000 --- a/usr/src/lib/libc/port/locale/regerror.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -#include "lint.h" -#include "file64.h" -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "../gen/_libc_gettext.h" - -#define RERR(x, msg) { x, #x, msg } - -static struct rerr { - int code; - char *name; - char *explain; -} rerrs[] = { - RERR(REG_NOMATCH, "regexec() failed to match"), - RERR(REG_BADPAT, "invalid regular expression"), - RERR(REG_ECOLLATE, "invalid collating element"), - RERR(REG_ECTYPE, "invalid character class"), - RERR(REG_EESCAPE, "trailing backslash (\\)"), - RERR(REG_ESUBREG, "invalid backreference number"), - RERR(REG_EBRACK, "brackets ([ ]) not balanced"), - RERR(REG_EPAREN, "parentheses not balanced"), - RERR(REG_EBRACE, "braces not balanced"), - RERR(REG_BADBR, "invalid repetition count(s)"), - RERR(REG_ERANGE, "invalid character range"), - RERR(REG_ESPACE, "out of memory"), - RERR(REG_BADRPT, "repetition-operator operand invalid"), -#ifdef REG_EMPTY - RERR(REG_EMPTY, "empty (sub)expression"), -#endif - RERR(REG_EFATAL, "fatal internal error"), -#ifdef REG_INVARG - RERR(REG_INVARG, "invalid argument to regex routine"), -#endif - RERR(REG_ECHAR, "illegal byte sequence"), - RERR(REG_ENOSYS, "function not supported"), - RERR(REG_STACK, "backtrack stack overflow"), - RERR(REG_ENSUB, "more than 9 \\( \\) pairs"), - RERR(REG_ENEWLINE, "\n found before end of pattern"), - {0, "", "*** unknown regexp error code ***"} -}; - - -/* - * regerror - the interface to error numbers - */ -/* ARGSUSED */ -size_t -regerror(int errcode, const regex_t *_RESTRICT_KYWD preg, - char *_RESTRICT_KYWD errbuf, size_t errbuf_size) -{ - struct rerr *r; - size_t len; - char *s; - - for (r = rerrs; r->code != 0; r++) - if (r->code == errcode) - break; - - s = _libc_gettext(r->explain); - - len = strlen(s) + 1; - if (errbuf_size > 0) { - if (errbuf_size > len) - (void) strcpy(errbuf, s); - else { - (void) strncpy(errbuf, s, errbuf_size-1); - errbuf[errbuf_size-1] = '\0'; - } - } - - return (len); -} diff --git a/usr/src/lib/libc/port/locale/regex2.h b/usr/src/lib/libc/port/locale/regex2.h deleted file mode 100644 index f44e1caeef..0000000000 --- a/usr/src/lib/libc/port/locale/regex2.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - * - * @(#)regex2.h 8.4 (Berkeley) 3/20/94 - * $FreeBSD: src/lib/libc/regex/regex2.h,v 1.11 2007/01/09 00:28:04 imp Exp $ - */ - -/* - * First, the stuff that ends up in the outside-world include file - * typedef off_t regoff_t; - * typedef struct { - * int re_magic; - * size_t re_nsub; // number of parenthesized subexpressions - * const char *re_endp; // end pointer for REG_PEND - * struct re_guts *re_g; // none of your business :-) - * } regex_t; - * typedef struct { - * regoff_t rm_so; // start of match - * regoff_t rm_eo; // end of match - * } regmatch_t; - */ -/* - * internals of regex_t - */ -#define MAGIC1 ((('r'^0200)<<8) | 'e') - -/* - * The internal representation is a *strip*, a sequence of - * operators ending with an endmarker. (Some terminology etc. is a - * historical relic of earlier versions which used multiple strips.) - * Certain oddities in the representation are there to permit running - * the machinery backwards; in particular, any deviation from sequential - * flow must be marked at both its source and its destination. Some - * fine points: - * - * - OPLUS_ and O_PLUS are *inside* the loop they create. - * - OQUEST_ and O_QUEST are *outside* the bypass they create. - * - OCH_ and O_CH are *outside* the multi-way branch they create, while - * OOR1 and OOR2 are respectively the end and the beginning of one of - * the branches. Note that there is an implicit OOR2 following OCH_ - * and an implicit OOR1 preceding O_CH. - * - * In state representations, an operator's bit is on to signify a state - * immediately *preceding* "execution" of that operator. - */ -typedef unsigned int sop; /* strip operator */ -typedef int sopno; -#define OPRMASK 0xf8000000U -#define OPDMASK 0x07ffffffU -#define OPSHIFT ((unsigned)27) -#define OP(n) ((n)&OPRMASK) -#define OPND(n) ((n)&OPDMASK) -#define SOP(op, opnd) ((op)|(opnd)) -/* operators meaning operand */ -/* (back, fwd are offsets) */ -#define OEND (1U<= 0); - if (ch < NC) - return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ - cs->invert); - for (i = 0; i < cs->nwides; i++) - if (ch == cs->wides[i]) - return (!cs->invert); - for (i = 0; i < cs->nranges; i++) - if (cs->ranges[i].min <= ch && ch <= cs->ranges[i].max) - return (!cs->invert); - for (i = 0; i < cs->ntypes; i++) - if (iswctype(ch, cs->types[i])) - return (!cs->invert); - return (cs->invert); -} - -static int -CHIN(cset *cs, wint_t ch) -{ - - assert(ch >= 0); - if (ch < NC) - return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ - cs->invert); - else if (cs->icase) - return (CHIN1(cs, ch) || CHIN1(cs, towlower(ch)) || - CHIN1(cs, towupper(ch))); - else - return (CHIN1(cs, ch)); -} - -/* - * main compiled-expression structure - */ -struct re_guts { - int magic; -#define MAGIC2 ((('R'^0200)<<8)|'E') - sop *strip; /* malloced area for strip */ - int ncsets; /* number of csets in use */ - cset *sets; /* -> cset [ncsets] */ - int cflags; /* copy of regcomp() cflags argument */ - sopno nstates; /* = number of sops */ - sopno firststate; /* the initial OEND (normally 0) */ - sopno laststate; /* the final OEND */ - int iflags; /* internal flags */ -#define USEBOL 01 /* used ^ */ -#define USEEOL 02 /* used $ */ -#define BAD 04 /* something wrong */ - int nbol; /* number of ^ used */ - int neol; /* number of $ used */ - char *must; /* match must contain this string */ - int moffset; /* latest point at which must may be located */ - int *charjump; /* Boyer-Moore char jump table */ - int *matchjump; /* Boyer-Moore match jump table */ - int mlen; /* length of must */ - size_t nsub; /* copy of re_nsub */ - int backrefs; /* does it use back references? */ - sopno nplus; /* how deep does it nest +s? */ -}; - -/* misc utilities */ -#define OUT (CHAR_MIN - 1) /* a non-character value */ -#define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') diff --git a/usr/src/lib/libc/port/locale/regexec.c b/usr/src/lib/libc/port/locale/regexec.c deleted file mode 100644 index b6b9b6f56c..0000000000 --- a/usr/src/lib/libc/port/locale/regexec.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -/* - * the outer shell of regexec() - * - * This file includes engine.c three times, after muchos fiddling with the - * macros that code uses. This lets the same code operate on two different - * representations for state sets and characters. - */ -#include "lint.h" -#include "file64.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "regex2.h" - -/* we want _NOTE, but not NOTE (which collides with our own use) */ -#undef NOTE - -static size_t -xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy) -{ - size_t nr; - wchar_t wc; - - nr = mbrtowc(&wc, s, n, mbs); - if (wi != NULL) - *wi = wc; - if (nr == 0) - return (1); - else if (nr == (size_t)-1 || nr == (size_t)-2) { - (void) memset(mbs, 0, sizeof (*mbs)); - if (wi != NULL) - *wi = dummy; - return (1); - } else - return (nr); -} - -static size_t -xmbrtowc_dummy(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, - wint_t dummy) -{ - _NOTE(ARGUNUSED(n)); - _NOTE(ARGUNUSED(mbs)); - _NOTE(ARGUNUSED(dummy)); - - if (wi != NULL) - *wi = (unsigned char)*s; - return (1); -} - -/* macros for manipulating states, small version */ -#define states long -#define states1 states /* for later use in regexec() decision */ -#define CLEAR(v) ((v) = 0) -#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n))) -#define SET1(v, n) ((v) |= (unsigned long)1 << (n)) -#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0) -#define ASSIGN(d, s) ((d) = (s)) -#define EQ(a, b) ((a) == (b)) -#define STATEVARS long dummy /* dummy version */ -#define STATESETUP(m, n) /* nothing */ -#define STATETEARDOWN(m) /* nothing */ -#define SETUP(v) ((v) = 0) -#define onestate long -#define INIT(o, n) ((o) = (unsigned long)1 << (n)) -#define INC(o) ((o) <<= 1) -#define ISSTATEIN(v, o) (((v) & (o)) != 0) -/* some abbreviations; note that some of these know variable names! */ -/* do "if I'm here, I can also be there" etc without branches */ -#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n)) -#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n)) -#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0) -/* no multibyte support */ -#define XMBRTOWC xmbrtowc_dummy -#define ZAPSTATE(mbs) ((void)(mbs)) -/* function names */ -#define SNAMES /* engine.c looks after details */ - -#include "engine.c" - -/* now undo things */ -#undef states -#undef CLEAR -#undef SET0 -#undef SET1 -#undef ISSET -#undef ASSIGN -#undef EQ -#undef STATEVARS -#undef STATESETUP -#undef STATETEARDOWN -#undef SETUP -#undef onestate -#undef INIT -#undef INC -#undef ISSTATEIN -#undef FWD -#undef BACK -#undef ISSETBACK -#undef SNAMES -#undef XMBRTOWC -#undef ZAPSTATE - -/* macros for manipulating states, large version */ -#define states char * -#define CLEAR(v) (void) memset(v, 0, m->g->nstates) -#define SET0(v, n) ((v)[n] = 0) -#define SET1(v, n) ((v)[n] = 1) -#define ISSET(v, n) ((v)[n]) -#define ASSIGN(d, s) (void) memcpy(d, s, m->g->nstates) -#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) -#define STATEVARS long vn; char *space -#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ - if ((m)->space == NULL) \ - return (REG_ESPACE); \ - (m)->vn = 0; } -#define STATETEARDOWN(m) { free((m)->space); } -#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) -#define onestate long -#define INIT(o, n) ((o) = (n)) -#define INC(o) ((o)++) -#define ISSTATEIN(v, o) ((v)[o]) -/* some abbreviations; note that some of these know variable names! */ -/* do "if I'm here, I can also be there" etc without branches */ -#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) -#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) -#define ISSETBACK(v, n) ((v)[here - (n)]) -/* no multibyte support */ -#define XMBRTOWC xmbrtowc_dummy -#define ZAPSTATE(mbs) ((void)(mbs)) -/* function names */ -#define LNAMES /* flag */ - -#include "engine.c" - -/* multibyte character & large states version */ -#undef LNAMES -#undef XMBRTOWC -#undef ZAPSTATE -#define XMBRTOWC xmbrtowc -#define ZAPSTATE(mbs) (void) memset((mbs), 0, sizeof (*(mbs))) -#define MNAMES - -#include "engine.c" - -/* - * regexec - interface for matching - * - * We put this here so we can exploit knowledge of the state representation - * when choosing which matcher to call. Also, by this point the matchers - * have been prototyped. - */ -int /* 0 success, REG_NOMATCH failure */ -regexec(const regex_t *_RESTRICT_KYWD preg, - const char *_RESTRICT_KYWD string, size_t nmatch, - regmatch_t pmatch[_RESTRICT_KYWD], int eflags) -{ - struct re_guts *g = preg->re_g; -#ifdef REDEBUG -#define GOODFLAGS(f) (f) -#else -#ifdef REG_STARTEND -#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) -#else -#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL)) -#endif -#endif - - if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) - return (REG_BADPAT); - assert(!(g->iflags&BAD)); - if (g->iflags&BAD) /* backstop for no-debug case */ - return (REG_BADPAT); - eflags = GOODFLAGS(eflags); - - if (MB_CUR_MAX > 1) - return (mmatcher(g, (char *)string, nmatch, pmatch, eflags)); -#ifdef REG_LARGE - else if (g->nstates <= CHAR_BIT*sizeof (states1) && !(eflags®_LARGE)) -#else - else if (g->nstates <= CHAR_BIT*sizeof (states1)) -#endif - return (smatcher(g, (char *)string, nmatch, pmatch, eflags)); - else - return (lmatcher(g, (char *)string, nmatch, pmatch, eflags)); -} diff --git a/usr/src/lib/libc/port/locale/regfree.c b/usr/src/lib/libc/port/locale/regfree.c deleted file mode 100644 index 43c7e13958..0000000000 --- a/usr/src/lib/libc/port/locale/regfree.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -#include "lint.h" -#include "file64.h" -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "regex2.h" - -/* - * regfree - free everything - */ -void -regfree(regex_t *preg) -{ - struct re_guts *g; - int i; - -#ifdef __lint - /* shut up lint! */ - CHIN(NULL, 0); -#endif - - if (preg->re_magic != MAGIC1) /* oops */ - return; /* nice to complain, but hard */ - - g = preg->re_g; - if (g == NULL || g->magic != MAGIC2) /* oops again */ - return; - preg->re_magic = 0; /* mark it invalid */ - g->magic = 0; /* mark it invalid */ - - if (g->strip != NULL) - free((char *)g->strip); - if (g->sets != NULL) { - for (i = 0; i < g->ncsets; i++) { - free(g->sets[i].ranges); - free(g->sets[i].wides); - free(g->sets[i].types); - } - free((char *)g->sets); - } - if (g->must != NULL) - free(g->must); - if (g->charjump != NULL) - free(&g->charjump[CHAR_MIN]); - if (g->matchjump != NULL) - free(g->matchjump); - free((char *)g); -} diff --git a/usr/src/lib/libc/port/locale/utils.h b/usr/src/lib/libc/port/locale/utils.h deleted file mode 100644 index 3ed1484391..0000000000 --- a/usr/src/lib/libc/port/locale/utils.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 1992, 1993, 1994 Henry Spencer. - * Copyright (c) 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Henry Spencer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 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. - */ - -/* utility definitions */ -#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ -#define INFINITY (DUPMAX + 1) -#define NC (CHAR_MAX - CHAR_MIN + 1) -typedef unsigned char uch; - -/* switch off assertions (if not already off) if no REDEBUG */ -#ifndef REDEBUG -#ifndef NDEBUG -#define NDEBUG /* no assertions please */ -#endif -#endif -#include diff --git a/usr/src/lib/libc/port/regex/cname.h b/usr/src/lib/libc/port/regex/cname.h new file mode 100644 index 0000000000..4bd065672a --- /dev/null +++ b/usr/src/lib/libc/port/regex/cname.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* character-name table */ +static struct cname { + char *name; + char code; +} cnames[] = { + {"NUL", '\0'}, + {"SOH", '\001'}, + {"STX", '\002'}, + {"ETX", '\003'}, + {"EOT", '\004'}, + {"ENQ", '\005'}, + {"ACK", '\006'}, + {"BEL", '\007'}, + {"alert", '\007'}, + {"BS", '\010'}, + {"backspace", '\b'}, + {"HT", '\011'}, + {"tab", '\t'}, + {"LF", '\012'}, + {"newline", '\n'}, + {"VT", '\013'}, + {"vertical-tab", '\v'}, + {"FF", '\014'}, + {"form-feed", '\f'}, + {"CR", '\015'}, + {"carriage-return", '\r'}, + {"SO", '\016'}, + {"SI", '\017'}, + {"DLE", '\020'}, + {"DC1", '\021'}, + {"DC2", '\022'}, + {"DC3", '\023'}, + {"DC4", '\024'}, + {"NAK", '\025'}, + {"SYN", '\026'}, + {"ETB", '\027'}, + {"CAN", '\030'}, + {"EM", '\031'}, + {"SUB", '\032'}, + {"ESC", '\033'}, + {"IS4", '\034'}, + {"FS", '\034'}, + {"IS3", '\035'}, + {"GS", '\035'}, + {"IS2", '\036'}, + {"RS", '\036'}, + {"IS1", '\037'}, + {"US", '\037'}, + {"space", ' '}, + {"exclamation-mark", '!'}, + {"quotation-mark", '"'}, + {"number-sign", '#'}, + {"dollar-sign", '$'}, + {"percent-sign", '%'}, + {"ampersand", '&'}, + {"apostrophe", '\''}, + {"left-parenthesis", '('}, + {"right-parenthesis", ')'}, + {"asterisk", '*'}, + {"plus-sign", '+'}, + {"comma", ','}, + {"hyphen", '-'}, + {"hyphen-minus", '-'}, + {"period", '.'}, + {"full-stop", '.'}, + {"slash", '/'}, + {"solidus", '/'}, + {"zero", '0'}, + {"one", '1'}, + {"two", '2'}, + {"three", '3'}, + {"four", '4'}, + {"five", '5'}, + {"six", '6'}, + {"seven", '7'}, + {"eight", '8'}, + {"nine", '9'}, + {"colon", ':'}, + {"semicolon", ';'}, + {"less-than-sign", '<'}, + {"equals-sign", '='}, + {"greater-than-sign", '>'}, + {"question-mark", '?'}, + {"commercial-at", '@'}, + {"left-square-bracket", '['}, + {"backslash", '\\'}, + {"reverse-solidus", '\\'}, + {"right-square-bracket", ']'}, + {"circumflex", '^'}, + {"circumflex-accent", '^'}, + {"underscore", '_'}, + {"low-line", '_'}, + {"grave-accent", '`'}, + {"left-brace", '{'}, + {"left-curly-bracket", '{'}, + {"vertical-line", '|'}, + {"right-brace", '}'}, + {"right-curly-bracket", '}'}, + {"tilde", '~'}, + {"DEL", '\177'}, + {NULL, 0} +}; diff --git a/usr/src/lib/libc/port/regex/engine.c b/usr/src/lib/libc/port/regex/engine.c new file mode 100644 index 0000000000..7481545864 --- /dev/null +++ b/usr/src/lib/libc/port/regex/engine.c @@ -0,0 +1,1135 @@ +/* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Milan Jurik. All rights reserved. + * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * The matching engine and friends. This file is #included by regexec.c + * after suitable #defines of a variety of macros used herein, so that + * different state representations can be used without duplicating masses + * of code. + */ + +#ifdef SNAMES +#define matcher smatcher +#define fast sfast +#define slow sslow +#define dissect sdissect +#define backref sbackref +#define step sstep +#define print sprint +#define at sat +#define match smat +#endif +#ifdef LNAMES +#define matcher lmatcher +#define fast lfast +#define slow lslow +#define dissect ldissect +#define backref lbackref +#define step lstep +#define print lprint +#define at lat +#define match lmat +#endif +#ifdef MNAMES +#define matcher mmatcher +#define fast mfast +#define slow mslow +#define dissect mdissect +#define backref mbackref +#define step mstep +#define print mprint +#define at mat +#define match mmat +#endif + +/* another structure passed up and down to avoid zillions of parameters */ +struct match { + struct re_guts *g; + int eflags; + regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ + const char *offp; /* offsets work from here */ + const char *beginp; /* start of string -- virtual NUL precedes */ + const char *endp; /* end of string -- virtual NUL here */ + const char *coldp; /* can be no match starting before here */ + const char **lastpos; /* [nplus+1] */ + STATEVARS; + states st; /* current states */ + states fresh; /* states for a fresh start */ + states tmp; /* temporary */ + states empty; /* empty set of states */ + mbstate_t mbs; /* multibyte conversion state */ +}; + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === engine.c === */ +static int matcher(struct re_guts *, const char *, size_t, regmatch_t[], int); +static const char *dissect(struct match *, const char *, const char *, + sopno, sopno); +static const char *backref(struct match *, const char *, const char *, sopno, + sopno, sopno, int); +static const char *fast(struct match *, const char *, const char *, sopno, + sopno); +static const char *slow(struct match *, const char *, const char *, sopno, + sopno); +static states step(struct re_guts *, sopno, sopno, states, wint_t, states); +#define MAX_RECURSION 100 +#define BOL (OUT-1) +#define EOL (BOL-1) +#define BOLEOL (BOL-2) +#define NOTHING (BOL-3) +#define BOW (BOL-4) +#define EOW (BOL-5) +#define BADCHAR (BOL-6) +#define NONCHAR(c) ((c) <= OUT) +#ifdef REDEBUG +static void print(struct match *, const char *, states, int, FILE *); +#endif +#ifdef REDEBUG +static void at(struct match *, const char *, const char *, const char *, + sopno, sopno); +#endif +#ifdef REDEBUG +static const char *pchar(int ch); +#endif + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ + +#ifdef REDEBUG +#define SP(t, s, c) print(m, t, s, c, stdout) +#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) +#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } +#else +#define SP(t, s, c) /* nothing */ +#define AT(t, p1, p2, s1, s2) /* nothing */ +#define NOTE(s) /* nothing */ +#endif + +/* + * matcher - the actual matching engine + */ +static int /* 0 success, REG_NOMATCH failure */ +matcher(struct re_guts *g, const char *string, size_t nmatch, + regmatch_t pmatch[], int eflags) +{ + const char *endp; + size_t i; + struct match mv; + struct match *m = &mv; + const char *dp = NULL; + const sopno gf = g->firststate+1; /* +1 for OEND */ + const sopno gl = g->laststate; + const char *start; + const char *stop; + /* Boyer-Moore algorithms variables */ + const char *pp; + int cj, mj; + const char *mustfirst; + const char *mustlast; + int *matchjump; + int *charjump; + + /* simplify the situation where possible */ + if (g->cflags®_NOSUB) + nmatch = 0; + + if (eflags®_STARTEND) { + start = string + pmatch[0].rm_so; + stop = string + pmatch[0].rm_eo; + } else { + start = string; + stop = start + strlen(start); + } + + if (stop < start) + return (REG_EFATAL); + + /* prescreening; this does wonders for this rather slow code */ + if (g->must != NULL) { + if (g->charjump != NULL && g->matchjump != NULL) { + mustfirst = g->must; + mustlast = g->must + g->mlen - 1; + charjump = g->charjump; + matchjump = g->matchjump; + pp = mustlast; + for (dp = start+g->mlen-1; dp < stop; ) { + /* Fast skip non-matches */ + while (dp < stop && charjump[(int)*dp]) + dp += charjump[(int)*dp]; + + if (dp >= stop) + break; + + /* Greedy matcher */ + /* + * We depend on not being used for + * for strings of length 1 + */ + while (*--dp == *--pp && pp != mustfirst) + ; + + if (*dp == *pp) + break; + + /* Jump to next possible match */ + mj = matchjump[pp - mustfirst]; + cj = charjump[(int)*dp]; + dp += (cj < mj ? mj : cj); + pp = mustlast; + } + if (pp != mustfirst) + return (REG_NOMATCH); + } else { + for (dp = start; dp < stop; dp++) + if (*dp == g->must[0] && + stop - dp >= g->mlen && + memcmp(dp, g->must, (size_t)g->mlen) == 0) + break; + if (dp == stop) /* we didn't find g->must */ + return (REG_NOMATCH); + } + } + + /* match struct setup */ + m->g = g; + m->eflags = eflags; + m->pmatch = NULL; + m->lastpos = NULL; + m->offp = string; + m->beginp = start; + m->endp = stop; + STATESETUP(m, 4); + SETUP(m->st); + SETUP(m->fresh); + SETUP(m->tmp); + SETUP(m->empty); + CLEAR(m->empty); + ZAPSTATE(&m->mbs); + + /* Adjust start according to moffset, to speed things up */ + if (dp != NULL && g->moffset > -1) + start = ((dp - g->moffset) < start) ? start : dp - g->moffset; + + SP("mloop", m->st, *start); + + /* this loop does only one repetition except for backrefs */ + for (;;) { + endp = fast(m, start, stop, gf, gl); + if (endp == NULL) { /* a miss */ + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); + STATETEARDOWN(m); + return (REG_NOMATCH); + } + if (nmatch == 0 && !g->backrefs) + break; /* no further info needed */ + + /* where? */ + assert(m->coldp != NULL); + for (;;) { + NOTE("finding start"); + endp = slow(m, m->coldp, stop, gf, gl); + if (endp != NULL) + break; + assert(m->coldp < m->endp); + m->coldp += XMBRTOWC(NULL, m->coldp, + m->endp - m->coldp, &m->mbs, 0); + } + if (nmatch == 1 && !g->backrefs) + break; /* no further info needed */ + + /* oh my, it wants the subexpressions... */ + if (m->pmatch == NULL) + m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * + sizeof (regmatch_t)); + if (m->pmatch == NULL) { + STATETEARDOWN(m); + return (REG_ESPACE); + } + for (i = 1; i <= m->g->nsub; i++) + m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; + /* NB: FreeBSD has REG_BACKR, we do not */ + if (!g->backrefs /* && !(m->eflags®_BACKR) */) { + NOTE("dissecting"); + dp = dissect(m, m->coldp, endp, gf, gl); + } else { + if (g->nplus > 0 && m->lastpos == NULL) + m->lastpos = malloc((g->nplus+1) * + sizeof (const char *)); + if (g->nplus > 0 && m->lastpos == NULL) { + free(m->pmatch); + STATETEARDOWN(m); + return (REG_ESPACE); + } + NOTE("backref dissect"); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); + } + if (dp != NULL) + break; + + /* uh-oh... we couldn't find a subexpression-level match */ + assert(g->backrefs); /* must be back references doing it */ + assert(g->nplus == 0 || m->lastpos != NULL); + for (;;) { + if (dp != NULL || endp <= m->coldp) + break; /* defeat */ + NOTE("backoff"); + endp = slow(m, m->coldp, endp-1, gf, gl); + if (endp == NULL) + break; /* defeat */ + /* try it on a shorter possibility */ +#ifndef NDEBUG + for (i = 1; i <= m->g->nsub; i++) { + assert(m->pmatch[i].rm_so == -1); + assert(m->pmatch[i].rm_eo == -1); + } +#endif + NOTE("backoff dissect"); + dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); + } + assert(dp == NULL || dp == endp); + if (dp != NULL) /* found a shorter one */ + break; + + /* despite initial appearances, there is no match here */ + NOTE("false alarm"); + /* recycle starting later */ + start = m->coldp + XMBRTOWC(NULL, m->coldp, + stop - m->coldp, &m->mbs, 0); + assert(start <= stop); + } + + /* fill in the details if requested */ + if (nmatch > 0) { + pmatch[0].rm_so = m->coldp - m->offp; + pmatch[0].rm_eo = endp - m->offp; + } + if (nmatch > 1) { + assert(m->pmatch != NULL); + for (i = 1; i < nmatch; i++) + if (i <= m->g->nsub) + pmatch[i] = m->pmatch[i]; + else { + pmatch[i].rm_so = -1; + pmatch[i].rm_eo = -1; + } + } + + if (m->pmatch != NULL) + free((char *)m->pmatch); + if (m->lastpos != NULL) + free((char *)m->lastpos); + STATETEARDOWN(m); + return (0); +} + +/* + * dissect - figure out what matched what, no back references + */ +static const char * +dissect(struct match *m, const char *start, const char *stop, sopno startst, + sopno stopst) +{ + int i; + sopno ss; /* start sop of current subRE */ + sopno es; /* end sop of current subRE */ + const char *sp; /* start of string matched by it */ + const char *stp; /* string matched by it cannot pass here */ + const char *rest; /* start of rest of string */ + const char *tail; /* string unmatched by rest of RE */ + sopno ssub; /* start sop of subsubRE */ + sopno esub; /* end sop of subsubRE */ + const char *ssp; /* start of string matched by subsubRE */ + const char *sep; /* end of string matched by subsubRE */ + const char *oldssp; /* previous ssp */ + const char *dp; + + AT("diss", start, stop, startst, stopst); + sp = start; + for (ss = startst; ss < stopst; ss = es) { + /* identify end of subRE */ + es = ss; + switch (OP(m->g->strip[es])) { + case OPLUS_: + case OQUEST_: + es += OPND(m->g->strip[es]); + break; + case OCH_: + while (OP(m->g->strip[es]) != O_CH) + es += OPND(m->g->strip[es]); + break; + } + es++; + + /* figure out what it matched */ + switch (OP(m->g->strip[ss])) { + case OEND: + assert(0); + break; + case OCHAR: + sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0); + break; + case OBOL: + case OEOL: + case OBOW: + case OEOW: + break; + case OANY: + case OANYOF: + sp += XMBRTOWC(NULL, sp, stop - start, &m->mbs, 0); + break; + case OBACK_: + case O_BACK: + assert(0); + break; + /* cases where length of match is hard to find */ + case OQUEST_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + /* did innards match? */ + if (slow(m, sp, rest, ssub, esub) != NULL) { + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); +#if defined(__lint) + (void) dp; +#endif + } else /* no */ + assert(sp == rest); + sp = rest; + break; + case OPLUS_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = es - 1; + ssp = sp; + oldssp = ssp; + for (;;) { /* find last match of innards */ + sep = slow(m, ssp, rest, ssub, esub); + if (sep == NULL || sep == ssp) + break; /* failed or matched null */ + oldssp = ssp; /* on to next try */ + ssp = sep; + } + if (sep == NULL) { + /* last successful match */ + sep = ssp; + ssp = oldssp; + } + assert(sep == rest); /* must exhaust substring */ + assert(slow(m, ssp, sep, ssub, esub) == rest); + dp = dissect(m, ssp, sep, ssub, esub); + assert(dp == sep); + sp = rest; + break; + case OCH_: + stp = stop; + for (;;) { + /* how long could this one be? */ + rest = slow(m, sp, stp, ss, es); + assert(rest != NULL); /* it did match */ + /* could the rest match the rest? */ + tail = slow(m, rest, stop, es, stopst); + if (tail == stop) + break; /* yes! */ + /* no -- try a shorter match for this one */ + stp = rest - 1; + assert(stp >= sp); /* it did work */ + } + ssub = ss + 1; + esub = ss + OPND(m->g->strip[ss]) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) { /* find first matching branch */ + if (slow(m, sp, rest, ssub, esub) == rest) + break; /* it matched all of it */ + /* that one missed, try next one */ + assert(OP(m->g->strip[esub]) == OOR1); + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + dp = dissect(m, sp, rest, ssub, esub); + assert(dp == rest); + sp = rest; + break; + case O_PLUS: + case O_QUEST: + case OOR1: + case OOR2: + case O_CH: + assert(0); + break; + case OLPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_so = sp - m->offp; + break; + case ORPAREN: + i = OPND(m->g->strip[ss]); + assert(0 < i && i <= m->g->nsub); + m->pmatch[i].rm_eo = sp - m->offp; + break; + default: /* uh oh */ + assert(0); + break; + } + } + + assert(sp == stop); + return (sp); +} + +/* + * backref - figure out what matched what, figuring in back references + */ +static const char * +backref(struct match *m, const char *start, const char *stop, sopno startst, + sopno stopst, sopno lev, /* PLUS nesting level */ + int rec) +{ + int i; + sopno ss; /* start sop of current subRE */ + const char *sp; /* start of string matched by it */ + sopno ssub; /* start sop of subsubRE */ + sopno esub; /* end sop of subsubRE */ + const char *ssp; /* start of string matched by subsubRE */ + const char *dp; + size_t len; + int hard; + sop s; + regoff_t offsave; + cset *cs; + wint_t wc; + + AT("back", start, stop, startst, stopst); + sp = start; + + /* get as far as we can with easy stuff */ + hard = 0; + for (ss = startst; !hard && ss < stopst; ss++) + switch (OP(s = m->g->strip[ss])) { + case OCHAR: + if (sp == stop) + return (NULL); + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); + if (wc != OPND(s)) + return (NULL); + break; + case OANY: + if (sp == stop) + return (NULL); + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); + if (wc == BADCHAR) + return (NULL); + break; + case OANYOF: + if (sp == stop) + return (NULL); + cs = &m->g->sets[OPND(s)]; + sp += XMBRTOWC(&wc, sp, stop - sp, &m->mbs, BADCHAR); + if (wc == BADCHAR || !CHIN(cs, wc)) + return (NULL); + break; + case OBOL: + if ((sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp > m->offp && sp < m->endp && + *(sp-1) == '\n' && (m->g->cflags®_NEWLINE))) { + break; + } + return (NULL); + case OEOL: + if ((sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE))) { + break; + } + return (NULL); + case OBOW: + if (sp < m->endp && ISWORD(*sp) && + ((sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp > m->offp && !ISWORD(*(sp-1))))) { + break; + } + return (NULL); + case OEOW: + if (((sp == m->endp && !(m->eflags®_NOTEOL)) || + (sp < m->endp && *sp == '\n' && + (m->g->cflags®_NEWLINE)) || + (sp < m->endp && !ISWORD(*sp))) && + (sp > m->beginp && ISWORD(*(sp-1)))) { + break; + } + return (NULL); + case O_QUEST: + break; + case OOR1: /* matches null but needs to skip */ + ss++; + s = m->g->strip[ss]; + do { + assert(OP(s) == OOR2); + ss += OPND(s); + } while (OP(s = m->g->strip[ss]) != O_CH); + /* note that the ss++ gets us past the O_CH */ + break; + default: /* have to make a choice */ + hard = 1; + break; + } + if (!hard) { /* that was it! */ + if (sp != stop) + return (NULL); + return (sp); + } + ss--; /* adjust for the for's final increment */ + + /* the hard stuff */ + AT("hard", sp, stop, ss, stopst); + s = m->g->strip[ss]; + switch (OP(s)) { + case OBACK_: /* the vilest depths */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + if (m->pmatch[i].rm_eo == -1) + return (NULL); + assert(m->pmatch[i].rm_so != -1); + len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; + if (len == 0 && rec++ > MAX_RECURSION) + return (NULL); + assert(stop - m->beginp >= len); + if (sp > stop - len) + return (NULL); /* not enough left to match */ + ssp = m->offp + m->pmatch[i].rm_so; + if (memcmp(sp, ssp, len) != 0) + return (NULL); + while (m->g->strip[ss] != SOP(O_BACK, i)) + ss++; + return (backref(m, sp+len, stop, ss+1, stopst, lev, rec)); + case OQUEST_: /* to null or not */ + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); + if (dp != NULL) + return (dp); /* not */ + return (backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec)); + case OPLUS_: + assert(m->lastpos != NULL); + assert(lev+1 <= m->g->nplus); + m->lastpos[lev+1] = sp; + return (backref(m, sp, stop, ss+1, stopst, lev+1, rec)); + case O_PLUS: + if (sp == m->lastpos[lev]) /* last pass matched null */ + return (backref(m, sp, stop, ss+1, stopst, lev-1, rec)); + /* try another pass */ + m->lastpos[lev] = sp; + dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec); + if (dp == NULL) + return (backref(m, sp, stop, ss+1, stopst, lev-1, rec)); + return (dp); + case OCH_: /* find the right one, if any */ + ssub = ss + 1; + esub = ss + OPND(s) - 1; + assert(OP(m->g->strip[esub]) == OOR1); + for (;;) { /* find first matching branch */ + dp = backref(m, sp, stop, ssub, esub, lev, rec); + if (dp != NULL) + return (dp); + /* that one missed, try next one */ + if (OP(m->g->strip[esub]) == O_CH) + return (NULL); /* there is none */ + esub++; + assert(OP(m->g->strip[esub]) == OOR2); + ssub = esub + 1; + esub += OPND(m->g->strip[esub]); + if (OP(m->g->strip[esub]) == OOR2) + esub--; + else + assert(OP(m->g->strip[esub]) == O_CH); + } + /* NOTREACHED */ + break; + case OLPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + offsave = m->pmatch[i].rm_so; + m->pmatch[i].rm_so = sp - m->offp; + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); + if (dp != NULL) + return (dp); + m->pmatch[i].rm_so = offsave; + return (NULL); + case ORPAREN: /* must undo assignment if rest fails */ + i = OPND(s); + assert(0 < i && i <= m->g->nsub); + offsave = m->pmatch[i].rm_eo; + m->pmatch[i].rm_eo = sp - m->offp; + dp = backref(m, sp, stop, ss+1, stopst, lev, rec); + if (dp != NULL) + return (dp); + m->pmatch[i].rm_eo = offsave; + return (NULL); + default: /* uh oh */ + assert(0); + break; + } + + /* "can't happen" */ + assert(0); + return (NULL); +} + +/* + * fast - step through the string at top speed + */ +static const char * +fast(struct match *m, const char *start, const char *stop, sopno startst, + sopno stopst) +{ + states st = m->st; + states fresh = m->fresh; + states tmp = m->tmp; + const char *p = start; + wint_t c; + wint_t lastc; /* previous c */ + wint_t flagch; + int i; + const char *coldp; /* last p after which no match was underway */ + size_t clen; + + CLEAR(st); + SET1(st, startst); + SP("fast", st, *p); + st = step(m->g, startst, stopst, st, NOTHING, st); + ASSIGN(fresh, st); + SP("start", st, *p); + coldp = NULL; + if (start == m->offp || (start == m->beginp && !(m->eflags®_NOTBOL))) + c = OUT; + else { + /* + * XXX Wrong if the previous character was multi-byte. + * Newline never is (in encodings supported by FreeBSD), + * so this only breaks the ISWORD tests below. + */ + c = (uch)*(start - 1); + } + for (;;) { + /* next character */ + lastc = c; + if (p == m->endp) { + clen = 0; + c = OUT; + } else + clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); + if (EQ(st, fresh)) + coldp = p; + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ((lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL))) { + flagch = BOL; + i = m->g->nbol; + } + if ((c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL))) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, + flagch, st); + SP("boleol", st, c); + } + + /* how about a word boundary? */ + if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && + (c != OUT && ISWORD(c))) { + flagch = BOW; + } + if ((lastc != OUT && ISWORD(lastc)) && + (flagch == EOL || (c != OUT && !ISWORD(c)))) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("boweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst) || p == stop || clen > stop - p) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, fresh); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("aft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p += clen; + } + + assert(coldp != NULL); + m->coldp = coldp; + if (ISSET(st, stopst)) + return (p+XMBRTOWC(NULL, p, stop - p, &m->mbs, 0)); + else + return (NULL); +} + +/* + * slow - step through the string more deliberately + */ +static const char * +slow(struct match *m, const char *start, const char *stop, sopno startst, + sopno stopst) +{ + states st = m->st; + states empty = m->empty; + states tmp = m->tmp; + const char *p = start; + wint_t c; + wint_t lastc; /* previous c */ + wint_t flagch; + int i; + const char *matchp; /* last p at which a match ended */ + size_t clen; + + AT("slow", start, stop, startst, stopst); + CLEAR(st); + SET1(st, startst); + SP("sstart", st, *p); + st = step(m->g, startst, stopst, st, NOTHING, st); + matchp = NULL; + if (start == m->offp || (start == m->beginp && !(m->eflags®_NOTBOL))) + c = OUT; + else { + /* + * XXX Wrong if the previous character was multi-byte. + * Newline never is (in encodings supported by FreeBSD), + * so this only breaks the ISWORD tests below. + */ + c = (uch)*(start - 1); + } + for (;;) { + /* next character */ + lastc = c; + if (p == m->endp) { + c = OUT; + clen = 0; + } else + clen = XMBRTOWC(&c, p, m->endp - p, &m->mbs, BADCHAR); + + /* is there an EOL and/or BOL between lastc and c? */ + flagch = '\0'; + i = 0; + if ((lastc == '\n' && m->g->cflags®_NEWLINE) || + (lastc == OUT && !(m->eflags®_NOTBOL))) { + flagch = BOL; + i = m->g->nbol; + } + if ((c == '\n' && m->g->cflags®_NEWLINE) || + (c == OUT && !(m->eflags®_NOTEOL))) { + flagch = (flagch == BOL) ? BOLEOL : EOL; + i += m->g->neol; + } + if (i != 0) { + for (; i > 0; i--) + st = step(m->g, startst, stopst, st, + flagch, st); + SP("sboleol", st, c); + } + + /* how about a word boundary? */ + if ((flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && + (c != OUT && ISWORD(c))) { + flagch = BOW; + } + if ((lastc != OUT && ISWORD(lastc)) && + (flagch == EOL || (c != OUT && !ISWORD(c)))) { + flagch = EOW; + } + if (flagch == BOW || flagch == EOW) { + st = step(m->g, startst, stopst, st, flagch, st); + SP("sboweow", st, c); + } + + /* are we done? */ + if (ISSET(st, stopst)) + matchp = p; + if (EQ(st, empty) || p == stop || clen > stop - p) + break; /* NOTE BREAK OUT */ + + /* no, we must deal with this character */ + ASSIGN(tmp, st); + ASSIGN(st, empty); + assert(c != OUT); + st = step(m->g, startst, stopst, tmp, c, st); + SP("saft", st, c); + assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); + p += clen; + } + + return (matchp); +} + + +/* + * step - map set of states reachable before char to set reachable after + */ +static states +step(struct re_guts *g, + sopno start, /* start state within strip */ + sopno stop, /* state after stop state within strip */ + states bef, /* states reachable before */ + wint_t ch, /* character or NONCHAR code */ + states aft) /* states already known reachable after */ +{ + cset *cs; + sop s; + sopno pc; + onestate here; /* note, macros know this name */ + sopno look; + int i; + + for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { + s = g->strip[pc]; + switch (OP(s)) { + case OEND: + assert(pc == stop-1); + break; + case OCHAR: + /* only characters can match */ + assert(!NONCHAR(ch) || ch != OPND(s)); + if (ch == OPND(s)) + FWD(aft, bef, 1); + break; + case OBOL: + if (ch == BOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OEOL: + if (ch == EOL || ch == BOLEOL) + FWD(aft, bef, 1); + break; + case OBOW: + if (ch == BOW) + FWD(aft, bef, 1); + break; + case OEOW: + if (ch == EOW) + FWD(aft, bef, 1); + break; + case OANY: + if (!NONCHAR(ch)) + FWD(aft, bef, 1); + break; + case OANYOF: + cs = &g->sets[OPND(s)]; + if (!NONCHAR(ch) && CHIN(cs, ch)) + FWD(aft, bef, 1); + break; + case OBACK_: /* ignored here */ + case O_BACK: + FWD(aft, aft, 1); + break; + case OPLUS_: /* forward, this is just an empty */ + FWD(aft, aft, 1); + break; + case O_PLUS: /* both forward and back */ + FWD(aft, aft, 1); + i = ISSETBACK(aft, OPND(s)); + BACK(aft, aft, OPND(s)); + if (!i && ISSETBACK(aft, OPND(s))) { + /* oho, must reconsider loop body */ + pc -= OPND(s) + 1; + INIT(here, pc); + } + break; + case OQUEST_: /* two branches, both forward */ + FWD(aft, aft, 1); + FWD(aft, aft, OPND(s)); + break; + case O_QUEST: /* just an empty */ + FWD(aft, aft, 1); + break; + case OLPAREN: /* not significant here */ + case ORPAREN: + FWD(aft, aft, 1); + break; + case OCH_: /* mark the first two branches */ + FWD(aft, aft, 1); + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + break; + case OOR1: /* done a branch, find the O_CH */ + if (ISSTATEIN(aft, here)) { + for (look = 1; + OP(s = g->strip[pc+look]) != O_CH; + look += OPND(s)) + assert(OP(s) == OOR2); + FWD(aft, aft, look + 1); + } + break; + case OOR2: /* propagate OCH_'s marking */ + FWD(aft, aft, 1); + if (OP(g->strip[pc+OPND(s)]) != O_CH) { + assert(OP(g->strip[pc+OPND(s)]) == OOR2); + FWD(aft, aft, OPND(s)); + } + break; + case O_CH: /* just empty */ + FWD(aft, aft, 1); + break; + default: /* ooooops... */ + assert(0); + break; + } + } + + return (aft); +} + +#ifdef REDEBUG +/* + * print - print a set of states + */ +static void +print(struct match *m, const char *caption, states st, int ch, FILE *d) +{ + struct re_guts *g = m->g; + sopno i; + int first = 1; + + if (!(m->eflags®_TRACE)) + return; + + (void) fprintf(d, "%s", caption); + if (ch != '\0') + (void) fprintf(d, " %s", pchar(ch)); + for (i = 0; i < g->nstates; i++) + if (ISSET(st, i)) { + (void) fprintf(d, "%s%d", (first) ? "\t" : ", ", i); + first = 0; + } + (void) fprintf(d, "\n"); +} + +/* + * at - print current situation + */ +static void +at(struct match *m, const char *title, const char *start, const char *stop, + sopno startst, sopno stopst) +{ + if (!(m->eflags®_TRACE)) + return; + + (void) printf("%s %s-", title, pchar(*start)); + (void) printf("%s ", pchar(*stop)); + (void) printf("%ld-%ld\n", (long)startst, (long)stopst); +} + +#ifndef PCHARDONE +#define PCHARDONE /* never again */ +/* + * pchar - make a character printable + * + * Is this identical to regchar() over in debug.c? Well, yes. But a + * duplicate here avoids having a debugging-capable regexec.o tied to + * a matching debug.o, and this is convenient. It all disappears in + * the non-debug compilation anyway, so it doesn't matter much. + */ +static const char * +pchar(int ch) +{ + static char pbuf[10]; + + if (isprint((uch)ch) || ch == ' ') + (void) sprintf(pbuf, "%c", ch); + else + (void) sprintf(pbuf, "\\%o", ch); + return (pbuf); +} +#endif +#endif + +#undef matcher +#undef fast +#undef slow +#undef dissect +#undef backref +#undef step +#undef print +#undef at +#undef match diff --git a/usr/src/lib/libc/port/regex/regcomp.c b/usr/src/lib/libc/port/regex/regcomp.c new file mode 100644 index 0000000000..c1c1ce90a3 --- /dev/null +++ b/usr/src/lib/libc/port/regex/regcomp.c @@ -0,0 +1,1784 @@ +/* + * Copyright 2013 Garrett D'Amore + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Milan Jurik. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lint.h" +#include "file64.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../locale/runetype.h" +#include "../locale/collate.h" + +#include "utils.h" +#include "regex2.h" + +#include "cname.h" +#include "../locale/mblocal.h" + +/* + * parse structure, passed up and down to avoid global variables and + * other clumsinesses + */ +struct parse { + const char *next; /* next character in RE */ + const char *end; /* end of string (-> NUL normally) */ + int error; /* has an error been seen? */ + sop *strip; /* malloced strip */ + sopno ssize; /* malloced strip size (allocated) */ + sopno slen; /* malloced strip length (used) */ + int ncsalloc; /* number of csets allocated */ + struct re_guts *g; +#define NPAREN 10 /* we need to remember () 1-9 for back refs */ + sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ + sopno pend[NPAREN]; /* -> ) ([0] unused) */ +}; + +/* ========= begin header generated by ./mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === regcomp.c === */ +static void p_ere(struct parse *p, int stop); +static void p_ere_exp(struct parse *p); +static void p_str(struct parse *p); +static void p_bre(struct parse *p, int end1, int end2); +static int p_simp_re(struct parse *p, int starordinary); +static int p_count(struct parse *p); +static void p_bracket(struct parse *p); +static void p_b_term(struct parse *p, cset *cs); +static void p_b_cclass(struct parse *p, cset *cs); +static void p_b_eclass(struct parse *p, cset *cs); +static wint_t p_b_symbol(struct parse *p); +static wint_t p_b_coll_elem(struct parse *p, wint_t endc); +static wint_t othercase(wint_t ch); +static void bothcases(struct parse *p, wint_t ch); +static void ordinary(struct parse *p, wint_t ch); +static void nonnewline(struct parse *p); +static void repeat(struct parse *p, sopno start, int from, int to); +static int seterr(struct parse *p, int e); +static cset *allocset(struct parse *p); +static void freeset(struct parse *p, cset *cs); +static void CHadd(struct parse *p, cset *cs, wint_t ch); +static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max); +static void CHaddtype(struct parse *p, cset *cs, wctype_t wct); +static wint_t singleton(cset *cs); +static sopno dupl(struct parse *p, sopno start, sopno finish); +static void doemit(struct parse *p, sop op, size_t opnd); +static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); +static void dofwd(struct parse *p, sopno pos, sop value); +static int enlarge(struct parse *p, sopno size); +static void stripsnug(struct parse *p, struct re_guts *g); +static void findmust(struct parse *p, struct re_guts *g); +static int altoffset(sop *scan, int offset); +static void computejumps(struct parse *p, struct re_guts *g); +static void computematchjumps(struct parse *p, struct re_guts *g); +static sopno pluscount(struct parse *p, struct re_guts *g); +static wint_t wgetnext(struct parse *p); + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ./mkh ========= */ + +static char nuls[10]; /* place to point scanner in event of error */ + +/* + * macros for use with parse structure + * BEWARE: these know that the parse structure is named `p' !!! + */ +#define PEEK() (*p->next) +#define PEEK2() (*(p->next+1)) +#define MORE() (p->next < p->end) +#define MORE2() (p->next+1 < p->end) +#define SEE(c) (MORE() && PEEK() == (c)) +#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) +#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) +#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) +#define NEXT() (p->next++) +#define NEXT2() (p->next += 2) +#define NEXTn(n) (p->next += (n)) +#define GETNEXT() (*p->next++) +#define WGETNEXT() wgetnext(p) +#define SETERROR(e) ((void)seterr(p, (e))) +#define REQUIRE(co, e) ((co) || seterr(p, e)) +#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) +#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) +#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) +#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) +#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) +#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) +#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) +#define HERE() (p->slen) +#define THERE() (p->slen - 1) +#define THERETHERE() (p->slen - 2) +#define DROP(n) (p->slen -= (n)) + +#ifndef NDEBUG +static int never = 0; /* for use in asserts; shuts lint up */ +#else +#define never 0 /* some s have bugs too */ +#endif + +/* + * regcomp - interface for parser and compilation + */ +int /* 0 success, otherwise REG_something */ +regcomp(regex_t *_RESTRICT_KYWD preg, const char *_RESTRICT_KYWD pattern, + int cflags) +{ + struct parse pa; + struct re_guts *g; + struct parse *p = &pa; + int i; + size_t len; + size_t maxlen; +#ifdef REDEBUG +#define GOODFLAGS(f) (f) +#else +#define GOODFLAGS(f) ((f)&~REG_DUMP) +#endif + + /* We had REG_INVARG, but we don't have that on Solaris. */ + cflags = GOODFLAGS(cflags); + if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) + return (REG_EFATAL); + + if (cflags®_PEND) { + if (preg->re_endp < pattern) + return (REG_EFATAL); + len = preg->re_endp - pattern; + } else + len = strlen(pattern); + + /* do the mallocs early so failure handling is easy */ + g = (struct re_guts *)malloc(sizeof (struct re_guts)); + if (g == NULL) + return (REG_ESPACE); + /* + * Limit the pattern space to avoid a 32-bit overflow on buffer + * extension. Also avoid any signed overflow in case of conversion + * so make the real limit based on a 31-bit overflow. + * + * Likely not applicable on 64-bit systems but handle the case + * generically (who are we to stop people from using ~715MB+ + * patterns?). + */ + maxlen = ((size_t)-1 >> 1) / sizeof (sop) * 2 / 3; + if (len >= maxlen) { + free((char *)g); + return (REG_ESPACE); + } + p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ + assert(p->ssize >= len); + + p->strip = (sop *)malloc(p->ssize * sizeof (sop)); + p->slen = 0; + if (p->strip == NULL) { + free((char *)g); + return (REG_ESPACE); + } + + /* set things up */ + p->g = g; + p->next = pattern; /* convenience; we do not modify it */ + p->end = p->next + len; + p->error = 0; + p->ncsalloc = 0; + for (i = 0; i < NPAREN; i++) { + p->pbegin[i] = 0; + p->pend[i] = 0; + } + g->sets = NULL; + g->ncsets = 0; + g->cflags = cflags; + g->iflags = 0; + g->nbol = 0; + g->neol = 0; + g->must = NULL; + g->moffset = -1; + g->charjump = NULL; + g->matchjump = NULL; + g->mlen = 0; + g->nsub = 0; + g->backrefs = 0; + + /* do it */ + EMIT(OEND, 0); + g->firststate = THERE(); + if (cflags®_EXTENDED) + p_ere(p, OUT); + else if (cflags®_NOSPEC) + p_str(p); + else + p_bre(p, OUT, OUT); + EMIT(OEND, 0); + g->laststate = THERE(); + + /* tidy up loose ends and fill things in */ + stripsnug(p, g); + findmust(p, g); + /* + * only use Boyer-Moore algorithm if the pattern is bigger + * than three characters + */ + if (g->mlen > 3) { + computejumps(p, g); + computematchjumps(p, g); + if (g->matchjump == NULL && g->charjump != NULL) { + free(g->charjump); + g->charjump = NULL; + } + } + g->nplus = pluscount(p, g); + g->magic = MAGIC2; + preg->re_nsub = g->nsub; + preg->re_g = g; + preg->re_magic = MAGIC1; +#ifndef REDEBUG + /* not debugging, so can't rely on the assert() in regexec() */ + if (g->iflags&BAD) + SETERROR(REG_EFATAL); +#endif + + /* win or lose, we're done */ + if (p->error != 0) /* lose */ + regfree(preg); + return (p->error); +} + +/* + * p_ere - ERE parser top level, concatenation and alternation + */ +static void +p_ere(struct parse *p, + int stop) /* character this ERE should end at */ +{ + char c; + sopno prevback; + sopno prevfwd; + sopno conc; + int first = 1; /* is this the first alternative? */ + + for (;;) { + /* do a bunch of concatenated expressions */ + conc = HERE(); + while (MORE() && (c = PEEK()) != '|' && c != stop) + p_ere_exp(p); + /* require nonempty */ + (void) REQUIRE(HERE() != conc, REG_BADPAT); + + if (!EAT('|')) + break; /* NOTE BREAK OUT */ + + if (first) { + INSERT(OCH_, conc); /* offset is wrong */ + prevfwd = conc; + prevback = conc; + first = 0; + } + ASTERN(OOR1, prevback); + prevback = THERE(); + AHEAD(prevfwd); /* fix previous offset */ + prevfwd = HERE(); + EMIT(OOR2, 0); /* offset is very wrong */ + } + + if (!first) { /* tail-end fixups */ + AHEAD(prevfwd); + ASTERN(O_CH, prevback); + } + + assert(!MORE() || SEE(stop)); +} + +/* + * p_ere_exp - parse one subERE, an atom possibly followed by a repetition op + */ +static void +p_ere_exp(struct parse *p) +{ + char c; + wint_t wc; + sopno pos; + int count; + int count2; + sopno subno; + int wascaret = 0; + + assert(MORE()); /* caller should have ensured this */ + c = GETNEXT(); + + pos = HERE(); + switch (c) { + case '(': + (void) REQUIRE(MORE(), REG_EPAREN); + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + if (!SEE(')')) + p_ere(p, ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + (void) MUSTEAT(')', REG_EPAREN); + break; +#ifndef POSIX_MISTAKE + case ')': /* happens only if no current unmatched ( */ + /* + * You may ask, why the ifndef? Because I didn't notice + * this until slightly too late for 1003.2, and none of the + * other 1003.2 regular-expression reviewers noticed it at + * all. So an unmatched ) is legal POSIX, at least until + * we can get it fixed. + */ + SETERROR(REG_EPAREN); + break; +#endif + case '^': + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + wascaret = 1; + break; + case '$': + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + break; + case '|': + SETERROR(REG_BADPAT); + break; + case '*': + case '+': + case '?': + SETERROR(REG_BADRPT); + break; + case '.': + if (p->g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case '\\': + (void) REQUIRE(MORE(), REG_EESCAPE); + wc = WGETNEXT(); + switch (wc) { + case '<': + EMIT(OBOW, 0); + break; + case '>': + EMIT(OEOW, 0); + break; + default: + ordinary(p, wc); + break; + } + break; + case '{': /* okay as ordinary except if digit follows */ + (void) REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); + /* FALLTHROUGH */ + default: + if (p->error != 0) + return; + p->next--; + wc = WGETNEXT(); + ordinary(p, wc); + break; + } + + if (!MORE()) + return; + c = PEEK(); + /* we call { a repetition if followed by a digit */ + if (!(c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit((uch)PEEK2())))) + return; /* no repetition, we're done */ + NEXT(); + + (void) REQUIRE(!wascaret, REG_BADRPT); + switch (c) { + case '*': /* implemented as +? */ + /* this case does not require the (y|) trick, noKLUDGE */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + break; + case '+': + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + break; + case '?': + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, pos); /* offset slightly wrong */ + ASTERN(OOR1, pos); /* this one's right */ + AHEAD(pos); /* fix the OCH_ */ + EMIT(OOR2, 0); /* offset very wrong... */ + AHEAD(THERE()); /* ...so fix it */ + ASTERN(O_CH, THERETHERE()); + break; + case '{': + count = p_count(p); + if (EAT(',')) { + if (isdigit((uch)PEEK())) { + count2 = p_count(p); + (void) REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EAT('}')) { /* error heuristics */ + while (MORE() && PEEK() != '}') + NEXT(); + (void) REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + break; + } + + if (!MORE()) + return; + c = PEEK(); + if (!(c == '*' || c == '+' || c == '?' || + (c == '{' && MORE2() && isdigit((uch)PEEK2())))) + return; + SETERROR(REG_BADRPT); +} + +/* + * p_str - string (no metacharacters) "parser" + */ +static void +p_str(struct parse *p) +{ + (void) REQUIRE(MORE(), REG_BADPAT); + while (MORE()) + ordinary(p, WGETNEXT()); +} + +/* + * p_bre - BRE parser top level, anchoring and concatenation + * Giving end1 as OUT essentially eliminates the end1/end2 check. + * + * This implementation is a bit of a kludge, in that a trailing $ is first + * taken as an ordinary character and then revised to be an anchor. + * The amount of lookahead needed to avoid this kludge is excessive. + */ +static void +p_bre(struct parse *p, + int end1, /* first terminating character */ + int end2) /* second terminating character */ +{ + sopno start = HERE(); + int first = 1; /* first subexpression? */ + int wasdollar = 0; + + if (EAT('^')) { + EMIT(OBOL, 0); + p->g->iflags |= USEBOL; + p->g->nbol++; + } + while (MORE() && !SEETWO(end1, end2)) { + wasdollar = p_simp_re(p, first); + first = 0; + } + if (wasdollar) { /* oops, that was a trailing anchor */ + DROP(1); + EMIT(OEOL, 0); + p->g->iflags |= USEEOL; + p->g->neol++; + } + + (void) REQUIRE(HERE() != start, REG_BADPAT); /* require nonempty */ +} + +/* + * p_simp_re - parse a simple RE, an atom possibly followed by a repetition + */ +static int /* was the simple RE an unbackslashed $? */ +p_simp_re(struct parse *p, + int starordinary) /* is a leading * an ordinary character? */ +{ + int c; + int count; + int count2; + sopno pos; + int i; + wint_t wc; + sopno subno; +#define BACKSL (1<g->cflags®_NEWLINE) + nonnewline(p); + else + EMIT(OANY, 0); + break; + case '[': + p_bracket(p); + break; + case BACKSL|'<': + EMIT(OBOW, 0); + break; + case BACKSL|'>': + EMIT(OEOW, 0); + break; + case BACKSL|'{': + SETERROR(REG_BADRPT); + break; + case BACKSL|'(': + p->g->nsub++; + subno = p->g->nsub; + if (subno < NPAREN) + p->pbegin[subno] = HERE(); + EMIT(OLPAREN, subno); + /* the MORE here is an error heuristic */ + if (MORE() && !SEETWO('\\', ')')) + p_bre(p, '\\', ')'); + if (subno < NPAREN) { + p->pend[subno] = HERE(); + assert(p->pend[subno] != 0); + } + EMIT(ORPAREN, subno); + (void) REQUIRE(EATTWO('\\', ')'), REG_EPAREN); + break; + case BACKSL|')': /* should not get here -- must be user */ + case BACKSL|'}': + SETERROR(REG_EPAREN); + break; + case BACKSL|'1': + case BACKSL|'2': + case BACKSL|'3': + case BACKSL|'4': + case BACKSL|'5': + case BACKSL|'6': + case BACKSL|'7': + case BACKSL|'8': + case BACKSL|'9': + i = (c&~BACKSL) - '0'; + assert(i < NPAREN); + if (p->pend[i] != 0) { + assert(i <= p->g->nsub); + EMIT(OBACK_, i); + assert(p->pbegin[i] != 0); + assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); + assert(OP(p->strip[p->pend[i]]) == ORPAREN); + (void) dupl(p, p->pbegin[i]+1, p->pend[i]); + EMIT(O_BACK, i); + } else + SETERROR(REG_ESUBREG); + p->g->backrefs = 1; + break; + case '*': + (void) REQUIRE(starordinary, REG_BADRPT); + /* FALLTHROUGH */ + default: + if (p->error != 0) + return (0); /* Definitely not $... */ + p->next--; + wc = WGETNEXT(); + ordinary(p, wc); + break; + } + + if (EAT('*')) { /* implemented as +? */ + /* this case does not require the (y|) trick, noKLUDGE */ + INSERT(OPLUS_, pos); + ASTERN(O_PLUS, pos); + INSERT(OQUEST_, pos); + ASTERN(O_QUEST, pos); + } else if (EATTWO('\\', '{')) { + count = p_count(p); + if (EAT(',')) { + if (MORE() && isdigit((uch)PEEK())) { + count2 = p_count(p); + (void) REQUIRE(count <= count2, REG_BADBR); + } else /* single number with comma */ + count2 = INFINITY; + } else /* just a single number */ + count2 = count; + repeat(p, pos, count, count2); + if (!EATTWO('\\', '}')) { /* error heuristics */ + while (MORE() && !SEETWO('\\', '}')) + NEXT(); + (void) REQUIRE(MORE(), REG_EBRACE); + SETERROR(REG_BADBR); + } + } else if (c == '$') /* $ (but not \$) ends it */ + return (1); + + return (0); +} + +/* + * p_count - parse a repetition count + */ +static int /* the value */ +p_count(struct parse *p) +{ + int count = 0; + int ndigits = 0; + + while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { + count = count*10 + (GETNEXT() - '0'); + ndigits++; + } + + (void) REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); + return (count); +} + +/* + * p_bracket - parse a bracketed character list + */ +static void +p_bracket(struct parse *p) +{ + cset *cs; + wint_t ch; + + /* Dept of Truly Sickening Special-Case Kludges */ + if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { + EMIT(OBOW, 0); + NEXTn(6); + return; + } + if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { + EMIT(OEOW, 0); + NEXTn(6); + return; + } + + if ((cs = allocset(p)) == NULL) + return; + + if (p->g->cflags®_ICASE) + cs->icase = 1; + if (EAT('^')) + cs->invert = 1; + if (EAT(']')) + CHadd(p, cs, ']'); + else if (EAT('-')) + CHadd(p, cs, '-'); + while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) + p_b_term(p, cs); + if (EAT('-')) + CHadd(p, cs, '-'); + (void) MUSTEAT(']', REG_EBRACK); + + if (p->error != 0) /* don't mess things up further */ + return; + + if (cs->invert && p->g->cflags®_NEWLINE) + cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); + + if ((ch = singleton(cs)) != OUT) { /* optimize singleton sets */ + ordinary(p, ch); + freeset(p, cs); + } else + EMIT(OANYOF, (int)(cs - p->g->sets)); +} + +/* + * p_b_term - parse one term of a bracketed character list + */ +static void +p_b_term(struct parse *p, cset *cs) +{ + char c; + wint_t start, finish; + wint_t i; + locale_t loc = uselocale(NULL); + + /* classify what we've got */ + switch ((MORE()) ? PEEK() : '\0') { + case '[': + c = (MORE2()) ? PEEK2() : '\0'; + break; + case '-': + SETERROR(REG_ERANGE); + return; /* NOTE RETURN */ + default: + c = '\0'; + break; + } + + switch (c) { + case ':': /* character class */ + NEXT2(); + (void) REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); + (void) REQUIRE(c != '-' && c != ']', REG_ECTYPE); + p_b_cclass(p, cs); + (void) REQUIRE(MORE(), REG_EBRACK); + (void) REQUIRE(EATTWO(':', ']'), REG_ECTYPE); + break; + case '=': /* equivalence class */ + NEXT2(); + (void) REQUIRE(MORE(), REG_EBRACK); + c = PEEK(); + (void) REQUIRE(c != '-' && c != ']', REG_ECOLLATE); + p_b_eclass(p, cs); + (void) REQUIRE(MORE(), REG_EBRACK); + (void) REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); + break; + default: /* symbol, ordinary character, or range */ + start = p_b_symbol(p); + if (SEE('-') && MORE2() && PEEK2() != ']') { + /* range */ + NEXT(); + if (EAT('-')) + finish = '-'; + else + finish = p_b_symbol(p); + } else + finish = start; + if (start == finish) + CHadd(p, cs, start); + else { + if (loc->collate->lc_is_posix) { + (void) REQUIRE((uch)start <= (uch)finish, + REG_ERANGE); + CHaddrange(p, cs, start, finish); + } else { + (void) REQUIRE(_collate_range_cmp(start, + finish, loc) <= 0, REG_ERANGE); + for (i = 0; i <= UCHAR_MAX; i++) { + if (_collate_range_cmp(start, i, loc) + <= 0 && + _collate_range_cmp(i, finish, loc) + <= 0) + CHadd(p, cs, i); + } + } + } + break; + } +} + +/* + * p_b_cclass - parse a character-class name and deal with it + */ +static void +p_b_cclass(struct parse *p, cset *cs) +{ + const char *sp = p->next; + size_t len; + wctype_t wct; + char clname[16]; + + while (MORE() && isalpha((uch)PEEK())) + NEXT(); + len = p->next - sp; + if (len >= sizeof (clname) - 1) { + SETERROR(REG_ECTYPE); + return; + } + (void) memcpy(clname, sp, len); + clname[len] = '\0'; + if ((wct = wctype(clname)) == 0) { + SETERROR(REG_ECTYPE); + return; + } + CHaddtype(p, cs, wct); +} + +/* + * p_b_eclass - parse an equivalence-class name and deal with it + * + * This implementation is incomplete. xxx + */ +static void +p_b_eclass(struct parse *p, cset *cs) +{ + wint_t c; + + c = p_b_coll_elem(p, '='); + CHadd(p, cs, c); +} + +/* + * p_b_symbol - parse a character or [..]ed multicharacter collating symbol + */ +static wint_t /* value of symbol */ +p_b_symbol(struct parse *p) +{ + wint_t value; + + (void) REQUIRE(MORE(), REG_EBRACK); + if (!EATTWO('[', '.')) + return (WGETNEXT()); + + /* collating symbol */ + value = p_b_coll_elem(p, '.'); + (void) REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); + return (value); +} + +/* + * p_b_coll_elem - parse a collating-element name and look it up + */ +static wint_t /* value of collating element */ +p_b_coll_elem(struct parse *p, + wint_t endc) /* name ended by endc,']' */ +{ + const char *sp = p->next; + struct cname *cp; + mbstate_t mbs; + wchar_t wc; + size_t clen, len; + + while (MORE() && !SEETWO(endc, ']')) + NEXT(); + if (!MORE()) { + SETERROR(REG_EBRACK); + return (0); + } + len = p->next - sp; + for (cp = cnames; cp->name != NULL; cp++) + if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') + return (cp->code); /* known name */ + (void) memset(&mbs, 0, sizeof (mbs)); + if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) + return (wc); /* single character */ + else if (clen == (size_t)-1 || clen == (size_t)-2) + SETERROR(REG_ECHAR); + else + SETERROR(REG_ECOLLATE); /* neither */ + return (0); +} + +/* + * othercase - return the case counterpart of an alphabetic + */ +static wint_t /* if no counterpart, return ch */ +othercase(wint_t ch) +{ + assert(iswalpha(ch)); + if (iswupper(ch)) + return (towlower(ch)); + else if (iswlower(ch)) + return (towupper(ch)); + else /* peculiar, but could happen */ + return (ch); +} + +/* + * bothcases - emit a dualcase version of a two-case character + * + * Boy, is this implementation ever a kludge... + */ +static void +bothcases(struct parse *p, wint_t ch) +{ + const char *oldnext = p->next; + const char *oldend = p->end; + char bracket[3 + MB_LEN_MAX]; + size_t n; + mbstate_t mbs; + + assert(othercase(ch) != ch); /* p_bracket() would recurse */ + p->next = bracket; + (void) memset(&mbs, 0, sizeof (mbs)); + n = wcrtomb(bracket, ch, &mbs); + assert(n != (size_t)-1); + bracket[n] = ']'; + bracket[n + 1] = '\0'; + p->end = bracket+n+1; + p_bracket(p); + assert(p->next == p->end); + p->next = oldnext; + p->end = oldend; +} + +/* + * ordinary - emit an ordinary character + */ +static void +ordinary(struct parse *p, wint_t ch) +{ + cset *cs; + + if ((p->g->cflags®_ICASE) && iswalpha(ch) && othercase(ch) != ch) + bothcases(p, ch); + else if ((ch & OPDMASK) == ch) + EMIT(OCHAR, ch); + else { + /* + * Kludge: character is too big to fit into an OCHAR operand. + * Emit a singleton set. + */ + if ((cs = allocset(p)) == NULL) + return; + CHadd(p, cs, ch); + EMIT(OANYOF, (int)(cs - p->g->sets)); + } +} + +/* + * nonnewline - emit REG_NEWLINE version of OANY + * + * Boy, is this implementation ever a kludge... + */ +static void +nonnewline(struct parse *p) +{ + const char *oldnext = p->next; + const char *oldend = p->end; + char bracket[4]; + + p->next = bracket; + p->end = bracket+3; + bracket[0] = '^'; + bracket[1] = '\n'; + bracket[2] = ']'; + bracket[3] = '\0'; + p_bracket(p); + assert(p->next == bracket+3); + p->next = oldnext; + p->end = oldend; +} + +/* + * repeat - generate code for a bounded repetition, recursively if needed + */ +static void +repeat(struct parse *p, + sopno start, /* operand from here to end of strip */ + int from, /* repeated from this number */ + int to) /* to this number of times (maybe INFINITY) */ +{ + sopno finish = HERE(); +#define N 2 +#define INF 3 +#define REP(f, t) ((f)*8 + (t)) +#define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) + sopno copy; + + if (p->error != 0) /* head off possible runaway recursion */ + return; + + assert(from <= to); + + switch (REP(MAP(from), MAP(to))) { + case REP(0, 0): /* must be user doing this */ + DROP(finish-start); /* drop the operand */ + break; + case REP(0, 1): /* as x{1,1}? */ + case REP(0, N): /* as x{1,n}? */ + case REP(0, INF): /* as x{1,}? */ + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, start); /* offset is wrong... */ + repeat(p, start+1, 1, to); + ASTERN(OOR1, start); + AHEAD(start); /* ... fix it */ + EMIT(OOR2, 0); + AHEAD(THERE()); + ASTERN(O_CH, THERETHERE()); + break; + case REP(1, 1): /* trivial case */ + /* done */ + break; + case REP(1, N): /* as x?x{1,n-1} */ + /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ + INSERT(OCH_, start); + ASTERN(OOR1, start); + AHEAD(start); + EMIT(OOR2, 0); /* offset very wrong... */ + AHEAD(THERE()); /* ...so fix it */ + ASTERN(O_CH, THERETHERE()); + copy = dupl(p, start+1, finish+1); + assert(copy == finish+4); + repeat(p, copy, 1, to-1); + break; + case REP(1, INF): /* as x+ */ + INSERT(OPLUS_, start); + ASTERN(O_PLUS, start); + break; + case REP(N, N): /* as xx{m-1,n-1} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to-1); + break; + case REP(N, INF): /* as xx{n-1,INF} */ + copy = dupl(p, start, finish); + repeat(p, copy, from-1, to); + break; + default: /* "can't happen" */ + SETERROR(REG_EFATAL); /* just in case */ + break; + } +} + +/* + * wgetnext - helper function for WGETNEXT() macro. Gets the next wide + * character from the parse struct, signals a REG_ILLSEQ error if the + * character can't be converted. Returns the number of bytes consumed. + */ +static wint_t +wgetnext(struct parse *p) +{ + mbstate_t mbs; + wchar_t wc; + size_t n; + + (void) memset(&mbs, 0, sizeof (mbs)); + n = mbrtowc(&wc, p->next, p->end - p->next, &mbs); + if (n == (size_t)-1 || n == (size_t)-2) { + SETERROR(REG_ECHAR); + return (0); + } + if (n == 0) + n = 1; + p->next += n; + return (wc); +} + +/* + * seterr - set an error condition + */ +static int /* useless but makes type checking happy */ +seterr(struct parse *p, int e) +{ + if (p->error == 0) /* keep earliest error condition */ + p->error = e; + p->next = nuls; /* try to bring things to a halt */ + p->end = nuls; + return (0); /* make the return value well-defined */ +} + +/* + * allocset - allocate a set of characters for [] + */ +static cset * +allocset(struct parse *p) +{ + cset *cs, *ncs; + + ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof (*ncs)); + if (ncs == NULL) { + SETERROR(REG_ESPACE); + return (NULL); + } + p->g->sets = ncs; + cs = &p->g->sets[p->g->ncsets++]; + (void) memset(cs, 0, sizeof (*cs)); + + return (cs); +} + +/* + * freeset - free a now-unused set + */ +static void +freeset(struct parse *p, cset *cs) +{ + cset *top = &p->g->sets[p->g->ncsets]; + + free(cs->wides); + free(cs->ranges); + free(cs->types); + (void) memset(cs, 0, sizeof (*cs)); + if (cs == top-1) /* recover only the easy case */ + p->g->ncsets--; +} + +/* + * singleton - Determine whether a set contains only one character, + * returning it if so, otherwise returning OUT. + */ +static wint_t +singleton(cset *cs) +{ + wint_t i, s, n; + + for (i = n = 0; i < NC; i++) + if (CHIN(cs, i)) { + n++; + s = i; + } + if (n == 1) + return (s); + if (cs->nwides == 1 && cs->nranges == 0 && cs->ntypes == 0 && + cs->icase == 0) + return (cs->wides[0]); + /* Don't bother handling the other cases. */ + return (OUT); +} + +/* + * CHadd - add character to character set. + */ +static void +CHadd(struct parse *p, cset *cs, wint_t ch) +{ + wint_t nch, *newwides; + assert(ch >= 0); + if (ch < NC) + cs->bmp[ch >> 3] |= 1 << (ch & 7); + else { + newwides = realloc(cs->wides, (cs->nwides + 1) * + sizeof (*cs->wides)); + if (newwides == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->wides = newwides; + cs->wides[cs->nwides++] = ch; + } + if (cs->icase) { + if ((nch = towlower(ch)) < NC) + cs->bmp[nch >> 3] |= 1 << (nch & 7); + if ((nch = towupper(ch)) < NC) + cs->bmp[nch >> 3] |= 1 << (nch & 7); + } +} + +/* + * CHaddrange - add all characters in the range [min,max] to a character set. + */ +static void +CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) +{ + crange *newranges; + + for (; min < NC && min <= max; min++) + CHadd(p, cs, min); + if (min >= max) + return; + newranges = realloc(cs->ranges, (cs->nranges + 1) * + sizeof (*cs->ranges)); + if (newranges == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->ranges = newranges; + cs->ranges[cs->nranges].min = min; + cs->ranges[cs->nranges].max = max; + cs->nranges++; +} + +/* + * CHaddtype - add all characters of a certain type to a character set. + */ +static void +CHaddtype(struct parse *p, cset *cs, wctype_t wct) +{ + wint_t i; + wctype_t *newtypes; + + for (i = 0; i < NC; i++) + if (iswctype(i, wct)) + CHadd(p, cs, i); + newtypes = realloc(cs->types, (cs->ntypes + 1) * + sizeof (*cs->types)); + if (newtypes == NULL) { + SETERROR(REG_ESPACE); + return; + } + cs->types = newtypes; + cs->types[cs->ntypes++] = wct; +} + +/* + * dupl - emit a duplicate of a bunch of sops + */ +static sopno /* start of duplicate */ +dupl(struct parse *p, + sopno start, /* from here */ + sopno finish) /* to this less one */ +{ + sopno ret = HERE(); + sopno len = finish - start; + + assert(finish >= start); + if (len == 0) + return (ret); + if (!enlarge(p, p->ssize + len)) /* this many unexpected additions */ + return (ret); + assert(p->ssize >= p->slen + len); + (void) memcpy((char *)(p->strip + p->slen), + (char *)(p->strip + start), (size_t)len*sizeof (sop)); + p->slen += len; + return (ret); +} + +/* + * doemit - emit a strip operator + * + * It might seem better to implement this as a macro with a function as + * hard-case backup, but it's just too big and messy unless there are + * some changes to the data structures. Maybe later. + */ +static void +doemit(struct parse *p, sop op, size_t opnd) +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* deal with oversize operands ("can't happen", more or less) */ + assert(opnd < 1<slen >= p->ssize) + if (!enlarge(p, (p->ssize+1) / 2 * 3)) /* +50% */ + return; + + /* finally, it's all reduced to the easy case */ + p->strip[p->slen++] = SOP(op, opnd); +} + +/* + * doinsert - insert a sop into the strip + */ +static void +doinsert(struct parse *p, sop op, size_t opnd, sopno pos) +{ + sopno sn; + sop s; + int i; + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + sn = HERE(); + EMIT(op, opnd); /* do checks, ensure space */ + assert(HERE() == sn+1); + s = p->strip[sn]; + + /* adjust paren pointers */ + assert(pos > 0); + for (i = 1; i < NPAREN; i++) { + if (p->pbegin[i] >= pos) { + p->pbegin[i]++; + } + if (p->pend[i] >= pos) { + p->pend[i]++; + } + } + + (void) memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], + (HERE()-pos-1)*sizeof (sop)); + p->strip[pos] = s; +} + +/* + * dofwd - complete a forward reference + */ +static void +dofwd(struct parse *p, sopno pos, sop value) +{ + /* avoid making error situations worse */ + if (p->error != 0) + return; + + assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; +} + +/* + * enlarge - enlarge the strip + */ +static int +enlarge(struct parse *p, sopno size) +{ + sop *sp; + + if (p->ssize >= size) + return (1); + + sp = (sop *)realloc(p->strip, size*sizeof (sop)); + if (sp == NULL) { + SETERROR(REG_ESPACE); + return (0); + } + p->strip = sp; + p->ssize = size; + return (1); +} + +/* + * stripsnug - compact the strip + */ +static void +stripsnug(struct parse *p, struct re_guts *g) +{ + g->nstates = p->slen; + g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof (sop)); + if (g->strip == NULL) { + SETERROR(REG_ESPACE); + g->strip = p->strip; + } +} + +/* + * findmust - fill in must and mlen with longest mandatory literal string + * + * This algorithm could do fancy things like analyzing the operands of | + * for common subsequences. Someday. This code is simple and finds most + * of the interesting cases. + * + * Note that must and mlen got initialized during setup. + */ +static void +findmust(struct parse *p, struct re_guts *g) +{ + sop *scan; + sop *start = NULL; + sop *newstart = NULL; + sopno newlen; + sop s; + char *cp; + int offset; + char buf[MB_LEN_MAX]; + size_t clen; + mbstate_t mbs; + locale_t loc = uselocale(NULL); + + /* avoid making error situations worse */ + if (p->error != 0) + return; + + /* + * It's not generally safe to do a ``char'' substring search on + * multibyte character strings, but it's safe for at least + * UTF-8 (see RFC 3629). + */ + if (MB_CUR_MAX > 1 && + strcmp(loc->runelocale->__encoding, "UTF-8") != 0) + return; + + /* find the longest OCHAR sequence in strip */ + newlen = 0; + offset = 0; + g->moffset = 0; + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OCHAR: /* sequence member */ + if (newlen == 0) { /* new sequence */ + (void) memset(&mbs, 0, sizeof (mbs)); + newstart = scan - 1; + } + clen = wcrtomb(buf, OPND(s), &mbs); + if (clen == (size_t)-1) + goto toohard; + newlen += clen; + break; + case OPLUS_: /* things that don't break one */ + case OLPAREN: + case ORPAREN: + break; + case OQUEST_: /* things that must be skipped */ + case OCH_: + offset = altoffset(scan, offset); + scan--; + do { + scan += OPND(s); + s = *scan; + /* assert() interferes w debug printouts */ + if (OP(s) != O_QUEST && OP(s) != O_CH && + OP(s) != OOR2) { + g->iflags |= BAD; + return; + } + } while (OP(s) != O_QUEST && OP(s) != O_CH); + /* FALLTHROUGH */ + case OBOW: /* things that break a sequence */ + case OEOW: + case OBOL: + case OEOL: + case O_QUEST: + case O_CH: + case OEND: + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + newlen = 0; + break; + case OANY: + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + if (offset > -1) + offset++; + newlen = 0; + break; + case OANYOF: /* may or may not invalidate offset */ + /* First, everything as OANY */ + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) { + g->moffset += offset; + offset = newlen; + } else + g->moffset = offset; + } else { + if (offset > -1) + offset += newlen; + } + if (offset > -1) + offset++; + newlen = 0; + break; + toohard: + default: + /* + * Anything here makes it impossible or too hard + * to calculate the offset -- so we give up; + * save the last known good offset, in case the + * must sequence doesn't occur later. + */ + if (newlen > g->mlen) { /* ends one */ + start = newstart; + g->mlen = newlen; + if (offset > -1) + g->moffset += offset; + else + g->moffset = offset; + } + offset = -1; + newlen = 0; + break; + } + } while (OP(s) != OEND); + + if (g->mlen == 0) { /* there isn't one */ + g->moffset = -1; + return; + } + + /* turn it into a character string */ + g->must = malloc((size_t)g->mlen + 1); + if (g->must == NULL) { /* argh; just forget it */ + g->mlen = 0; + g->moffset = -1; + return; + } + cp = g->must; + scan = start; + (void) memset(&mbs, 0, sizeof (mbs)); + while (cp < g->must + g->mlen) { + while (OP(s = *scan++) != OCHAR) + continue; + clen = wcrtomb(cp, OPND(s), &mbs); + assert(clen != (size_t)-1); + cp += clen; + } + assert(cp == g->must + g->mlen); + *cp++ = '\0'; /* just on general principles */ +} + +/* + * altoffset - choose biggest offset among multiple choices + * + * Compute, recursively if necessary, the largest offset among multiple + * re paths. + */ +static int +altoffset(sop *scan, int offset) +{ + int largest; + int try; + sop s; + + /* If we gave up already on offsets, return */ + if (offset == -1) + return (-1); + + largest = 0; + try = 0; + s = *scan++; + while (OP(s) != O_QUEST && OP(s) != O_CH) { + switch (OP(s)) { + case OOR1: + if (try > largest) + largest = try; + try = 0; + break; + case OQUEST_: + case OCH_: + try = altoffset(scan, try); + if (try == -1) + return (-1); + scan--; + do { + scan += OPND(s); + s = *scan; + if (OP(s) != O_QUEST && OP(s) != O_CH && + OP(s) != OOR2) + return (-1); + } while (OP(s) != O_QUEST && OP(s) != O_CH); + /* + * We must skip to the next position, or we'll + * leave altoffset() too early. + */ + scan++; + break; + case OANYOF: + case OCHAR: + case OANY: + try++; + /*FALLTHRU*/ + case OBOW: + case OEOW: + case OLPAREN: + case ORPAREN: + case OOR2: + break; + default: + try = -1; + break; + } + if (try == -1) + return (-1); + s = *scan++; + } + + if (try > largest) + largest = try; + + return (largest+offset); +} + +/* + * computejumps - compute char jumps for BM scan + * + * This algorithm assumes g->must exists and is has size greater than + * zero. It's based on the algorithm found on Computer Algorithms by + * Sara Baase. + * + * A char jump is the number of characters one needs to jump based on + * the value of the character from the text that was mismatched. + */ +static void +computejumps(struct parse *p, struct re_guts *g) +{ + int ch; + int mindex; + + /* Avoid making errors worse */ + if (p->error != 0) + return; + + g->charjump = (int *)malloc((NC + 1) * sizeof (int)); + if (g->charjump == NULL) /* Not a fatal error */ + return; + /* Adjust for signed chars, if necessary */ + g->charjump = &g->charjump[-(CHAR_MIN)]; + + /* + * If the character does not exist in the pattern, the jump + * is equal to the number of characters in the pattern. + */ + for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++) + g->charjump[ch] = g->mlen; + + /* + * If the character does exist, compute the jump that would + * take us to the last character in the pattern equal to it + * (notice that we match right to left, so that last character + * is the first one that would be matched). + */ + for (mindex = 0; mindex < g->mlen; mindex++) + g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1; +} + +/* + * computematchjumps - compute match jumps for BM scan + * + * This algorithm assumes g->must exists and is has size greater than + * zero. It's based on the algorithm found on Computer Algorithms by + * Sara Baase. + * + * A match jump is the number of characters one needs to advance based + * on the already-matched suffix. + * Notice that all values here are minus (g->mlen-1), because of the way + * the search algorithm works. + */ +static void +computematchjumps(struct parse *p, struct re_guts *g) +{ + int mindex; /* General "must" iterator */ + int suffix; /* Keeps track of matching suffix */ + int ssuffix; /* Keeps track of suffixes' suffix */ + int *pmatches; + /* + * pmatches[k] points to the next i + * such that i+1...mlen is a substring + * of k+1...k+mlen-i-1 + */ + + /* Avoid making errors worse */ + if (p->error != 0) + return; + + pmatches = (int *)malloc(g->mlen * sizeof (unsigned int)); + if (pmatches == NULL) { + g->matchjump = NULL; + return; + } + + g->matchjump = (int *)malloc(g->mlen * sizeof (unsigned int)); + if (g->matchjump == NULL) { /* Not a fatal error */ + free(pmatches); + return; + } + + /* Set maximum possible jump for each character in the pattern */ + for (mindex = 0; mindex < g->mlen; mindex++) + g->matchjump[mindex] = 2*g->mlen - mindex - 1; + + /* Compute pmatches[] */ + for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0; + mindex--, suffix--) { + pmatches[mindex] = suffix; + + /* + * If a mismatch is found, interrupting the substring, + * compute the matchjump for that position. If no + * mismatch is found, then a text substring mismatched + * against the suffix will also mismatch against the + * substring. + */ + while (suffix < g->mlen && g->must[mindex] != g->must[suffix]) { + g->matchjump[suffix] = MIN(g->matchjump[suffix], + g->mlen - mindex - 1); + suffix = pmatches[suffix]; + } + } + + /* + * Compute the matchjump up to the last substring found to jump + * to the beginning of the largest must pattern prefix matching + * it's own suffix. + */ + for (mindex = 0; mindex <= suffix; mindex++) + g->matchjump[mindex] = MIN(g->matchjump[mindex], + g->mlen + suffix - mindex); + + ssuffix = pmatches[suffix]; + while (suffix < g->mlen) { + while (suffix <= ssuffix && suffix < g->mlen) { + g->matchjump[suffix] = MIN(g->matchjump[suffix], + g->mlen + ssuffix - suffix); + suffix++; + } + if (suffix < g->mlen) + ssuffix = pmatches[ssuffix]; + } + + free(pmatches); +} + +/* + * pluscount - count + nesting + */ +static sopno /* nesting depth */ +pluscount(struct parse *p, struct re_guts *g) +{ + sop *scan; + sop s; + sopno plusnest = 0; + sopno maxnest = 0; + + if (p->error != 0) + return (0); /* there may not be an OEND */ + + scan = g->strip + 1; + do { + s = *scan++; + switch (OP(s)) { + case OPLUS_: + plusnest++; + break; + case O_PLUS: + if (plusnest > maxnest) + maxnest = plusnest; + plusnest--; + break; + } + } while (OP(s) != OEND); + if (plusnest != 0) + g->iflags |= BAD; + return (maxnest); +} diff --git a/usr/src/lib/libc/port/regex/regerror.c b/usr/src/lib/libc/port/regex/regerror.c new file mode 100644 index 0000000000..3915c4429b --- /dev/null +++ b/usr/src/lib/libc/port/regex/regerror.c @@ -0,0 +1,112 @@ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lint.h" +#include "file64.h" +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "../gen/_libc_gettext.h" + +#define RERR(x, msg) { x, #x, msg } + +static struct rerr { + int code; + const char *name; + const char *explain; +} rerrs[] = { + RERR(REG_NOMATCH, "regexec() failed to match"), + RERR(REG_BADPAT, "invalid regular expression"), + RERR(REG_ECOLLATE, "invalid collating element"), + RERR(REG_ECTYPE, "invalid character class"), + RERR(REG_EESCAPE, "trailing backslash (\\)"), + RERR(REG_ESUBREG, "invalid backreference number"), + RERR(REG_EBRACK, "brackets ([ ]) not balanced"), + RERR(REG_EPAREN, "parentheses not balanced"), + RERR(REG_EBRACE, "braces not balanced"), + RERR(REG_BADBR, "invalid repetition count(s)"), + RERR(REG_ERANGE, "invalid character range"), + RERR(REG_ESPACE, "out of memory"), + RERR(REG_BADRPT, "repetition-operator operand invalid"), +#ifdef REG_EMPTY + RERR(REG_EMPTY, "empty (sub)expression"), +#endif + RERR(REG_EFATAL, "fatal internal error"), +#ifdef REG_INVARG + RERR(REG_INVARG, "invalid argument to regex routine"), +#endif + RERR(REG_ECHAR, "illegal byte sequence"), + RERR(REG_ENOSYS, "function not supported"), + RERR(REG_STACK, "backtrack stack overflow"), + RERR(REG_ENSUB, "more than 9 \\( \\) pairs"), + RERR(REG_ENEWLINE, "\n found before end of pattern"), + {0, "", "*** unknown regexp error code ***"} +}; + + +/* + * regerror - the interface to error numbers + */ +/* ARGSUSED */ +size_t +regerror(int errcode, const regex_t *_RESTRICT_KYWD preg, + char *_RESTRICT_KYWD errbuf, size_t errbuf_size) +{ + struct rerr *r; + size_t len; + const char *s; + + for (r = rerrs; r->code != 0; r++) + if (r->code == errcode) + break; + + s = _libc_gettext(r->explain); + + len = strlen(s) + 1; + if (errbuf_size > 0) { + if (errbuf_size > len) + (void) strcpy(errbuf, s); + else { + (void) strncpy(errbuf, s, errbuf_size-1); + errbuf[errbuf_size-1] = '\0'; + } + } + + return (len); +} diff --git a/usr/src/lib/libc/port/regex/regex2.h b/usr/src/lib/libc/port/regex/regex2.h new file mode 100644 index 0000000000..551611c610 --- /dev/null +++ b/usr/src/lib/libc/port/regex/regex2.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * First, the stuff that ends up in the outside-world include file + * typedef off_t regoff_t; + * typedef struct { + * int re_magic; + * size_t re_nsub; // number of parenthesized subexpressions + * const char *re_endp; // end pointer for REG_PEND + * struct re_guts *re_g; // none of your business :-) + * } regex_t; + * typedef struct { + * regoff_t rm_so; // start of match + * regoff_t rm_eo; // end of match + * } regmatch_t; + */ +/* + * internals of regex_t + */ +#define MAGIC1 ((('r'^0200)<<8) | 'e') + +/* + * The internal representation is a *strip*, a sequence of + * operators ending with an endmarker. (Some terminology etc. is a + * historical relic of earlier versions which used multiple strips.) + * Certain oddities in the representation are there to permit running + * the machinery backwards; in particular, any deviation from sequential + * flow must be marked at both its source and its destination. Some + * fine points: + * + * - OPLUS_ and O_PLUS are *inside* the loop they create. + * - OQUEST_ and O_QUEST are *outside* the bypass they create. + * - OCH_ and O_CH are *outside* the multi-way branch they create, while + * OOR1 and OOR2 are respectively the end and the beginning of one of + * the branches. Note that there is an implicit OOR2 following OCH_ + * and an implicit OOR1 preceding O_CH. + * + * In state representations, an operator's bit is on to signify a state + * immediately *preceding* "execution" of that operator. + */ +typedef unsigned int sop; /* strip operator */ +typedef unsigned int sopno; +#define OPRMASK 0xf8000000U +#define OPDMASK 0x07ffffffU +#define OPSHIFT ((unsigned)27) +#define OP(n) ((n)&OPRMASK) +#define OPND(n) ((n)&OPDMASK) +#define SOP(op, opnd) ((op)|(opnd)) +/* operators meaning operand */ +/* (back, fwd are offsets) */ +#define OEND (1U<= 0); + if (ch < NC) + return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ + cs->invert); + for (i = 0; i < cs->nwides; i++) + if (ch == cs->wides[i]) + return (!cs->invert); + for (i = 0; i < cs->nranges; i++) + if (cs->ranges[i].min <= ch && ch <= cs->ranges[i].max) + return (!cs->invert); + for (i = 0; i < cs->ntypes; i++) + if (iswctype(ch, cs->types[i])) + return (!cs->invert); + return (cs->invert); +} + +static int +CHIN(cset *cs, wint_t ch) +{ + + assert(ch >= 0); + if (ch < NC) + return (((cs->bmp[ch >> 3] & (1 << (ch & 7))) != 0) ^ + cs->invert); + else if (cs->icase) + return (CHIN1(cs, ch) || CHIN1(cs, towlower(ch)) || + CHIN1(cs, towupper(ch))); + else + return (CHIN1(cs, ch)); +} + +/* + * main compiled-expression structure + */ +struct re_guts { + int magic; +#define MAGIC2 ((('R'^0200)<<8)|'E') + sop *strip; /* malloced area for strip */ + unsigned int ncsets; /* number of csets in use */ + cset *sets; /* -> cset [ncsets] */ + int cflags; /* copy of regcomp() cflags argument */ + sopno nstates; /* = number of sops */ + sopno firststate; /* the initial OEND (normally 0) */ + sopno laststate; /* the final OEND */ + int iflags; /* internal flags */ +#define USEBOL 01 /* used ^ */ +#define USEEOL 02 /* used $ */ +#define BAD 04 /* something wrong */ + int nbol; /* number of ^ used */ + int neol; /* number of $ used */ + char *must; /* match must contain this string */ + int moffset; /* latest point at which must may be located */ + int *charjump; /* Boyer-Moore char jump table */ + int *matchjump; /* Boyer-Moore match jump table */ + int mlen; /* length of must */ + size_t nsub; /* copy of re_nsub */ + int backrefs; /* does it use back references? */ + sopno nplus; /* how deep does it nest +s? */ +}; + +/* misc utilities */ +#define OUT (CHAR_MIN - 1) /* a non-character value */ +#define ISWORD(c) (iswalnum((uch)(c)) || (c) == '_') diff --git a/usr/src/lib/libc/port/regex/regexec.c b/usr/src/lib/libc/port/regex/regexec.c new file mode 100644 index 0000000000..c1bc7b436a --- /dev/null +++ b/usr/src/lib/libc/port/regex/regexec.c @@ -0,0 +1,229 @@ +/* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * the outer shell of regexec() + * + * This file includes engine.c three times, after muchos fiddling with the + * macros that code uses. This lets the same code operate on two different + * representations for state sets and characters. + */ +#include "lint.h" +#include "file64.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "regex2.h" + +/* we want _NOTE, but not NOTE (which collides with our own use) */ +#undef NOTE + +static size_t +xmbrtowc(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, wint_t dummy) +{ + size_t nr; + wchar_t wc; + + nr = mbrtowc(&wc, s, n, mbs); + if (wi != NULL) + *wi = wc; + if (nr == 0) + return (1); + else if (nr == (size_t)-1 || nr == (size_t)-2) { + (void) memset(mbs, 0, sizeof (*mbs)); + if (wi != NULL) + *wi = dummy; + return (1); + } else + return (nr); +} + +static size_t +xmbrtowc_dummy(wint_t *wi, const char *s, size_t n, mbstate_t *mbs, + wint_t dummy) +{ + _NOTE(ARGUNUSED(n)); + _NOTE(ARGUNUSED(mbs)); + _NOTE(ARGUNUSED(dummy)); + + if (wi != NULL) + *wi = (unsigned char)*s; + return (1); +} + +/* macros for manipulating states, small version */ +#define states long +#define states1 states /* for later use in regexec() decision */ +#define CLEAR(v) ((v) = 0) +#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n))) +#define SET1(v, n) ((v) |= (unsigned long)1 << (n)) +#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0) +#define ASSIGN(d, s) ((d) = (s)) +#define EQ(a, b) ((a) == (b)) +#define STATEVARS long dummy /* dummy version */ +#define STATESETUP(m, n) /* nothing */ +#define STATETEARDOWN(m) /* nothing */ +#define SETUP(v) ((v) = 0) +#define onestate long +#define INIT(o, n) ((o) = (unsigned long)1 << (n)) +#define INC(o) ((o) <<= 1) +#define ISSTATEIN(v, o) (((v) & (o)) != 0) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n)) +#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n)) +#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0) +/* no multibyte support */ +#define XMBRTOWC xmbrtowc_dummy +#define ZAPSTATE(mbs) ((void)(mbs)) +/* function names */ +#define SNAMES /* engine.c looks after details */ + +#include "engine.c" + +/* now undo things */ +#undef states +#undef CLEAR +#undef SET0 +#undef SET1 +#undef ISSET +#undef ASSIGN +#undef EQ +#undef STATEVARS +#undef STATESETUP +#undef STATETEARDOWN +#undef SETUP +#undef onestate +#undef INIT +#undef INC +#undef ISSTATEIN +#undef FWD +#undef BACK +#undef ISSETBACK +#undef SNAMES +#undef XMBRTOWC +#undef ZAPSTATE + +/* macros for manipulating states, large version */ +#define states char * +#define CLEAR(v) (void) memset(v, 0, m->g->nstates) +#define SET0(v, n) ((v)[n] = 0) +#define SET1(v, n) ((v)[n] = 1) +#define ISSET(v, n) ((v)[n]) +#define ASSIGN(d, s) (void) memcpy(d, s, m->g->nstates) +#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) +#define STATEVARS long vn; char *space +#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ + if ((m)->space == NULL) \ + return (REG_ESPACE); \ + (m)->vn = 0; } +#define STATETEARDOWN(m) { free((m)->space); } +#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) +#define onestate long +#define INIT(o, n) ((o) = (n)) +#define INC(o) ((o)++) +#define ISSTATEIN(v, o) ((v)[o]) +/* some abbreviations; note that some of these know variable names! */ +/* do "if I'm here, I can also be there" etc without branches */ +#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) +#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) +#define ISSETBACK(v, n) ((v)[here - (n)]) +/* no multibyte support */ +#define XMBRTOWC xmbrtowc_dummy +#define ZAPSTATE(mbs) ((void)(mbs)) +/* function names */ +#define LNAMES /* flag */ + +#include "engine.c" + +/* multibyte character & large states version */ +#undef LNAMES +#undef XMBRTOWC +#undef ZAPSTATE +#define XMBRTOWC xmbrtowc +#define ZAPSTATE(mbs) (void) memset((mbs), 0, sizeof (*(mbs))) +#define MNAMES + +#include "engine.c" + +/* + * regexec - interface for matching + * + * We put this here so we can exploit knowledge of the state representation + * when choosing which matcher to call. Also, by this point the matchers + * have been prototyped. + */ +int /* 0 success, REG_NOMATCH failure */ +regexec(const regex_t *_RESTRICT_KYWD preg, const char *_RESTRICT_KYWD string, + size_t nmatch, regmatch_t pmatch[_RESTRICT_KYWD], int eflags) +{ + struct re_guts *g = preg->re_g; +#ifdef REDEBUG +#define GOODFLAGS(f) (f) +#else +#ifdef REG_STARTEND +#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) +#else +#define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL)) +#endif +#endif + + if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) + return (REG_BADPAT); + assert(!(g->iflags&BAD)); + if (g->iflags&BAD) /* backstop for no-debug case */ + return (REG_BADPAT); + eflags = GOODFLAGS(eflags); + + if (MB_CUR_MAX > 1) + return (mmatcher(g, string, nmatch, pmatch, eflags)); +#ifdef REG_LARGE + else if (g->nstates <= CHAR_BIT*sizeof (states1) && !(eflags®_LARGE)) +#else + else if (g->nstates <= CHAR_BIT*sizeof (states1)) +#endif + return (smatcher(g, string, nmatch, pmatch, eflags)); + else + return (lmatcher(g, string, nmatch, pmatch, eflags)); +} diff --git a/usr/src/lib/libc/port/regex/regfree.c b/usr/src/lib/libc/port/regex/regfree.c new file mode 100644 index 0000000000..0e84f0d8cc --- /dev/null +++ b/usr/src/lib/libc/port/regex/regfree.c @@ -0,0 +1,88 @@ +/* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lint.h" +#include "file64.h" +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "regex2.h" + +/* + * regfree - free everything + */ +void +regfree(regex_t *preg) +{ + struct re_guts *g; + int i; + +#ifdef __lint + /* shut up lint! */ + CHIN(NULL, 0); +#endif + + if (preg->re_magic != MAGIC1) /* oops */ + return; /* nice to complain, but hard */ + + g = preg->re_g; + if (g == NULL || g->magic != MAGIC2) /* oops again */ + return; + preg->re_magic = 0; /* mark it invalid */ + g->magic = 0; /* mark it invalid */ + + if (g->strip != NULL) + free((char *)g->strip); + if (g->sets != NULL) { + for (i = 0; i < g->ncsets; i++) { + free(g->sets[i].ranges); + free(g->sets[i].wides); + free(g->sets[i].types); + } + free((char *)g->sets); + } + if (g->must != NULL) + free(g->must); + if (g->charjump != NULL) + free(&g->charjump[CHAR_MIN]); + if (g->matchjump != NULL) + free(g->matchjump); + free((char *)g); +} diff --git a/usr/src/lib/libc/port/regex/utils.h b/usr/src/lib/libc/port/regex/utils.h new file mode 100644 index 0000000000..b77dc69433 --- /dev/null +++ b/usr/src/lib/libc/port/regex/utils.h @@ -0,0 +1,47 @@ +/* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 1992, 1993, 1994 Henry Spencer. + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Henry Spencer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* utility definitions */ +#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ +#define INFINITY (DUPMAX + 1) +#define NC (CHAR_MAX - CHAR_MIN + 1) +typedef unsigned char uch; + +/* switch off assertions (if not already off) if no REDEBUG */ +#ifndef REDEBUG +#ifndef NDEBUG +#define NDEBUG /* no assertions please */ +#endif +#endif +#include diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 2f5f67dd8f..7c8f14372d 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -836,10 +836,6 @@ PORTLOCALE= \ nextwctype.o \ nl_langinfo.o \ none.o \ - regcomp.o \ - regfree.o \ - regerror.o \ - regexec.o \ rune.o \ runetype.o \ setlocale.o \ @@ -1002,7 +998,11 @@ PORTSYS= \ PORTREGEX= \ glob.o \ regcmp.o \ + regcomp.o \ + regerror.o \ regex.o \ + regexec.o \ + regfree.o \ wordexp.o PORTREGEX64= \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index a3861c40f0..6744289046 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -39,12 +39,12 @@ TARGET_ARCH= sparc # Symbol capabilities objects. EXTPICS= \ - $(LIBCDIR)/capabilities/sun4u/sparcv9/pics/symcap.o \ - $(LIBCDIR)/capabilities/sun4u-opl/sparcv9/pics/symcap.o \ - $(LIBCDIR)/capabilities/sun4u-us3-hwcap1/sparcv9/pics/symcap.o \ - $(LIBCDIR)/capabilities/sun4u-us3-hwcap2/sparcv9/pics/symcap.o \ - $(LIBCDIR)/capabilities/sun4v-hwcap1/sparcv9/pics/symcap.o \ - $(LIBCDIR)/capabilities/sun4v-hwcap2/sparcv9/pics/symcap.o + $(LIBCDIR)/capabilities/sun4u/sparcv9/pics/symcap.o \ + $(LIBCDIR)/capabilities/sun4u-opl/sparcv9/pics/symcap.o \ + $(LIBCDIR)/capabilities/sun4u-us3-hwcap1/sparcv9/pics/symcap.o \ + $(LIBCDIR)/capabilities/sun4u-us3-hwcap2/sparcv9/pics/symcap.o \ + $(LIBCDIR)/capabilities/sun4v-hwcap1/sparcv9/pics/symcap.o \ + $(LIBCDIR)/capabilities/sun4v-hwcap2/sparcv9/pics/symcap.o # local objects STRETS= @@ -780,10 +780,6 @@ PORTLOCALE= \ nextwctype.o \ nl_langinfo.o \ none.o \ - regcomp.o \ - regfree.o \ - regerror.o \ - regexec.o \ rune.o \ runetype.o \ setlocale.o \ @@ -948,7 +944,11 @@ PORTSYS= \ PORTREGEX= \ glob.o \ regcmp.o \ + regcomp.o \ + regerror.o \ regex.o \ + regexec.o \ + regfree.o \ wordexp.o VALUES= values-Xa.o -- cgit v1.2.3 From 490fea6b98d609ce9ae1306209c80bb255b84c95 Mon Sep 17 00:00:00 2001 From: Yuri Pankov Date: Wed, 7 Jun 2017 00:36:24 +0300 Subject: 8355 need libc regex tests Reviewed by: Robert Mustacchi Approved by: Hans Rosenfeld --- usr/src/head/regex.h | 62 +-- usr/src/lib/libc/port/regex/engine.c | 3 +- usr/src/lib/libc/port/regex/regerror.c | 49 +- usr/src/lib/libc/port/regex/regexec.c | 4 - usr/src/pkg/manifests/system-test-libctest.mf | 25 + usr/src/test/libc-tests/runfiles/default.run | 2 + usr/src/test/libc-tests/tests/Makefile | 1 + usr/src/test/libc-tests/tests/regex/Makefile | 88 ++++ .../test/libc-tests/tests/regex/THIRDPARTYLICENSE | 23 + .../tests/regex/THIRDPARTYLICENSE.descrip | 1 + usr/src/test/libc-tests/tests/regex/data/anchor.in | 33 ++ .../test/libc-tests/tests/regex/data/backref.in | 21 + usr/src/test/libc-tests/tests/regex/data/basic.in | 5 + .../test/libc-tests/tests/regex/data/bracket.in | 55 +++ .../test/libc-tests/tests/regex/data/c_comments.in | 17 + .../test/libc-tests/tests/regex/data/complex.in | 23 + usr/src/test/libc-tests/tests/regex/data/error.in | 30 ++ usr/src/test/libc-tests/tests/regex/data/meta.in | 21 + usr/src/test/libc-tests/tests/regex/data/nospec.in | 7 + usr/src/test/libc-tests/tests/regex/data/paren.in | 19 + .../test/libc-tests/tests/regex/data/regress.in | 9 + .../libc-tests/tests/regex/data/repet_bounded.in | 45 ++ .../libc-tests/tests/regex/data/repet_multi.in | 21 + .../libc-tests/tests/regex/data/repet_ordinary.in | 10 + .../test/libc-tests/tests/regex/data/startend.in | 9 + usr/src/test/libc-tests/tests/regex/data/subexp.in | 57 +++ usr/src/test/libc-tests/tests/regex/data/subtle.in | 21 + .../test/libc-tests/tests/regex/data/word_bound.in | 13 + usr/src/test/libc-tests/tests/regex/data/zero.in | 7 + usr/src/test/libc-tests/tests/regex/main.c | 514 +++++++++++++++++++++ usr/src/test/libc-tests/tests/regex/split.c | 168 +++++++ usr/src/test/libc-tests/tests/regex/t_regex.sh | 25 + usr/src/test/libc-tests/tests/regex/test_regex.h | 39 ++ 33 files changed, 1385 insertions(+), 42 deletions(-) create mode 100644 usr/src/test/libc-tests/tests/regex/Makefile create mode 100644 usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE create mode 100644 usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE.descrip create mode 100644 usr/src/test/libc-tests/tests/regex/data/anchor.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/backref.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/basic.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/bracket.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/c_comments.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/complex.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/error.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/meta.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/nospec.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/paren.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/regress.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/repet_bounded.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/repet_multi.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/repet_ordinary.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/startend.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/subexp.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/subtle.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/word_bound.in create mode 100644 usr/src/test/libc-tests/tests/regex/data/zero.in create mode 100644 usr/src/test/libc-tests/tests/regex/main.c create mode 100644 usr/src/test/libc-tests/tests/regex/split.c create mode 100644 usr/src/test/libc-tests/tests/regex/t_regex.sh create mode 100644 usr/src/test/libc-tests/tests/regex/test_regex.h (limited to 'usr/src') diff --git a/usr/src/head/regex.h b/usr/src/head/regex.h index 8131d756cc..33e4bd7de1 100644 --- a/usr/src/head/regex.h +++ b/usr/src/head/regex.h @@ -19,6 +19,7 @@ * * CDDL HEADER END */ + /* * Copyright 2014 Garrett D'Amore * @@ -30,9 +31,9 @@ * Copyright 1989, 1994 by Mortice Kern Systems Inc. * All rights reserved. */ + /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright 2017 Nexenta Systems, Inc. */ #ifndef _REGEX_H @@ -73,32 +74,31 @@ typedef long wchar_t; typedef ssize_t regoff_t; /* regcomp flags */ -#define REG_BASIC 0x00 -#define REG_EXTENDED 0x01 /* Use Extended Regular Expressions */ -#define REG_NEWLINE 0x08 /* Treat \n as regular character */ -#define REG_ICASE 0x04 /* Ignore case in match */ -#define REG_NOSUB 0x02 /* Don't set subexpression */ -#define REG_EGREP 0x1000 /* running as egrep(1) */ - -/* non-standard flags - note that most of these are not supported */ -#define REG_DELIM 0x10 /* string[0] is delimiter */ -#define REG_DEBUG 0x20 /* Debug recomp and regexec */ -#define REG_ANCHOR 0x40 /* Implicit ^ and $ */ -#define REG_WORDS 0x80 /* \< and \> match word boundries */ - -/* FreeBSD additions */ -#define REG_DUMP 0x2000 -#define REG_PEND 0x4000 -#define REG_NOSPEC 0x8000 -#define REG_STARTEND 0x10000 +#define REG_BASIC 0x00000 +#define REG_EXTENDED 0x00001 /* Use Extended Regular Expressions */ +#define REG_NOSUB 0x00002 /* Don't set subexpression */ +#define REG_ICASE 0x00004 /* Ignore case in match */ +#define REG_NEWLINE 0x00008 /* Treat \n as regular character */ +#define REG_DELIM 0x00010 /* legacy, no effect */ +#define REG_DEBUG 0x00020 /* legacy, no effect */ +#define REG_ANCHOR 0x00040 /* legacy, no effect */ +#define REG_WORDS 0x00080 /* legacy, no effect */ +#define REG_EGREP 0x01000 /* legacy, no effect */ +#define REG_DUMP 0x02000 /* internal */ +#define REG_PEND 0x04000 /* NULs are ordinary characters */ +#define REG_NOSPEC 0x08000 /* no special characters */ /* internal flags */ -#define REG_MUST 0x100 /* check for regmust substring */ +#define REG_MUST 0x00100 /* legacy, no effect */ /* regexec flags */ -#define REG_NOTBOL 0x200 /* string is not BOL */ -#define REG_NOTEOL 0x400 /* string has no EOL */ -#define REG_NOOPT 0x800 /* don't do regmust optimization */ +#define REG_NOTBOL 0x00200 /* string is not BOL */ +#define REG_NOTEOL 0x00400 /* string has no EOL */ +#define REG_NOOPT 0x00800 /* legacy, no effect */ +#define REG_STARTEND 0x10000 /* match whole pattern */ +#define REG_TRACE 0x20000 /* tracing of execution */ +#define REG_LARGE 0x40000 /* force large representation */ +#define REG_BACKR 0x80000 /* force use of backref code */ /* regcomp and regexec return codes */ #define REG_OK 0 /* success (non-standard) */ @@ -118,12 +118,15 @@ typedef ssize_t regoff_t; #define REG_BADPAT 14 /* syntax error */ #define REG_BADBR 15 /* \{ \} contents bad */ #define REG_EFATAL 16 /* internal error, not POSIX.2 */ -#define REG_ECHAR 17 /* invalid mulitbyte character */ +#define REG_ECHAR 17 /* invalid multibyte character */ #define REG_STACK 18 /* backtrack stack overflow */ #define REG_ENOSYS 19 /* function not supported (XPG4) */ #define REG__LAST 20 /* first unused code */ #define REG_EBOL 21 /* ^ anchor and not BOL */ #define REG_EEOL 22 /* $ anchor and not EOL */ +#define REG_ATOI 255 /* convert name to number (!) */ +#define REG_ITOA 256 /* convert number to name (!) */ + #define _REG_BACKREF_MAX 9 /* Max # of subexp. backreference */ typedef struct { /* regcomp() data saved for regexec() */ @@ -151,15 +154,14 @@ typedef struct { /* - * Additional API and structs to support regular expression manipulations - * on wide characters. + * IEEE Std 1003.2 ("POSIX.2") regular expressions API. */ extern int regcomp(regex_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, int); extern int regexec(const regex_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, - size_t, regmatch_t *_RESTRICT_KYWD, int); -extern size_t regerror(int, const regex_t *_RESTRICT_KYWD, - char *_RESTRICT_KYWD, size_t); + size_t, regmatch_t *_RESTRICT_KYWD, int); +extern size_t regerror(int, const regex_t *_RESTRICT_KYWD, char *_RESTRICT_KYWD, + size_t); extern void regfree(regex_t *); #ifdef __cplusplus diff --git a/usr/src/lib/libc/port/regex/engine.c b/usr/src/lib/libc/port/regex/engine.c index 7481545864..68cf24a5da 100644 --- a/usr/src/lib/libc/port/regex/engine.c +++ b/usr/src/lib/libc/port/regex/engine.c @@ -289,8 +289,7 @@ matcher(struct re_guts *g, const char *string, size_t nmatch, } for (i = 1; i <= m->g->nsub; i++) m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; - /* NB: FreeBSD has REG_BACKR, we do not */ - if (!g->backrefs /* && !(m->eflags®_BACKR) */) { + if (!g->backrefs && !(m->eflags®_BACKR)) { NOTE("dissecting"); dp = dissect(m, m->coldp, endp, gf, gl); } else { diff --git a/usr/src/lib/libc/port/regex/regerror.c b/usr/src/lib/libc/port/regex/regerror.c index 3915c4429b..92179feea6 100644 --- a/usr/src/lib/libc/port/regex/regerror.c +++ b/usr/src/lib/libc/port/regex/regerror.c @@ -44,6 +44,8 @@ #include "utils.h" #include "../gen/_libc_gettext.h" +static const char *regatoi(const regex_t *preg, char *localbuf); + #define RERR(x, msg) { x, #x, msg } static struct rerr { @@ -90,19 +92,35 @@ regerror(int errcode, const regex_t *_RESTRICT_KYWD preg, { struct rerr *r; size_t len; + int target = errcode &~ REG_ITOA; const char *s; + char convbuf[50]; - for (r = rerrs; r->code != 0; r++) - if (r->code == errcode) - break; + if (errcode == REG_ATOI) { + s = regatoi(preg, convbuf); + } else { + for (r = rerrs; r->code != 0; r++) { + if (r->code == target) + break; + } - s = _libc_gettext(r->explain); + if (errcode®_ITOA) { + if (r->code != 0) + (void) strcpy(convbuf, r->name); + else + (void) sprintf(convbuf, "REG_0x%x", target); + assert(strlen(convbuf) < sizeof (convbuf)); + s = convbuf; + } else { + s = _libc_gettext(r->explain); + } + } len = strlen(s) + 1; if (errbuf_size > 0) { - if (errbuf_size > len) + if (errbuf_size > len) { (void) strcpy(errbuf, s); - else { + } else { (void) strncpy(errbuf, s, errbuf_size-1); errbuf[errbuf_size-1] = '\0'; } @@ -110,3 +128,22 @@ regerror(int errcode, const regex_t *_RESTRICT_KYWD preg, return (len); } + +/* + * regatoi - internal routine to implement REG_ATOI + */ +static const char * +regatoi(const regex_t *preg, char *localbuf) +{ + struct rerr *r; + + for (r = rerrs; r->code != 0; r++) { + if (strcmp(r->name, preg->re_endp) == 0) + break; + } + if (r->code == 0) + return ("0"); + + (void) sprintf(localbuf, "%d", r->code); + return (localbuf); +} diff --git a/usr/src/lib/libc/port/regex/regexec.c b/usr/src/lib/libc/port/regex/regexec.c index c1bc7b436a..188e9f08ed 100644 --- a/usr/src/lib/libc/port/regex/regexec.c +++ b/usr/src/lib/libc/port/regex/regexec.c @@ -218,11 +218,7 @@ regexec(const regex_t *_RESTRICT_KYWD preg, const char *_RESTRICT_KYWD string, if (MB_CUR_MAX > 1) return (mmatcher(g, string, nmatch, pmatch, eflags)); -#ifdef REG_LARGE else if (g->nstates <= CHAR_BIT*sizeof (states1) && !(eflags®_LARGE)) -#else - else if (g->nstates <= CHAR_BIT*sizeof (states1)) -#endif return (smatcher(g, string, nmatch, pmatch, eflags)); else return (lmatcher(g, string, nmatch, pmatch, eflags)); diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf index 6cc5b2ebcb..2b2f3329f6 100644 --- a/usr/src/pkg/manifests/system-test-libctest.mf +++ b/usr/src/pkg/manifests/system-test-libctest.mf @@ -28,6 +28,8 @@ dir path=opt/libc-tests/cfg/symbols dir path=opt/libc-tests/runfiles dir path=opt/libc-tests/tests dir path=opt/libc-tests/tests/random +dir path=opt/libc-tests/tests/regex +dir path=opt/libc-tests/tests/regex/data dir path=opt/libc-tests/tests/select dir path=opt/libc-tests/tests/symbols dir path=usr group=sys @@ -124,6 +126,27 @@ file path=opt/libc-tests/tests/random/inz_region mode=0555 file path=opt/libc-tests/tests/random/inz_split mode=0555 file path=opt/libc-tests/tests/random/inz_split_vpp mode=0555 file path=opt/libc-tests/tests/random/inz_vpp mode=0555 +file path=opt/libc-tests/tests/regex/data/anchor.in mode=0444 +file path=opt/libc-tests/tests/regex/data/backref.in mode=0444 +file path=opt/libc-tests/tests/regex/data/basic.in mode=0444 +file path=opt/libc-tests/tests/regex/data/bracket.in mode=0444 +file path=opt/libc-tests/tests/regex/data/c_comments.in mode=0444 +file path=opt/libc-tests/tests/regex/data/complex.in mode=0444 +file path=opt/libc-tests/tests/regex/data/error.in mode=0444 +file path=opt/libc-tests/tests/regex/data/meta.in mode=0444 +file path=opt/libc-tests/tests/regex/data/nospec.in mode=0444 +file path=opt/libc-tests/tests/regex/data/paren.in mode=0444 +file path=opt/libc-tests/tests/regex/data/regress.in mode=0444 +file path=opt/libc-tests/tests/regex/data/repet_bounded.in mode=0444 +file path=opt/libc-tests/tests/regex/data/repet_multi.in mode=0444 +file path=opt/libc-tests/tests/regex/data/repet_ordinary.in mode=0444 +file path=opt/libc-tests/tests/regex/data/startend.in mode=0444 +file path=opt/libc-tests/tests/regex/data/subexp.in mode=0444 +file path=opt/libc-tests/tests/regex/data/subtle.in mode=0444 +file path=opt/libc-tests/tests/regex/data/word_bound.in mode=0444 +file path=opt/libc-tests/tests/regex/data/zero.in mode=0444 +file path=opt/libc-tests/tests/regex/h_regex mode=0555 +file path=opt/libc-tests/tests/regex/t_regex mode=0555 file path=opt/libc-tests/tests/select/select.sh mode=0555 file path=opt/libc-tests/tests/select/select_test mode=0555 file path=opt/libc-tests/tests/strcoll-strxfrm-6907.32 mode=0555 @@ -180,6 +203,8 @@ hardlink path=opt/libc-tests/tests/symbols/unistd_h target=setup hardlink path=opt/libc-tests/tests/symbols/wchar_h target=setup hardlink path=opt/libc-tests/tests/symbols/wctype_h target=setup license lic_CDDL license=lic_CDDL +license usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE \ + license=usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE depend fmri=locale/de type=require depend fmri=locale/en type=require depend fmri=locale/en-extra type=require diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run index 149d696f03..93a394782b 100644 --- a/usr/src/test/libc-tests/runfiles/default.run +++ b/usr/src/test/libc-tests/runfiles/default.run @@ -57,6 +57,8 @@ outputdir = /var/tmp/test_results [/opt/libc-tests/tests/random/arc4random_preforksig] [/opt/libc-tests/tests/random/arc4key.ksh] +[/opt/libc-tests/tests/regex/t_regex] + [/opt/libc-tests/tests/select/select.sh] timeout = 600 diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile index e9e15616d0..160e9a9383 100644 --- a/usr/src/test/libc-tests/tests/Makefile +++ b/usr/src/test/libc-tests/tests/Makefile @@ -22,6 +22,7 @@ SUBDIRS = \ nl_langinfo \ priv_gettext \ random \ + regex \ select \ strerror \ symbols \ diff --git a/usr/src/test/libc-tests/tests/regex/Makefile b/usr/src/test/libc-tests/tests/regex/Makefile new file mode 100644 index 0000000000..41227d87b4 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/Makefile @@ -0,0 +1,88 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Nexenta Systems, Inc. +# + +include $(SRC)/Makefile.master + +ROOTOPTPKG= $(ROOT)/opt/libc-tests +TESTDIR= $(ROOTOPTPKG)/tests/regex +DATADIR= $(TESTDIR)/data + +PROG= h_regex +OBJS= main.o \ + split.o + +SHPROG= t_regex + +DATA= anchor.in \ + backref.in \ + basic.in \ + bracket.in \ + c_comments.in \ + complex.in \ + error.in \ + meta.in \ + nospec.in \ + paren.in \ + regress.in \ + repet_bounded.in \ + repet_multi.in \ + repet_ordinary.in \ + startend.in \ + subexp.in \ + subtle.in \ + word_bound.in \ + zero.in + +include $(SRC)/cmd/Makefile.cmd + +CMDS= $(PROG:%=$(TESTDIR)/%) $(SHPROG:%=$(TESTDIR)/%) +$(CMDS):= FILEMODE=0555 +TESTDATA= $(DATA:%=$(DATADIR)/%) +$(TESTDATA):= FILEMODE=0444 + +CPPFLAGS += -I$(SRC)/lib/libc/port/regex + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +$(CMDS): $(TESTDIR) + +$(TESTDATA): $(DATADIR) + +install: all $(CMDS) $(TESTDATA) + +clean: + $(RM) $(OBJS) + +lint: + +$(TESTDIR) $(DATADIR): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) + +$(TESTDIR)/%: %.sh + $(INS.rename) + +$(DATADIR)/%: data/% + $(INS.file) + +include $(SRC)/cmd/Makefile.targ diff --git a/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE b/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE new file mode 100644 index 0000000000..7a7e26d39b --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE @@ -0,0 +1,23 @@ +Copyright (c) 1993 The NetBSD Foundation, Inc. +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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE.descrip b/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..e3d50f5ef3 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +LIBC REGEX TESTS diff --git a/usr/src/test/libc-tests/tests/regex/data/anchor.in b/usr/src/test/libc-tests/tests/regex/data/anchor.in new file mode 100644 index 0000000000..d145408247 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/anchor.in @@ -0,0 +1,33 @@ +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b diff --git a/usr/src/test/libc-tests/tests/regex/data/backref.in b/usr/src/test/libc-tests/tests/regex/data/backref.in new file mode 100644 index 0000000000..cc59b06e5f --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/backref.in @@ -0,0 +1,21 @@ +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd diff --git a/usr/src/test/libc-tests/tests/regex/data/basic.in b/usr/src/test/libc-tests/tests/regex/data/basic.in new file mode 100644 index 0000000000..d1e3aa9dad --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/basic.in @@ -0,0 +1,5 @@ +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a diff --git a/usr/src/test/libc-tests/tests/regex/data/bracket.in b/usr/src/test/libc-tests/tests/regex/data/bracket.in new file mode 100644 index 0000000000..53a0b20d3c --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/bracket.in @@ -0,0 +1,55 @@ +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b diff --git a/usr/src/test/libc-tests/tests/regex/data/c_comments.in b/usr/src/test/libc-tests/tests/regex/data/c_comments.in new file mode 100644 index 0000000000..ea3faf9ddf --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/c_comments.in @@ -0,0 +1,17 @@ +# Let's have some fun -- try to match a C comment. +# first the obvious, which looks okay at first glance... +/\*.*\*/ - /*x*/ /*x*/ +# but... +/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/ +# okay, we must not match */ inside; try to do that... +/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/ +/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/ +# but... +/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/ +# and a still fancier version, which does it right (I think)... +/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/ +/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/ diff --git a/usr/src/test/libc-tests/tests/regex/data/complex.in b/usr/src/test/libc-tests/tests/regex/data/complex.in new file mode 100644 index 0000000000..e1140588e7 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/complex.in @@ -0,0 +1,23 @@ +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq diff --git a/usr/src/test/libc-tests/tests/regex/data/error.in b/usr/src/test/libc-tests/tests/regex/data/error.in new file mode 100644 index 0000000000..ea106f1653 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/error.in @@ -0,0 +1,30 @@ +# certain syntax errors and non-errors +| C BADPAT +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C BADPAT +() - abc @abc +\(\) b abc @abc +a||b C BADPAT +|ab C BADPAT +ab| C BADPAT +(|a)b C BADPAT +(a|)b C BADPAT +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT diff --git a/usr/src/test/libc-tests/tests/regex/data/meta.in b/usr/src/test/libc-tests/tests/regex/data/meta.in new file mode 100644 index 0000000000..4533d3591b --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/meta.in @@ -0,0 +1,21 @@ +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +a\[b & a[b a[b +a[b &C EBRACK +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ diff --git a/usr/src/test/libc-tests/tests/regex/data/nospec.in b/usr/src/test/libc-tests/tests/regex/data/nospec.in new file mode 100644 index 0000000000..d95f81d1d7 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/nospec.in @@ -0,0 +1,7 @@ +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC BADPAT diff --git a/usr/src/test/libc-tests/tests/regex/data/paren.in b/usr/src/test/libc-tests/tests/regex/data/paren.in new file mode 100644 index 0000000000..c3e8a295fe --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/paren.in @@ -0,0 +1,19 @@ +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) b EPAREN +) b EPAREN +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab diff --git a/usr/src/test/libc-tests/tests/regex/data/regress.in b/usr/src/test/libc-tests/tests/regex/data/regress.in new file mode 100644 index 0000000000..afd832a51c --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/regress.in @@ -0,0 +1,9 @@ +# past problems, and suspected problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 +Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz +a?b - ab ab +-\{0,1\}[0-9]*$ b -5 -5 diff --git a/usr/src/test/libc-tests/tests/regex/data/repet_bounded.in b/usr/src/test/libc-tests/tests/regex/data/repet_bounded.in new file mode 100644 index 0000000000..ee6ff4cd19 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/repet_bounded.in @@ -0,0 +1,45 @@ +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a diff --git a/usr/src/test/libc-tests/tests/regex/data/repet_multi.in b/usr/src/test/libc-tests/tests/regex/data/repet_multi.in new file mode 100644 index 0000000000..da97badde9 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/repet_multi.in @@ -0,0 +1,21 @@ +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT diff --git a/usr/src/test/libc-tests/tests/regex/data/repet_ordinary.in b/usr/src/test/libc-tests/tests/regex/data/repet_ordinary.in new file mode 100644 index 0000000000..08bc286e5b --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/repet_ordinary.in @@ -0,0 +1,10 @@ +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT diff --git a/usr/src/test/libc-tests/tests/regex/data/startend.in b/usr/src/test/libc-tests/tests/regex/data/startend.in new file mode 100644 index 0000000000..c396e58ac4 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/startend.in @@ -0,0 +1,9 @@ +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc diff --git a/usr/src/test/libc-tests/tests/regex/data/subexp.in b/usr/src/test/libc-tests/tests/regex/data/subexp.in new file mode 100644 index 0000000000..c7bcc06175 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/subexp.in @@ -0,0 +1,57 @@ +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- diff --git a/usr/src/test/libc-tests/tests/regex/data/subtle.in b/usr/src/test/libc-tests/tests/regex/data/subtle.in new file mode 100644 index 0000000000..92d68bb9c2 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/subtle.in @@ -0,0 +1,21 @@ +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc +a* & b @b diff --git a/usr/src/test/libc-tests/tests/regex/data/word_bound.in b/usr/src/test/libc-tests/tests/regex/data/word_bound.in new file mode 100644 index 0000000000..e09a329afd --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/word_bound.in @@ -0,0 +1,13 @@ +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc +[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc +[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_ +[[:<:]]a_b[[:>:]] & x_a_b diff --git a/usr/src/test/libc-tests/tests/regex/data/zero.in b/usr/src/test/libc-tests/tests/regex/data/zero.in new file mode 100644 index 0000000000..2786944eb2 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/data/zero.in @@ -0,0 +1,7 @@ +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb diff --git a/usr/src/test/libc-tests/tests/regex/main.c b/usr/src/test/libc-tests/tests/regex/main.c new file mode 100644 index 0000000000..fa7a2dd408 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/main.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "test_regex.h" + +char *progname; +int line = 0; +int status = 0; + +int copts = REG_EXTENDED; +int eopts = 0; +regoff_t startoff = 0; +regoff_t endoff = 0; + +static char empty = '\0'; + +static char *eprint(int); +static int efind(char *); + +/* + * main - do the simple case, hand off to regress() for regression + */ +int +main(int argc, char *argv[]) +{ + regex_t re; +#define NS 10 + regmatch_t subs[NS]; + char erbuf[100]; + int err; + size_t len; + int c; + int errflg = 0; + int i; + extern int optind; + extern char *optarg; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "c:e:S:E:")) != -1) + switch (c) { + case 'c': /* compile options */ + copts = options('c', optarg); + break; + case 'e': /* execute options */ + eopts = options('e', optarg); + break; + case 'S': /* start offset */ + startoff = (regoff_t)atoi(optarg); + break; + case 'E': /* end offset */ + endoff = (regoff_t)atoi(optarg); + break; + case '?': + default: + errflg++; + break; + } + if (errflg) { + fprintf(stderr, "usage: %s ", progname); + fprintf(stderr, "[-c copt][-C][-d] [re]\n"); + exit(2); + } + + if (optind >= argc) { + regress(stdin); + exit(status); + } + + err = regcomp(&re, argv[optind++], copts); + if (err) { + len = regerror(err, &re, erbuf, sizeof (erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof (erbuf), erbuf); + exit(status); + } + + if (optind >= argc) { + regfree(&re); + exit(status); + } + + if (eopts®_STARTEND) { + subs[0].rm_so = startoff; + subs[0].rm_eo = strlen(argv[optind]) - endoff; + } + err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); + if (err) { + len = regerror(err, &re, erbuf, sizeof (erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof (erbuf), erbuf); + exit(status); + } + if (!(copts®_NOSUB)) { + len = (int)(subs[0].rm_eo - subs[0].rm_so); + if (subs[0].rm_so != -1) { + if (len != 0) { + printf("match `%.*s'\n", (int)len, + argv[optind] + subs[0].rm_so); + } else { + printf("match `'@%.1s\n", + argv[optind] + subs[0].rm_so); + } + } + for (i = 1; i < NS; i++) { + if (subs[i].rm_so != -1) { + printf("(%d) `%.*s'\n", i, + (int)(subs[i].rm_eo - subs[i].rm_so), + argv[optind] + subs[i].rm_so); + } + } + } + exit(status); +} + +/* + * regress - main loop of regression test + */ +void +regress(FILE *in) +{ + char inbuf[1000]; +#define MAXF 10 + char *f[MAXF]; + int nf; + int i; + char erbuf[100]; + size_t ne; + const char *badpat = "invalid regular expression"; +#define SHORT 10 + const char *bpname = "REG_BADPAT"; + regex_t re; + + while (fgets(inbuf, sizeof (inbuf), in) != NULL) { + line++; + if (inbuf[0] == '#' || inbuf[0] == '\n') + continue; /* NOTE CONTINUE */ + inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ + nf = split(inbuf, f, MAXF, "\t\t"); + if (nf < 3) { + fprintf(stderr, "bad input, line %d\n", line); + exit(1); + } + for (i = 0; i < nf; i++) + if (strcmp(f[i], "\"\"") == 0) + f[i] = ∅ + if (nf <= 3) + f[3] = NULL; + if (nf <= 4) + f[4] = NULL; + try(f[0], f[1], f[2], f[3], f[4], options('c', f[1])); + if (opt('&', f[1])) /* try with either type of RE */ + try(f[0], f[1], f[2], f[3], f[4], + options('c', f[1]) &~ REG_EXTENDED); + } + + ne = regerror(REG_BADPAT, NULL, erbuf, sizeof (erbuf)); + if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { + fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", + erbuf, badpat); + status = 1; + } + ne = regerror(REG_BADPAT, NULL, erbuf, (size_t)SHORT); + if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || + ne != strlen(badpat)+1) { + fprintf(stderr, + "end: regerror() short test gave `%s' not `%.*s'\n", + erbuf, SHORT-1, badpat); + status = 1; + } + ne = regerror(REG_ITOA|REG_BADPAT, NULL, erbuf, sizeof (erbuf)); + if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) { + fprintf(stderr, + "end: regerror() ITOA test gave `%s' not `%s'\n", + erbuf, bpname); + status = 1; + } + re.re_endp = bpname; + ne = regerror(REG_ATOI, &re, erbuf, sizeof (erbuf)); + if (atoi(erbuf) != (int)REG_BADPAT) { + fprintf(stderr, + "end: regerror() ATOI test gave `%s' not `%ld'\n", + erbuf, (long)REG_BADPAT); + status = 1; + } else if (ne != strlen(erbuf)+1) { + fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n", + erbuf, (long)REG_BADPAT); + status = 1; + } +} + +/* + * try - try it, and report on problems + */ +void +try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts) +{ + regex_t re; +#define NSUBS 10 + regmatch_t subs[NSUBS]; +#define NSHOULD 15 + char *should[NSHOULD]; + int nshould; + char erbuf[100]; + int err; + int len; + const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; + int i; + char *grump; + char f0copy[1000]; + char f2copy[1000]; + + strcpy(f0copy, f0); + re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; + fixstr(f0copy); + err = regcomp(&re, f0copy, opts); + if (err != 0 && (!opt('C', f1) || err != efind(f2))) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof (erbuf)); + fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", + line, type, eprint(err), len, (int)sizeof (erbuf), erbuf); + status = 1; + } else if (err == 0 && opt('C', f1)) { + /* unexpected success */ + fprintf(stderr, "%d: %s should have given REG_%s\n", + line, type, f2); + status = 1; + err = 1; /* so we won't try regexec */ + } + + if (err != 0) { + regfree(&re); + return; + } + + strcpy(f2copy, f2); + fixstr(f2copy); + + if (options('e', f1)®_STARTEND) { + if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) + fprintf(stderr, "%d: bad STARTEND syntax\n", line); + subs[0].rm_so = strchr(f2, '(') - f2 + 1; + subs[0].rm_eo = strchr(f2, ')') - f2; + } + err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); + + if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof (erbuf)); + fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", + line, type, eprint(err), len, (int)sizeof (erbuf), erbuf); + status = 1; + } else if (err != 0) { + /* nothing more to check */ + } else if (f3 == NULL) { + /* unexpected success */ + fprintf(stderr, "%d: %s exec should have failed\n", line, type); + status = 1; + err = 1; /* just on principle */ + } else if (opts®_NOSUB) { + /* nothing more to check */ + } else if ((grump = check(f2, subs[0], f3)) != NULL) { + fprintf(stderr, "%d: %s %s\n", line, type, grump); + status = 1; + err = 1; + } + + if (err != 0 || f4 == NULL) { + regfree(&re); + return; + } + + for (i = 1; i < NSHOULD; i++) + should[i] = NULL; + nshould = split(f4, &should[1], NSHOULD-1, ","); + if (nshould == 0) { + nshould = 1; + should[1] = ∅ + } + for (i = 1; i < NSUBS; i++) { + grump = check(f2, subs[i], should[i]); + if (grump != NULL) { + fprintf(stderr, "%d: %s $%d %s\n", line, + type, i, grump); + status = 1; + err = 1; + } + } + + regfree(&re); +} + +/* + * options - pick options out of a regression-test string + */ +int +options(int type, char *s) +{ + char *p; + int o = (type == 'c') ? copts : eopts; + const char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; + + for (p = s; *p != '\0'; p++) + if (strchr(legal, *p) != NULL) + switch (*p) { + case 'b': + o &= ~REG_EXTENDED; + break; + case 'i': + o |= REG_ICASE; + break; + case 's': + o |= REG_NOSUB; + break; + case 'n': + o |= REG_NEWLINE; + break; + case 'm': + o &= ~REG_EXTENDED; + o |= REG_NOSPEC; + break; + case 'p': + o |= REG_PEND; + break; + case '^': + o |= REG_NOTBOL; + break; + case '$': + o |= REG_NOTEOL; + break; + case '#': + o |= REG_STARTEND; + break; + case 't': /* trace */ + o |= REG_TRACE; + break; + case 'l': /* force long representation */ + o |= REG_LARGE; + break; + case 'r': /* force backref use */ + o |= REG_BACKR; + break; + } + return (o); +} + +/* + * opt - is a particular option in a regression string? + */ +int /* predicate */ +opt(int c, char *s) +{ + return (strchr(s, c) != NULL); +} + +/* + * fixstr - transform magic characters in strings + */ +void +fixstr(char *p) +{ + if (p == NULL) + return; + + for (; *p != '\0'; p++) + if (*p == 'N') + *p = '\n'; + else if (*p == 'T') + *p = '\t'; + else if (*p == 'S') + *p = ' '; + else if (*p == 'Z') + *p = '\0'; +} + +/* + * check - check a substring match + */ +char * +check(char *str, regmatch_t sub, char *should) +{ + int len; + int shlen; + char *p; + static char grump[500]; + char *at = NULL; + + if (should != NULL && strcmp(should, "-") == 0) + should = NULL; + if (should != NULL && should[0] == '@') { + at = should + 1; + should = ∅ + } + + /* check rm_so and rm_eo for consistency */ + if ((sub.rm_so > sub.rm_eo) || + (sub.rm_so == -1 && sub.rm_eo != -1) || + (sub.rm_so != -1 && sub.rm_eo == -1) || + (sub.rm_so != -1 && sub.rm_so < 0) || + (sub.rm_eo != -1 && sub.rm_eo < 0)) { + sprintf(grump, "start %ld end %ld", + (long)sub.rm_so, (long)sub.rm_eo); + return (grump); + } + + /* check for no match */ + if (sub.rm_so == -1) { + if (should == NULL) + return (NULL); + else { + sprintf(grump, "did not match"); + return (grump); + } + } + + /* check for in range */ + if (sub.rm_eo > (ssize_t)strlen(str)) { + sprintf(grump, "start %ld end %ld, past end of string", + (long)sub.rm_so, (long)sub.rm_eo); + return (grump); + } + + len = (int)(sub.rm_eo - sub.rm_so); + p = str + sub.rm_so; + + /* check for not supposed to match */ + if (should == NULL) { + sprintf(grump, "matched `%.*s'", len, p); + return (grump); + } + + /* check for wrong match */ + shlen = (int)strlen(should); + if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { + sprintf(grump, "matched `%.*s' instead", len, p); + return (grump); + } + if (shlen > 0) + return (NULL); + + /* check null match in right place */ + if (at == NULL) + return (NULL); + shlen = strlen(at); + if (shlen == 0) + shlen = 1; /* force check for end-of-string */ + if (strncmp(p, at, shlen) != 0) { + sprintf(grump, "matched null at `%.20s'", p); + return (grump); + } + return (NULL); +} + +/* + * eprint - convert error number to name + */ +static char * +eprint(int err) +{ + static char epbuf[100]; + size_t len; + + len = regerror(REG_ITOA|err, NULL, epbuf, sizeof (epbuf)); + assert(len <= sizeof (epbuf)); + return (epbuf); +} + +/* + * efind - convert error name to number + */ +static int +efind(char *name) +{ + static char efbuf[100]; + regex_t re; + + sprintf(efbuf, "REG_%s", name); + assert(strlen(efbuf) < sizeof (efbuf)); + re.re_endp = efbuf; + (void) regerror(REG_ATOI, &re, efbuf, sizeof (efbuf)); + return (atoi(efbuf)); +} diff --git a/usr/src/test/libc-tests/tests/regex/split.c b/usr/src/test/libc-tests/tests/regex/split.c new file mode 100644 index 0000000000..664b8375af --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/split.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "test_regex.h" + +/* + * split - divide a string into fields, like awk split() + * + * returns number of fields, including overflow + * + * fields[] list is not NULL-terminated + * nfields number of entries available in fields[] + * sep "" white, "c" single char, "ab" [ab]+ + */ +int +split(char *string, char *fields[], int nfields, const char *sep) +{ + char *p = string; + char c; /* latest character */ + char sepc = *sep; + char sepc2; + int fn; + char **fp = fields; + const char *sepp; + int trimtrail; + + /* white space */ + if (sepc == '\0') { + while ((c = *p++) == ' ' || c == '\t') + continue; + p--; + trimtrail = 1; + sep = " \t"; /* note, code below knows this is 2 long */ + sepc = ' '; + } else + trimtrail = 0; + sepc2 = sep[1]; /* now we can safely pick this up */ + + /* catch empties */ + if (*p == '\0') + return (0); + + /* single separator */ + if (sepc2 == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + if (fn == 0) + break; + while ((c = *p++) != sepc) + if (c == '\0') + return (nfields - fn); + *(p-1) = '\0'; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + for (;;) { + while ((c = *p++) != sepc) + if (c == '\0') + return (fn); + fn++; + } + /* not reached */ + } + + /* two separators */ + if (sep[2] == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + while ((c = *p++) != sepc && c != sepc2) + if (c == '\0') { + if (trimtrail && **(fp-1) == '\0') + fn++; + return (nfields - fn); + } + if (fn == 0) + break; + *(p-1) = '\0'; + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + while (c != '\0') { + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + fn++; + while ((c = *p++) != '\0' && c != sepc && c != sepc2) + continue; + } + /* might have to trim trailing white space */ + if (trimtrail) { + p--; + while ((c = *--p) == sepc || c == sepc2) + continue; + p++; + if (*p != '\0') { + if (fn == nfields+1) + *p = '\0'; + fn--; + } + } + return (fn); + } + + /* n separators */ + fn = 0; + for (;;) { + if (fn < nfields) + *fp++ = p; + fn++; + for (;;) { + c = *p++; + if (c == '\0') + return (fn); + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc != '\0') /* it was a separator */ + break; + } + if (fn < nfields) + *(p-1) = '\0'; + for (;;) { + c = *p++; + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc == '\0') /* it wasn't a separator */ + break; + } + p--; + } + + /* not reached */ +} diff --git a/usr/src/test/libc-tests/tests/regex/t_regex.sh b/usr/src/test/libc-tests/tests/regex/t_regex.sh new file mode 100644 index 0000000000..990f13154c --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/t_regex.sh @@ -0,0 +1,25 @@ +#! /usr/bin/sh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Nexenta Systems, Inc. +# + +TESTDIR=$(dirname $0) +HREGEX=${TESTDIR}/h_regex + +for t in $TESTDIR/data/*.in; do + $HREGEX < $t || exit 1 + $HREGEX -el < $t || exit 1 + $HREGEX -er < $t || exit 1 +done diff --git a/usr/src/test/libc-tests/tests/regex/test_regex.h b/usr/src/test/libc-tests/tests/regex/test_regex.h new file mode 100644 index 0000000000..7a90ac4859 --- /dev/null +++ b/usr/src/test/libc-tests/tests/regex/test_regex.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* from main.c */ +void regress(FILE *); +void try(char *, char *, char *, char *, char *, int); +int options(int, char *); +int opt(int, char *); +void fixstr(char *); +char *check(char *, regmatch_t, char *); + +/* from split.c */ +int split(char *string, char *fields[], int nfields, const char *sep); -- cgit v1.2.3 From e2f4f3dab373b605b62ac175115f264a5c417eb6 Mon Sep 17 00:00:00 2001 From: Yuri Pankov Date: Sun, 11 Jun 2017 14:06:03 +0300 Subject: 8366 remove warlock leftovers from usr/src/cmd and usr/src/lib Reviewed by: Toomas Soome Reviewed by: Robert Mustacchi Approved by: Hans Rosenfeld --- usr/src/cmd/sgs/libelf/Makefile.com | 4 +- usr/src/cmd/sgs/libelf/Makefile.targ | 39 ------------ usr/src/cmd/sgs/libelf/common/begin.c | 10 --- usr/src/cmd/sgs/libelf/common/clscook.c | 9 --- usr/src/cmd/sgs/libelf/common/cook.c | 6 -- usr/src/cmd/sgs/libelf/common/decl.h | 83 ------------------------- usr/src/cmd/sgs/libelf/common/end.c | 14 ----- usr/src/cmd/sgs/libelf/common/error.c | 4 -- usr/src/cmd/sgs/libelf/common/getscn.c | 5 +- usr/src/cmd/sgs/libelf/common/input.c | 5 -- usr/src/cmd/sgs/libelf/common/libelf.wlcmd | 98 ------------------------------ usr/src/cmd/sgs/libelf/common/newdata.c | 4 -- usr/src/cmd/sgs/libelf/common/newscn.c | 8 --- usr/src/cmd/sgs/libelf/common/update.c | 3 - usr/src/cmd/sgs/libelf/misc/demangle.c | 2 - usr/src/cmd/sgs/libelf/misc/nlist.c | 6 -- usr/src/cmd/syslogd/syslogd.c | 15 ----- usr/src/cmd/syslogd/syslogd.h | 9 --- usr/src/lib/libnsl/rpc/svc_run.c | 4 -- usr/src/lib/libnsl/rpc/svc_vc.c | 8 --- usr/src/lib/libtnfctl/Makefile.com | 8 --- usr/src/lib/libtnfctl/checklib.c | 24 -------- usr/src/lib/libtnfctl/internal.c | 29 --------- usr/src/lib/libtnfctl/kernel_int.c | 8 --- usr/src/lib/libtnfctl/prb_proc.h | 3 - usr/src/lib/libtnfctl/prb_proc_int.h | 5 -- usr/src/lib/libtnfctl/probes.c | 6 -- usr/src/lib/libtnfctl/sym.c | 4 -- usr/src/lib/libtnfctl/tnfctl_int.h | 39 ------------ usr/src/lib/libtnfctl/wlcmd | 65 -------------------- 30 files changed, 2 insertions(+), 525 deletions(-) delete mode 100644 usr/src/cmd/sgs/libelf/common/libelf.wlcmd delete mode 100644 usr/src/lib/libtnfctl/wlcmd (limited to 'usr/src') diff --git a/usr/src/cmd/sgs/libelf/Makefile.com b/usr/src/cmd/sgs/libelf/Makefile.com index 95e4009445..5a6d7e0a5d 100644 --- a/usr/src/cmd/sgs/libelf/Makefile.com +++ b/usr/src/cmd/sgs/libelf/Makefile.com @@ -60,8 +60,6 @@ ROOTDEMODIRS= $(ROOTDEMODIRBASE) include $(SRC)/cmd/sgs/Makefile.com -WARLOCKFILES= $(OBJECTS:%.o=wlocks/%.ll) - MAPFILES = ../common/mapfile-vers DYNFLAGS += $(VERSREF) @@ -109,6 +107,6 @@ $(ROOTFS_DYNLIB64) := FILEMODE= 755 LIBS = $(DYNLIB) $(LINTLIB) -CLEANFILES += $(LINTOUTS) $(BLTSRCS) $(BLTFILES) $(WARLOCKFILES) +CLEANFILES += $(LINTOUTS) $(BLTSRCS) $(BLTFILES) .PARALLEL: $(LIBS) diff --git a/usr/src/cmd/sgs/libelf/Makefile.targ b/usr/src/cmd/sgs/libelf/Makefile.targ index 22f6c261e8..0ca8d64218 100644 --- a/usr/src/cmd/sgs/libelf/Makefile.targ +++ b/usr/src/cmd/sgs/libelf/Makefile.targ @@ -90,45 +90,6 @@ pics/ar.o: msg.h objs/xlate.o \ pics/xlate.o: xlate.c -# -# Targets needed to support running of Warlock. The old warlock can be -# located at: -# suntools.eng:/export/tools/internal/warlock -# -# to use add the following to your path: -# export PATH=/net/suntools.eng/export/tools/internal/warlock/bin:$PATH -# -# The newer warlock is at: -# export PATH=/ws/onnv-gate/public/warlock/$MACH:$PATH -# -# This target has value for manual debugging, but is not suitable -# for production use. For this reason, the necessary rules are commented -# out with '###'. Remove the comments to use it. -# -###warlock := CFLAGS= -### -###.PARALLEL: $(WARLOCKFILES) -###warlock: wlocks .WAIT warlock_files -### warlock -c ../common/libelf.wlcmd $(WARLOCKFILES) -### -###warlock_files: $(BLTSRCS) .WAIT $(WARLOCKFILES) -### -###wlocks: -### -@mkdir -p $@ -### -###wlocks/%.ll: %.c -### wlcc $(CFLAGS) $(CPPFLAGS) -o $@ $< -### -###wlocks/%.ll: ../misc/%.c -### wlcc $(CFLAGS) $(CPPFLAGS) -o $@ $< -### -###wlocks/%.ll: ../common/%.c -### wlcc $(CFLAGS) $(CPPFLAGS) -o $@ $< -### -###wlocks/%64.ll: ../common/%.c -### wlcc -D_ELF64 $(CFLAGS) $(CPPFLAGS) -o $@ $< - - # Special target for native builds (ie. when we need to build a version of ld # to build a version of ld :-). diff --git a/usr/src/cmd/sgs/libelf/common/begin.c b/usr/src/cmd/sgs/libelf/common/begin.c index d4e3639207..1eebbfefaf 100644 --- a/usr/src/cmd/sgs/libelf/common/begin.c +++ b/usr/src/cmd/sgs/libelf/common/begin.c @@ -29,8 +29,6 @@ * All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -117,14 +115,12 @@ _elf_regular(int fd, unsigned flags) /* initialize regular file */ return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*elf)) elf->ed_fd = fd; elf->ed_myflags |= flags; if (_elf_inmap(elf) != OK_YES) { free(elf); return (0); } - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*elf)) return (elf); } @@ -214,7 +210,6 @@ elf_memory(char *image, size_t sz) _elf_seterr(EMEM_ELF, errno); return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*elf)) elf->ed_fd = -1; elf->ed_myflags |= EDF_READ | EDF_MEMORY; elf->ed_image = elf->ed_ident = image; @@ -227,7 +222,6 @@ elf_memory(char *image, size_t sz) elf->ed_identsz = EI_NIDENT; elf->ed_activ = 1; elf = _elf_config(elf); - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*elf)) return (elf); } @@ -337,14 +331,12 @@ elf_begin(int fd, Elf_Cmd cmd, Elf *ref) _elf_seterr(EMEM_ELF, errno); return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*elf)) ELFRWLOCKINIT(&elf->ed_rwlock); elf->ed_fd = fd; elf->ed_activ = 1; elf->ed_myflags |= EDF_WRITE; if (cmd == ELF_C_IMAGE) elf->ed_myflags |= EDF_WRALLOC; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*elf)) return (elf); case ELF_C_RDWR: flags = EDF_WRITE | EDF_READ; @@ -386,10 +378,8 @@ elf_begin(int fd, Elf_Cmd cmd, Elf *ref) ELFUNLOCK(ref); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*elf)) elf->ed_activ = 1; elf = _elf_config(elf); - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*elf)) return (elf); } diff --git a/usr/src/cmd/sgs/libelf/common/clscook.c b/usr/src/cmd/sgs/libelf/common/clscook.c index e571de5b1a..a34bf62c6e 100644 --- a/usr/src/cmd/sgs/libelf/common/clscook.c +++ b/usr/src/cmd/sgs/libelf/common/clscook.c @@ -91,7 +91,6 @@ static Okay _elf_prepscn(Elf *elf, size_t cnt) { - NOTE(ASSUMING_PROTECTED(*elf)) Elf_Scn * s; Elf_Scn * end; @@ -102,7 +101,6 @@ _elf_prepscn(Elf *elf, size_t cnt) _elf_seterr(EMEM_SCN, errno); return (OK_NO); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) elf->ed_scntabsz = cnt; end = s + cnt; elf->ed_hdscn = s; @@ -136,7 +134,6 @@ _elf_prepscn(Elf *elf, size_t cnt) s->s_myflags = SF_ALLOC; s->s_hdnode = 0; s->s_tlnode = 0; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s)) return (OK_YES); } @@ -144,14 +141,12 @@ _elf_prepscn(Elf *elf, size_t cnt) Okay _elf_cookscn(Elf_Scn * s) { - NOTE(ASSUMING_PROTECTED(*s, *(s->s_elf))) Elf * elf; Shdr * sh; register Dnode * d = &s->s_dnode; size_t fsz, msz; unsigned work; - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*d)) s->s_hdnode = s->s_tlnode = d; s->s_err = 0; s->s_shflags = 0; @@ -191,7 +186,6 @@ _elf_cookscn(Elf_Scn * s) s->s_myflags |= SF_READY; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*d)) return (OK_YES); } @@ -218,7 +212,6 @@ _elf_snode() int _elf_ehdr(Elf * elf, int inplace) { - NOTE(ASSUMING_PROTECTED(*elf)) register size_t fsz; /* field size */ Elf_Data dst, src; @@ -295,7 +288,6 @@ _elf_ehdr(Elf * elf, int inplace) int _elf_phdr(Elf * elf, int inplace) { - NOTE(ASSUMING_PROTECTED(*elf)) register size_t fsz, msz; Elf_Data dst, src; Ehdr * eh = elf->ed_ehdr; /* must be present */ @@ -355,7 +347,6 @@ _elf_phdr(Elf * elf, int inplace) int _elf_shdr(Elf * elf, int inplace) { - NOTE(ASSUMING_PROTECTED(*elf)) register size_t fsz, msz; size_t scncnt; Elf_Data dst, src; diff --git a/usr/src/cmd/sgs/libelf/common/cook.c b/usr/src/cmd/sgs/libelf/common/cook.c index 746a2285b5..5f9e93ca5e 100644 --- a/usr/src/cmd/sgs/libelf/common/cook.c +++ b/usr/src/cmd/sgs/libelf/common/cook.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -99,10 +97,8 @@ _elf_dnode() _elf_seterr(EMEM_DNODE, errno); return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*d)) *d = _elf_dnode_init; d->db_myflags = DBF_ALLOC; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*d)) return (d); } @@ -111,7 +107,6 @@ _elf_dnode() int _elf_slide(Elf * elf) { - NOTE(ASSUMING_PROTECTED(*elf)) Elf *par = elf->ed_parent; size_t sz, szof; register char *dst; @@ -162,7 +157,6 @@ _elf_slide(Elf * elf) Okay _elf_cook(Elf * elf) { - NOTE(ASSUMING_PROTECTED(*elf)) register int inplace = 1; if (elf->ed_kind != ELF_K_ELF) diff --git a/usr/src/cmd/sgs/libelf/common/decl.h b/usr/src/cmd/sgs/libelf/common/decl.h index 613bfbba41..9ccca2e5a9 100644 --- a/usr/src/cmd/sgs/libelf/common/decl.h +++ b/usr/src/cmd/sgs/libelf/common/decl.h @@ -30,7 +30,6 @@ #define _DECL_H #include -#include #include <_libelf.h> #include #include @@ -147,89 +146,45 @@ struct Elf_Scn Dnode s_dnode; /* every scn needs one */ }; -NOTE(MUTEX_PROTECTS_DATA(Elf_Scn::s_mutex, Elf_Scn Dnode Elf_Data)) -NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf_Data)) -NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf32_Shdr Elf32_Sym)) -NOTE(READ_ONLY_DATA(Elf_Scn::s_elf)) -NOTE(READ_ONLY_DATA(Dnode::db_scn)) - - /* * Designates whether or not we are in a threaded_app. */ extern int *_elf_libc_threaded; #define elf_threaded (_elf_libc_threaded && *_elf_libc_threaded) -#ifdef __lock_lint -#define SCNLOCK(x) (void) mutex_lock(&((Elf_Scn *)x)->s_mutex); -#else #define SCNLOCK(x) \ if (elf_threaded) \ (void) mutex_lock(&((Elf_Scn *)x)->s_mutex); -#endif -#ifdef __lock_lint -#define SCNUNLOCK(x) (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex); -#else #define SCNUNLOCK(x) \ if (elf_threaded) \ (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex); -#endif -#ifdef __lock_lint -#define UPGRADELOCKS(e, s)\ - (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ - (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ - (void) rw_wrlock(&((Elf *)e)->ed_rwlock); -#else #define UPGRADELOCKS(e, s)\ if (elf_threaded) { \ (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ (void) rw_wrlock(&((Elf *)e)->ed_rwlock); \ } -#endif -#ifdef __lock_lint -#define DOWNGRADELOCKS(e, s)\ - (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ - (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ - (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); -#else #define DOWNGRADELOCKS(e, s)\ if (elf_threaded) { \ (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \ } -#endif -#ifdef __lock_lint -#define READLOCKS(e, s) \ - (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ - (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); -#else #define READLOCKS(e, s) \ if (elf_threaded) { \ (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \ } -#endif -#ifdef __lock_lint -#define READUNLOCKS(e, s) \ - (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ - (void) rw_unlock(&((Elf *)e)->ed_rwlock); -#else #define READUNLOCKS(e, s) \ if (elf_threaded) { \ (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ } -#endif - - - #define SF_ALLOC 0x1 /* applies to Scn */ #define SF_READY 0x2 /* has section been cooked */ @@ -350,32 +305,17 @@ struct Elf unsigned ed_uflags; /* elf descriptor flags */ }; -NOTE(RWLOCK_PROTECTS_DATA(Elf::ed_rwlock, Elf)) -NOTE(RWLOCK_COVERS_LOCKS(Elf::ed_rwlock, Elf_Scn::s_mutex)) - -#ifdef __lock_lint -#define ELFRLOCK(e) (void) rw_rdlock(&((Elf *)e)->ed_rwlock); -#else #define ELFRLOCK(e) \ if (elf_threaded) \ (void) rw_rdlock(&((Elf *)e)->ed_rwlock); -#endif -#ifdef __lock_lint -#define ELFWLOCK(e) (void) rw_wrlock(&((Elf *)e)->ed_rwlock); -#else #define ELFWLOCK(e) \ if (elf_threaded) \ (void) rw_wrlock(&((Elf *)e)->ed_rwlock); -#endif -#ifdef __lock_lint -#define ELFUNLOCK(e) (void) rw_unlock(&((Elf *)e)->ed_rwlock); -#else #define ELFUNLOCK(e) \ if (elf_threaded) \ (void) rw_unlock(&((Elf *)e)->ed_rwlock); -#endif #define EDF_ASALLOC 0x1 /* applies to ed_arsym */ #define EDF_EHALLOC 0x2 /* applies to ed_ehdr */ @@ -409,12 +349,6 @@ typedef enum /* * General thread management macros */ -#ifdef __lock_lint -#define ELFACCESSDATA(a, b) \ - (void) mutex_lock(&_elf_globals_mutex); \ - a = b; \ - (void) mutex_unlock(&_elf_globals_mutex); -#else #define ELFACCESSDATA(a, b) \ if (elf_threaded) { \ (void) mutex_lock(&_elf_globals_mutex); \ @@ -422,28 +356,16 @@ typedef enum (void) mutex_unlock(&_elf_globals_mutex); \ } else \ a = b; -#endif -#ifdef __lock_lint -#define ELFRWLOCKINIT(lock) \ - (void) rwlock_init((lock), USYNC_THREAD, 0); -#else #define ELFRWLOCKINIT(lock) \ if (elf_threaded) { \ (void) rwlock_init((lock), USYNC_THREAD, 0); \ } -#endif -#ifdef __lock_lint -#define ELFMUTEXINIT(lock) \ - (void) mutex_init(lock, USYNC_THREAD, 0); -#else #define ELFMUTEXINIT(lock) \ if (elf_threaded) { \ (void) mutex_init(lock, USYNC_THREAD, 0); \ } -#endif - extern Member *_elf_armem(Elf *, char *, size_t); extern void _elf_arinit(Elf *); @@ -487,11 +409,6 @@ extern mutex_t _elf_globals_mutex; extern off_t _elf64_update(Elf * elf, Elf_Cmd cmd); extern int _elf64_swap_wrimage(Elf *elf); -/* CSTYLED */ -NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \ - _elf_byte _elf32_ehdr_init _elf64_ehdr_init _elf_encode \ - _elf_snode_init _elf_work)) - #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/sgs/libelf/common/end.c b/usr/src/cmd/sgs/libelf/common/end.c index 134c8ac25e..037f26f87d 100644 --- a/usr/src/cmd/sgs/libelf/common/end.c +++ b/usr/src/cmd/sgs/libelf/common/end.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include "libelf.h" @@ -53,7 +51,6 @@ elf_end(Elf * elf) return (rc); } -#ifndef __lock_lint while (elf->ed_activ == 0) { for (s = elf->ed_hdscn; s != 0; s = s->s_next) { if (s->s_myflags & SF_ALLOC) { @@ -140,17 +137,6 @@ elf_end(Elf * elf) if (elf) { ELFUNLOCK(elf) } -#else - /* - * This sill stuff is here to make warlock happy - * durring it's lock checking. The problem is that it - * just can't track the multiple dynamic paths through - * the above loop so we just give it a simple one it can - * look at. - */ - _elf_unmap(elf->ed_image, elf->ed_imagesz); - ELFUNLOCK(elf) -#endif return (0); } diff --git a/usr/src/cmd/sgs/libelf/common/error.c b/usr/src/cmd/sgs/libelf/common/error.c index 0a55a9efe6..52b2cb2548 100644 --- a/usr/src/cmd/sgs/libelf/common/error.c +++ b/usr/src/cmd/sgs/libelf/common/error.c @@ -60,22 +60,18 @@ _elf_seterr(Msg lib_err, int sys_err) intptr_t encerr = ((int)lib_err << ELFERRSHIFT) | (sys_err & SYSERRMASK); -#ifndef __lock_lint if (thr_main()) { _elf_err = (int)encerr; return; } -#endif (void) thr_keycreate_once(&errkey, 0); (void) thr_setspecific(errkey, (void *)encerr); } int _elf_geterr() { -#ifndef __lock_lint if (thr_main()) return (_elf_err); -#endif return ((uintptr_t)pthread_getspecific(errkey)); } diff --git a/usr/src/cmd/sgs/libelf/common/getscn.c b/usr/src/cmd/sgs/libelf/common/getscn.c index 2416f2cfb4..f0a71d0734 100644 --- a/usr/src/cmd/sgs/libelf/common/getscn.c +++ b/usr/src/cmd/sgs/libelf/common/getscn.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "libelf.h" #include "decl.h" #include "msg.h" @@ -68,7 +66,6 @@ elf_getscn(Elf * elf, size_t index) return (s); } -#ifndef __lock_lint if (tabsz) s = &elf->ed_hdscn[tabsz - 1]; else @@ -95,7 +92,7 @@ elf_getscn(Elf * elf, size_t index) if (prev_s) { SCNUNLOCK(prev_s) } -#endif + _elf_seterr(EREQ_NDX, 0); ELFUNLOCK(elf); return (0); diff --git a/usr/src/cmd/sgs/libelf/common/input.c b/usr/src/cmd/sgs/libelf/common/input.c index b9dcaac864..fe88f8c897 100644 --- a/usr/src/cmd/sgs/libelf/common/input.c +++ b/usr/src/cmd/sgs/libelf/common/input.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -73,8 +71,6 @@ * to repeatedly call this through out libelf. */ static unsigned long _elf_pagesize = 0; -NOTE(SCHEME_PROTECTS_DATA("read only data", _elf_pagesize)) - #define NBITS (8 * sizeof (unsigned)) #define REGSZ (NBITS * _elf_pagesize) @@ -86,7 +82,6 @@ NOTE(SCHEME_PROTECTS_DATA("read only data", _elf_pagesize)) Okay _elf_vm(Elf * elf, size_t base, size_t sz) { - NOTE(ASSUMING_PROTECTED(*elf)) register unsigned *hdreg, hdbit; unsigned *tlreg, tlbit; size_t tail; diff --git a/usr/src/cmd/sgs/libelf/common/libelf.wlcmd b/usr/src/cmd/sgs/libelf/common/libelf.wlcmd deleted file mode 100644 index 5c9c0eb1ce..0000000000 --- a/usr/src/cmd/sgs/libelf/common/libelf.wlcmd +++ /dev/null @@ -1,98 +0,0 @@ -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -root _elf_begin -root _elf_cntl -root _elf_end -root _elf_errmsg -root _elf_errno -root _elf_fill -root _elf_flagdata -root _elf_flagehdr -root _elf_flagelf -root _elf_flagphdr -root _elf_flagscn -root _elf_flagshdr -root _elf32_fsize -root _elf_getarhdr -root _elf_getarsym -root _elf_getbase -root _elf_getdata -root _elf32_getehdr -root _elf_getident -root _elf32_getphdr -root _elf_getscn -root _elf32_getshdr -root _elf_hash -root _elf_kind -root _elf_memory -root _elf_ndxscn -root _elf_newdata -root _elf32_newehdr -root _elf32_newphdr -root _elf_newscn -root _elf_nextscn -root _elf_next -root _elf_rand -root _elf_rawdata -root _elf_rawfile -root _elf_strptr -root _elf_update -root _elf_version -#root _elf32_xlatetof -#root _elf32_xlatetom -root nlist -#root _elf_errmsg_r -root demangle -add xlate.c:xlate/f target `funcs | egrep '_to(m|f)$'` xlate.c:byte_to -add xlate64.c:xlate/f target `funcs | egrep '_to(m|f)$'` xlate64.c:byte_to -# -root _elf_getxoff -root _elf_swap_wrimage -root _gelf_getdyndtflags_1 -root elf_getshnum -root elf_getshstrndx -root gelf_checksum -root gelf_fsize -root gelf_getcap -root gelf_getmove -root gelf_getphdr -root gelf_getrel -root gelf_getrela -root gelf_getsyminfo -root gelf_getsymshndx -root gelf_newehdr -root gelf_newphdr -root gelf_update_cap -root gelf_update_dyn -root gelf_update_ehdr -root gelf_update_move -root gelf_update_phdr -root gelf_update_rel -root gelf_update_rela -root gelf_update_shdr -root gelf_update_syminfo -root gelf_update_symshndx -root gelf_xlatetof -root gelf_xlatetom diff --git a/usr/src/cmd/sgs/libelf/common/newdata.c b/usr/src/cmd/sgs/libelf/common/newdata.c index dfca71ffdc..c3416a7710 100644 --- a/usr/src/cmd/sgs/libelf/common/newdata.c +++ b/usr/src/cmd/sgs/libelf/common/newdata.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "libelf.h" #include "decl.h" #include "msg.h" @@ -84,7 +82,6 @@ elf_newdata(Elf_Scn * s) READUNLOCKS(elf, s) return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*d)) d->db_data.d_version = work; d->db_scn = s; d->db_uflags |= ELF_F_DIRTY; @@ -92,7 +89,6 @@ elf_newdata(Elf_Scn * s) s->s_tlnode->db_next = d; s->s_tlnode = d; rc = &d->db_data; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*d)) READUNLOCKS(elf, s) return (rc); } diff --git a/usr/src/cmd/sgs/libelf/common/newscn.c b/usr/src/cmd/sgs/libelf/common/newscn.c index e765d0badb..a31662456c 100644 --- a/usr/src/cmd/sgs/libelf/common/newscn.c +++ b/usr/src/cmd/sgs/libelf/common/newscn.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "libelf.h" #include "decl.h" #include "msg.h" @@ -65,7 +63,6 @@ elf_newscn(Elf * elf) ELFUNLOCK(elf) return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) s->sb_scn.s_elf = elf; elf->ed_hdscn = elf->ed_tlscn = &s->sb_scn; s->sb_scn.s_uflags |= ELF_F_DIRTY; @@ -74,7 +71,6 @@ elf_newscn(Elf * elf) ELFUNLOCK(elf) return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) tl = elf->ed_tlscn; s->sb_scn.s_elf = elf; s->sb_scn.s_index = tl->s_index + 1; @@ -84,7 +80,6 @@ elf_newscn(Elf * elf) = (Elf32_Half)(tl->s_index + 2); s->sb_scn.s_uflags |= ELF_F_DIRTY; tl = &s->sb_scn; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s)) ELFUNLOCK(elf) return (tl); } else if (elf->ed_class == ELFCLASS64) { @@ -95,7 +90,6 @@ elf_newscn(Elf * elf) ELFUNLOCK(elf) return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) s->sb_scn.s_elf = elf; elf->ed_hdscn = elf->ed_tlscn = &s->sb_scn; s->sb_scn.s_uflags |= ELF_F_DIRTY; @@ -104,7 +98,6 @@ elf_newscn(Elf * elf) ELFUNLOCK(elf) return (0); } - NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*s)) tl = elf->ed_tlscn; s->sb_scn.s_elf = elf; s->sb_scn.s_index = tl->s_index + 1; @@ -114,7 +107,6 @@ elf_newscn(Elf * elf) = (Elf64_Half)(tl->s_index + 2); s->sb_scn.s_uflags |= ELF_F_DIRTY; tl = &s->sb_scn; - NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*s)) ELFUNLOCK(elf) return (tl); } else { diff --git a/usr/src/cmd/sgs/libelf/common/update.c b/usr/src/cmd/sgs/libelf/common/update.c index 98bdafb655..fe0705a928 100644 --- a/usr/src/cmd/sgs/libelf/common/update.c +++ b/usr/src/cmd/sgs/libelf/common/update.c @@ -155,7 +155,6 @@ test_size(Lword hi) static size_t _elf_upd_lib(Elf * elf) { - NOTE(ASSUMING_PROTECTED(*elf)) Lword hi; Lword hibit; Elf_Scn * s; @@ -340,7 +339,6 @@ _elf_upd_lib(Elf * elf) static size_t _elf_upd_usr(Elf * elf) { - NOTE(ASSUMING_PROTECTED(*elf)) Lword hi; Elf_Scn * s; register Lword sz; @@ -455,7 +453,6 @@ _elf_upd_usr(Elf * elf) static size_t wrt(Elf * elf, Xword outsz, unsigned fill, int update_cmd) { - NOTE(ASSUMING_PROTECTED(*elf)) Elf_Data dst, src; unsigned flag; Xword hi, sz; diff --git a/usr/src/cmd/sgs/libelf/misc/demangle.c b/usr/src/cmd/sgs/libelf/misc/demangle.c index ef1f4bd698..1397bfda94 100644 --- a/usr/src/cmd/sgs/libelf/misc/demangle.c +++ b/usr/src/cmd/sgs/libelf/misc/demangle.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "elf_dem.h" #include "String.h" #include "msg.h" @@ -123,7 +122,6 @@ demangle(char *c) extern jmp_buf jbuf; static mutex_t mlock = DEFAULTMUTEX; - NOTE(MUTEX_PROTECTS_DATA(mlock, String)) (void) mutex_lock(&mlock); if (setjmp(jbuf)) { diff --git a/usr/src/cmd/sgs/libelf/misc/nlist.c b/usr/src/cmd/sgs/libelf/misc/nlist.c index be45b9b1da..bd72d8b7fa 100644 --- a/usr/src/cmd/sgs/libelf/misc/nlist.c +++ b/usr/src/cmd/sgs/libelf/misc/nlist.c @@ -28,14 +28,11 @@ * All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13 */ - #include "libelf.h" #include #include #include #include -#include #include "syms.h" #include "gelf.h" @@ -119,9 +116,6 @@ _elf_nlist(int fd, struct nlist * list) return (0); } - -NOTE(SCHEME_PROTECTS_DATA("user provides buffers", nlist)) - int nlist(const char * name, struct nlist * list) { diff --git a/usr/src/cmd/syslogd/syslogd.c b/usr/src/cmd/syslogd/syslogd.c index ed9d41ec60..f3489f02db 100644 --- a/usr/src/cmd/syslogd/syslogd.c +++ b/usr/src/cmd/syslogd/syslogd.c @@ -60,7 +60,6 @@ */ #include -#include #include #include #include @@ -95,7 +94,6 @@ #include #include #include -#include #include #include @@ -804,8 +802,6 @@ net_poll(void *ap) DPRINT1(1, "net_poll(%u): net_thread started\n", mythreadno); - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)) - for (;;) { errno = 0; t_errno = 0; @@ -980,7 +976,6 @@ logmymsg(int pri, char *msg, int flags, int pending) return (-1); } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)) mp->pri = pri; mp->hlp = &LocalHostName; (void) strlcpy(mp->msg, msg, MAXLINE+1); @@ -1016,7 +1011,6 @@ shutdown_msg(void) return (-1); } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)); mp->flags = SHUTDOWN; mp->hlp = &LocalHostName; @@ -1048,7 +1042,6 @@ flushmsg(int flags) return; } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)); mp->flags = FLUSHMSG | flags; mp->hlp = &LocalHostName; @@ -1136,8 +1129,6 @@ formatsys(struct log_ctl *lp, char *msg, int sync) * We should do it here since a single message (msg) * could be composed of many lines. */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)); - if ((mp = new_msg()) == NULL) { MALLOC_FAIL("dropping message"); /* @@ -1233,7 +1224,6 @@ logmsg(void *ap) } else { (void) dataq_dequeue(&inputq, (void **)&mp, 0); } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mp)) DPRINT3(5, "logmsg(%u): msg dispatcher dequeued %p from " "queue %p\n", mythreadno, (void *)mp, (void *)&inputq); @@ -1387,8 +1377,6 @@ logmsg(void *ap) * so the reference count is accurate before any * of the log threads can decrement it. */ - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*mp)) - _NOTE(COMPETING_THREADS_NOW) (void) pthread_mutex_lock(&mp->msg_mutex); for (f = Files; f < &Files[nlogs]; f++) { @@ -1465,7 +1453,6 @@ logit(void *ap) DPRINT4(5, "logit(%u): logger started for \"%s\" (queue %p, filed " "%p)\n", f->f_thread, f->f_un.f_fname, (void *)&f->f_queue, (void *)f); - _NOTE(COMPETING_THREADS_NOW); while (f->f_type != F_UNUSED) { (void) dataq_dequeue(&f->f_queue, (void **)&mp, 0); @@ -4117,8 +4104,6 @@ new_msg(void) if ((lm = malloc(sizeof (log_message_t))) == NULL) return ((log_message_t *)NULL); - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*lm)) - if (pthread_mutex_init(&lm->msg_mutex, NULL) != 0) return ((log_message_t *)NULL); lm->refcnt = 0; diff --git a/usr/src/cmd/syslogd/syslogd.h b/usr/src/cmd/syslogd/syslogd.h index 2d1680a94e..9ec1f1dbe5 100644 --- a/usr/src/cmd/syslogd/syslogd.h +++ b/usr/src/cmd/syslogd/syslogd.h @@ -39,8 +39,6 @@ #ifndef _SYSLOGD_H #define _SYSLOGD_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -110,10 +108,6 @@ typedef struct log_message { char msg[MAXLINE+1]; /* the message itself */ } log_message_t; -_NOTE(MUTEX_PROTECTS_DATA(log_message_t::msg_mutex, log_message_t)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(log_message_t)) - - /* * format of a saved message. For each active file we are logging * we save the last message and the current message, to make it @@ -175,9 +169,6 @@ struct filed { } f_un; }; -_NOTE(MUTEX_PROTECTS_DATA(filed::filed_mutex, filed)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(filed)) - /* values for f_type */ #define F_UNUSED 0 /* unused entry */ #define F_FILE 1 /* regular file */ diff --git a/usr/src/lib/libnsl/rpc/svc_run.c b/usr/src/lib/libnsl/rpc/svc_run.c index 9b968fe8f6..feee5791d7 100644 --- a/usr/src/lib/libnsl/rpc/svc_run.c +++ b/usr/src/lib/libnsl/rpc/svc_run.c @@ -184,10 +184,6 @@ static bool_t svc_exit_done = TRUE; /* END PROTECTED BY svc_exit_mutex */ -/* - * Warlock section - */ - /* VARIABLES PROTECTED BY svc_mutex: svc_thr_total, svc_thr_active, svc_pending_fds, svc_next_pending, svc_last_pending, svc_total_pending, svc_thr_total_creates, diff --git a/usr/src/lib/libnsl/rpc/svc_vc.c b/usr/src/lib/libnsl/rpc/svc_vc.c index bd001a43b8..04badff6f6 100644 --- a/usr/src/lib/libnsl/rpc/svc_vc.c +++ b/usr/src/lib/libnsl/rpc/svc_vc.c @@ -1731,13 +1731,9 @@ svc_vc_reply(SVCXPRT *xprt, struct rpc_msg *msg) caddr_t xdr_location; bool_t has_args; -#ifdef __lock_lint - (void) mutex_lock(&svc_send_mutex(SVCEXT(xprt)->parent)); -#else if (svc_mt_mode != RPC_SVC_MT_NONE) /* LINTED pointer alignment */ (void) mutex_lock(&svc_send_mutex(SVCEXT(xprt)->parent)); -#endif if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { @@ -1758,13 +1754,9 @@ svc_vc_reply(SVCXPRT *xprt, struct rpc_msg *msg) } (void) xdrrec_endofrecord(xdrs, TRUE); -#ifdef __lock_lint - (void) mutex_unlock(&svc_send_mutex(SVCEXT(xprt)->parent)); -#else if (svc_mt_mode != RPC_SVC_MT_NONE) /* LINTED pointer alignment */ (void) mutex_unlock(&svc_send_mutex(SVCEXT(xprt)->parent)); -#endif return (stat); } diff --git a/usr/src/lib/libtnfctl/Makefile.com b/usr/src/lib/libtnfctl/Makefile.com index 569b7e92d7..4117e0fa8a 100644 --- a/usr/src/lib/libtnfctl/Makefile.com +++ b/usr/src/lib/libtnfctl/Makefile.com @@ -116,12 +116,4 @@ objs/%.o pics/%.o: ../%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) -WARLOCK_FILES= $(OBJECTS.c:%.o=%.ll) -CLEANFILES= $(WARLOCK_FILES) -warlock_files: $(WARLOCK_FILES) -%.ll: ../%.c - wlcc $(CFLAGS) $(CPPFLAGS) -o $@ $< -warlock: warlock_files - warlock -c wlcmd $(WARLOCK_FILES) - include ../../Makefile.targ diff --git a/usr/src/lib/libtnfctl/checklib.c b/usr/src/lib/libtnfctl/checklib.c index cbdb0dbc5f..324cbcfbd1 100644 --- a/usr/src/lib/libtnfctl/checklib.c +++ b/usr/src/lib/libtnfctl/checklib.c @@ -23,8 +23,6 @@ * Copyright (c) 1994, by Sun Microsytems, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Functions to sync up library list with that of the run time linker */ @@ -73,22 +71,11 @@ tnfctl_check_libs(tnfctl_handle_t *hndl) * this thread has the lock held. The return value "release_lock" indicates * whether the lock should be released or not. It can be passed into * _tnfctl_unlock_libs() which will do the right thing. - * - * All of this is a bit too complex for warlock. Here we give warlock a - * simpler view, that these routines have the side effect of acquiring and - * releasing the lock, period. */ tnfctl_errcode_t _tnfctl_lock_libs(tnfctl_handle_t *hndl, boolean_t *release_lock) { -#if defined(__lock_lint) - - NOTE(MUTEX_ACQUIRED_AS_SIDE_EFFECT(&warlock_kludge->lmap_lock)) - mutex_lock(&warlock_kludge->lmap_lock); - -#else - /* this interface is only for INTERNAL_MODE clients */ assert(hndl->mode == INTERNAL_MODE); @@ -107,20 +94,11 @@ _tnfctl_lock_libs(tnfctl_handle_t *hndl, boolean_t *release_lock) *release_lock = B_TRUE; return (TNFCTL_ERR_NONE); - -#endif } void _tnfctl_unlock_libs(tnfctl_handle_t *hndl, boolean_t release_lock) { -#if defined(__lock_lint) - - NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&warlock_kludge->lmap_lock)) - mutex_unlock(&warlock_kludge->lmap_lock); - -#else - /* this interface is only for INTERNAL_MODE clients */ assert(hndl->mode == INTERNAL_MODE); @@ -128,8 +106,6 @@ _tnfctl_unlock_libs(tnfctl_handle_t *hndl, boolean_t release_lock) hndl->in_objlist = B_FALSE; mutex_unlock(&_tnfctl_lmap_lock); } - -#endif } /* diff --git a/usr/src/lib/libtnfctl/internal.c b/usr/src/lib/libtnfctl/internal.c index fba6909c14..dbe97fc714 100644 --- a/usr/src/lib/libtnfctl/internal.c +++ b/usr/src/lib/libtnfctl/internal.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Implements the routines that are needed only for internal process * control. @@ -276,19 +274,8 @@ boolean_t _tnfctl_libs_changed = B_FALSE; * a lock it already holds. */ static thread_t lock_holder = 0; /* XXX - no tid with 0 */ -NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, lock_holder)) -NOTE(DATA_READABLE_WITHOUT_LOCK(lock_holder)) -/* - * In the routines below, we will appear to use a different lock if we - * are running lock_lint/warlock. We define a macro to represent whichever - * lock is appropriate. - */ -#if defined(__lock_lint) -#define LMAP_LOCK (&warlock_kludge->lmap_lock) -#else #define LMAP_LOCK (&_tnfctl_lmap_lock) -#endif /* * dlclose interposition with a recursive lock so that a .fini section @@ -408,19 +395,3 @@ _tnfctl_internal_getlock() mutex_unlock(&_tnfctl_internalguard_lock); return (TNFCTL_ERR_NONE); } - - -#ifdef __lock_lint - -/* - * dummy function for lock_lint (warlock) static lock analysis. - */ -int -warlock_dummy() -{ - int (*fp)(); - - return ((*fp)()); -} - -#endif diff --git a/usr/src/lib/libtnfctl/kernel_int.c b/usr/src/lib/libtnfctl/kernel_int.c index b9260f3212..9580440919 100644 --- a/usr/src/lib/libtnfctl/kernel_int.c +++ b/usr/src/lib/libtnfctl/kernel_int.c @@ -23,8 +23,6 @@ * Copyright (c) 1994, by Sun Microsytems, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Interfaces to control kernel tracing and kernel probes */ @@ -390,9 +388,7 @@ _tnfctl_refresh_kernel(tnfctl_handle_t *hndl) if (prexstat) return (prexstat); - NOTE(NO_COMPETING_THREADS_NOW) obj_p = hndl->objlist; - NOTE(COMPETING_THREADS_NOW) assert((obj_p != NULL) && (obj_p->probes != NULL)); for (i = 1; i <= maxprobe; ++i) { @@ -474,9 +470,7 @@ alloc_probe_space(tnfctl_handle_t *hndl, int maxprobe) prbctlref_t *probe_p; /* we know that: hndl->maxprobe != maxprobe */ - NOTE(NO_COMPETING_THREADS_NOW) obj_p = hndl->objlist; - NOTE(COMPETING_THREADS_NOW) if (obj_p == NULL) { /* no objects allocated */ o_pp = &(hndl->objlist); @@ -511,9 +505,7 @@ alloc_probe_space(tnfctl_handle_t *hndl, int maxprobe) probe_p = &(nobj_p->probes[0]); for (i = min_probe_num; i <= maxprobe; i++) { - NOTE(NO_COMPETING_THREADS_NOW) probe_p->obj = nobj_p; - NOTE(COMPETING_THREADS_NOW) probe_p->probe_id = i; probe_p->probe_handle = calloc(1, sizeof (tnfctl_probe_t)); if (probe_p->probe_handle == NULL) { diff --git a/usr/src/lib/libtnfctl/prb_proc.h b/usr/src/lib/libtnfctl/prb_proc.h index 1e32d46f65..9693404e84 100644 --- a/usr/src/lib/libtnfctl/prb_proc.h +++ b/usr/src/lib/libtnfctl/prb_proc.h @@ -45,7 +45,6 @@ extern "C" { #include #include #include -#include #include @@ -92,8 +91,6 @@ typedef struct prb_proc_state { long ps_syscallnum; } prb_proc_state_t; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", prb_proc_state)) - /* * Opaque /proc handle */ diff --git a/usr/src/lib/libtnfctl/prb_proc_int.h b/usr/src/lib/libtnfctl/prb_proc_int.h index 24c3ab2a8d..8c4d6bf31d 100644 --- a/usr/src/lib/libtnfctl/prb_proc_int.h +++ b/usr/src/lib/libtnfctl/prb_proc_int.h @@ -27,8 +27,6 @@ #ifndef _PRB_PROC_INT_H #define _PRB_PROC_INT_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -41,7 +39,6 @@ extern "C" { #include #include -#include #include "prb_proc.h" @@ -61,7 +58,6 @@ typedef unsigned char bptsave_t; typedef struct shmem_msg { boolean_t spin; } shmem_msg_t; -NOTE(SCHEME_PROTECTS_DATA("parent writes; child reads", shmem_msg)) /* * per /proc handle state @@ -74,7 +70,6 @@ struct prb_proc_ctl { boolean_t bpt_inserted; /* is bpt inserted ? */ uintptr_t dbgaddr; }; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", prb_proc_ctl)) /* * Declarations diff --git a/usr/src/lib/libtnfctl/probes.c b/usr/src/lib/libtnfctl/probes.c index 0014974b45..57d8b139fd 100644 --- a/usr/src/lib/libtnfctl/probes.c +++ b/usr/src/lib/libtnfctl/probes.c @@ -23,8 +23,6 @@ * Copyright (c) 1994, by Sun Microsytems, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Load object and probe discovery in target process. This file is * not exercised for kernel probes. @@ -71,8 +69,6 @@ typedef struct link_args2 { ulong_t la_base; } link_args2_t; -NOTE(SCHEME_PROTECTS_DATA("always automatic", link_args link_args2)) - static int per_loadobj(void *, const tnfctl_ind_obj_info_t *, void *); static objlist_t *loadobj_find(tnfctl_handle_t *, const tnfctl_ind_obj_info_t *); @@ -271,7 +267,6 @@ _tnfctl_free_objs_and_probes(tnfctl_handle_t *hndl) { objlist_t *obj, *tmp; - NOTE(NO_COMPETING_THREADS_NOW) obj = hndl->objlist; while (obj) { free_obj_fields(obj); @@ -280,7 +275,6 @@ _tnfctl_free_objs_and_probes(tnfctl_handle_t *hndl) free(tmp); } hndl->objlist = NULL; - NOTE(COMPETING_THREADS_NOW) } /* diff --git a/usr/src/lib/libtnfctl/sym.c b/usr/src/lib/libtnfctl/sym.c index 350549d5e4..82730e9f51 100644 --- a/usr/src/lib/libtnfctl/sym.c +++ b/usr/src/lib/libtnfctl/sym.c @@ -23,8 +23,6 @@ * Copyright (c) 1994, by Sun Microsytems, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Routines that * - return an address for a symbol name @@ -42,7 +40,6 @@ #include #include #include -#include #include "tnfctl_int.h" #include "dbg.h" @@ -56,7 +53,6 @@ typedef struct sym_args { char *sa_name; uintptr_t sa_addr; } sym_args_t; -NOTE(SCHEME_PROTECTS_DATA("always automatic", sym_args)) /* * Declarations diff --git a/usr/src/lib/libtnfctl/tnfctl_int.h b/usr/src/lib/libtnfctl/tnfctl_int.h index 681d4964cc..01f559e03e 100644 --- a/usr/src/lib/libtnfctl/tnfctl_int.h +++ b/usr/src/lib/libtnfctl/tnfctl_int.h @@ -26,8 +26,6 @@ #ifndef _TNFCTL_INT_H #define _TNFCTL_INT_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Interfaces private to libtnfctl * layout of tnfctl handle structure @@ -44,30 +42,15 @@ extern "C" { #include #include #include "prb_proc.h" -/* for warlock (lock_lint) static lock checking */ -#include #include #include -/* - * This bogus structure is our way of getting around the fact that - * warlock does not handle recursive locks (warlock does not complain - * when anonymous locks, such as warlock_kludge->lmap_lock, are - * multiply locked). - */ -#if defined(__lock_lint) -struct warlock { - mutex_t lmap_lock; -} *warlock_kludge; -#endif - /* * global variables used for INTERNAL_MODE synchronization with * dlopen's and dlclose's on another thread. */ extern mutex_t _tnfctl_lmap_lock; extern boolean_t _tnfctl_libs_changed; -NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, _tnfctl_libs_changed)) /* Project private interface - function name in target */ #define TRACE_END_FUNC "tnf_trace_end" @@ -93,9 +76,6 @@ struct prbctlref { tnfctl_probe_t *probe_handle; /* handle visible to client */ }; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", prbctlref)) -NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, prbctlref::{addr obj})) - /* per object state */ struct objlist { boolean_t new_probe; /* relative to last library change */ @@ -109,7 +89,6 @@ struct objlist { prbctlref_t *probes; /* pointer to an array of probes */ objlist_t *next; }; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", objlist)) /* per probe state that is freed only on tnfctl_close() */ struct tnfctl_probe_handle { @@ -118,7 +97,6 @@ struct tnfctl_probe_handle { void *client_registered_data; struct tnfctl_probe_handle *next; }; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", tnfctl_probe_handle)) /* * state saved per tnfctl handle @@ -170,9 +148,6 @@ struct tnfctl_handle { pid_t (*p_getpid)(void *prochandle); }; -NOTE(SCHEME_PROTECTS_DATA("one thread per handle", tnfctl_handle)) -NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, tnfctl_handle::objlist)) - typedef enum comb_op { PRB_COMB_CHAIN = 0, /* call the down, then the next */ PRB_COMB_COUNT = 1 /* how many? */ @@ -319,18 +294,6 @@ tnfctl_errcode_t tnfctl_status_map(int); * lock_lint won't have to see the conditional locking. * CAUTION: Be aware that these macros have a return() embedded in them. */ -#ifdef __lock_lint - -#define LOCK(hndl, stat, release) (void) _tnfctl_lock_libs(hndl, &release) - -#define LOCK_SYNC(hndl, stat, release) \ - (void) _tnfctl_lock_libs(hndl, &release); \ - (void) _tnfctl_sync_lib_list(hndl) - -#define UNLOCK(hndl, release) _tnfctl_unlock_libs(hndl, release) - -#else - #define LOCK(hndl, stat, release) \ if (hndl->mode == INTERNAL_MODE) { \ stat = _tnfctl_lock_libs(hndl, &release); \ @@ -357,8 +320,6 @@ tnfctl_errcode_t tnfctl_status_map(int); _tnfctl_unlock_libs(hndl, release_lock); \ else -#endif - #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libtnfctl/wlcmd b/usr/src/lib/libtnfctl/wlcmd deleted file mode 100644 index 6937afa565..0000000000 --- a/usr/src/lib/libtnfctl/wlcmd +++ /dev/null @@ -1,65 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 1996 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -# Tell warlock not to pursue these calling sequences: - -disallow _tnfctl_sym_find_in_obj \ - _tnfctl_traverse_object \ - _tnfctl_traverse_rela \ - read_a_probe - -disallow _tnfctl_sym_find_in_obj \ - _tnfctl_traverse_object \ - _tnfctl_traverse_dynsym \ - read_a_probe - -disallow dynsec_num \ - _tnfctl_traverse_object \ - _tnfctl_traverse_rela \ - read_a_probe - -disallow dynsec_num \ - _tnfctl_traverse_object \ - _tnfctl_traverse_dynsym \ - read_a_probe - -# Arrange for warlock_dummy() to call all libtnfctl entry points. -interfaces=`sed -n 's/^[ ]*\(tnfctl_.*\);$/\1/p' mapfile-vers` -add warlock_dummy/fp target $interfaces -root $interfaces # make them all roots, too - -# Arrange for libtnfctl callbacks to call warlock_dummy(). Theoretically, -# a client's routine invoked by any of these callbacks could call into any -# public interface. -add pr_func_args::func_p target warlock_dummy -add tnfctl_handle::create_func target warlock_dummy -add tnfctl_handle::destroy_func target warlock_dummy - -# Miscellany -ignore prb_status_str decode_compare comb_compare -ignore real_dlopen real_dlclose -root _tnfctl_dlclose _tnfctl_dlopen # these can get called at any time -ignore `members tnf_probevals_t` -- cgit v1.2.3 From 115716444da43c8948885b687239f3c4187d0897 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Sun, 30 Apr 2017 13:56:40 +0300 Subject: 8131 loader: add support for chain and device BE's Reviewed by: Robert Mustacchi Approved by: Hans Rosenfeld --- usr/src/boot/sys/boot/forth/beadm.4th | 145 +++++++++++++++++--------- usr/src/boot/sys/boot/forth/menu-commands.4th | 17 ++- 2 files changed, 109 insertions(+), 53 deletions(-) (limited to 'usr/src') diff --git a/usr/src/boot/sys/boot/forth/beadm.4th b/usr/src/boot/sys/boot/forth/beadm.4th index 6ed81e8913..31b1fe5db1 100644 --- a/usr/src/boot/sys/boot/forth/beadm.4th +++ b/usr/src/boot/sys/boot/forth/beadm.4th @@ -8,7 +8,7 @@ \ source. A copy of the CDDL is also available via the Internet at \ http://www.illumos.org/license/CDDL. -\ Copyright 2015 Toomas Soome +\ Copyright 2017 Toomas Soome \ This module is implementing the beadm user command to support listing \ and switching Boot Environments (BE) from command line and @@ -83,7 +83,7 @@ variable page_remainder O_RDONLY fopen fd ! reset_line_reading fd @ -1 = if EOPEN throw then - ." BE" dup 2 - spaces ." bootfs" cr + ." BE" dup 2 - spaces ." Type Device" cr begin end_of_file? 0= while @@ -95,6 +95,9 @@ variable page_remainder free_buffers read_line get_name_value + name_buffer strget type + name_buffer strget s" bootfs" compare 0= if 2 spaces then + name_buffer strget s" chain" compare 0= if 3 spaces then value_buffer strget type cr free_buffers repeat @@ -102,12 +105,14 @@ variable page_remainder drop ; -: beadm_bootfs ( be_addr be_len menu_addr menu_len -- addr len flag ) +\ we are called with strings be_name menu_file, to simplify the stack +\ management, we open the menu and free the menu_file. +: beadm_bootfs ( be_addr be_len maddr mlen -- addr len taddr tlen flag | flag ) 0 to end_of_file? - O_RDONLY fopen fd ! - reset_line_reading + 2dup O_RDONLY fopen fd ! + drop free-memory fd @ -1 = if EOPEN throw then - 2swap + reset_line_reading begin end_of_file? 0= while @@ -116,11 +121,12 @@ variable page_remainder get_name_value 2dup value_buffer strget compare 0= if ( title == be ) - 2drop + 2drop \ drop be_name free_buffers read_line get_name_value - value_buffer strget strdup -1 + value_buffer strget strdup + name_buffer strget strdup -1 free_buffers 1 to end_of_file? \ mark end of file to skip the rest else @@ -130,9 +136,9 @@ variable page_remainder fd @ fclose line_buffer strfree read_buffer strfree - dup -1 > if ( dev_addr dev_len ) + dup -1 > if ( be_addr be_len ) 2drop - 0 0 0 + 0 then ; @@ -179,43 +185,55 @@ variable page_remainder ; \ activate be on device. -\ in case of zfs, we query device:/boot/menu.lst for bootfs and -\ use zfs:bootfs: for currdev -\ in case of ufs we have device name without ':', so we just -\ set currdev=device: and hope for best - there are no multiple BE's on ufs +\ if be name was not given, set currdev +\ otherwize, we query device:/boot/menu.lst for bootfs and +\ if found, and bootfs type is chain, attempt chainload. +\ set currdev to bootfs. +\ if we were able to set currdev, reload the config : activate-dev ( dev.addr dev.len be.addr be.len -- ) - 2swap colon- \ remove : at the end of the dev name - 2dup [char] : strchr nip - 0= if ( no ':' in dev name, its ufs ) - 2swap 2drop + + dup 0= if + 2drop + colon- \ remove : at the end of the dev name dup 1+ allocate if ENOMEM throw then dup 2swap 0 -rot strcat colon+ s" currdev" setenv \ setenv currdev = device free-memory else - dup 16 + allocate if ENOMEM throw then - swap 2dup 2>R \ copy of new addr len to return stack - move 2R> \ copy dev name and concat file name - s" :/boot/menu.lst" strcat 2dup \ leave copy to stack - beadm_bootfs if ( dev_addr dev_len addr len ) - 2swap \ addr len dev_addr dev_len - drop - free-memory + 2swap menu.lst + beadm_bootfs if ( addr len taddr tlen ) + 2dup s" chain" compare 0= if + drop free-memory \ free type + 2dup + dup 6 + allocate if ENOMEM throw then + dup >R + 0 s" chain " strcat + 2swap strcat ['] evaluate catch drop + \ We are still there? + R> free-memory \ free chain command + drop free-memory \ free addr + exit + then + drop free-memory \ free type + 2dup [char] : strchr nip 0= if \ have dataset and need to get zfs:pool/ROOT/be: - dup 5 + allocate if ENOMEM throw then - 0 s" zfs:" strcat - 2swap strcat - colon+ + dup 5 + allocate if ENOMEM throw then + 0 s" zfs:" strcat + 2swap strcat + colon+ + then 2dup s" currdev" setenv drop free-memory else - 2drop drop free \ free the file name - ." Failed to process BE/dev" cr abort + ." No such BE in menu.lst or menu.lst is missing." cr + exit then then + \ reset BE menu + 0 page_count ! \ need to do: 0 unload drop free-module-options @@ -233,7 +251,7 @@ variable page_remainder ; \ beadm list [device] -\ beadm activate BE [device] BE +\ beadm activate BE [device] | device \ \ lists BE's from current or specified device /boot/menu.lst file \ activates specified BE by unloading modules, setting currdev and @@ -243,7 +261,7 @@ variable page_remainder dup 0= if ." Usage:" cr - ." beadm activate beName [device]" cr + ." beadm activate {beName [device] | device}" cr ." beadm list [device]" cr ." Use lsdev to get device names." cr drop exit @@ -269,12 +287,12 @@ variable page_remainder then argc 2 = if ( activate be ) \ need to set arg list into proper order - 1 + >R \ save argc+1 to return stack + 1+ >R \ save argc+1 to return stack \ if we have : in name, its device, inject - \ dummy be name, as it must be ufs device + \ empty be name 2dup [char] : strchr nip if ( its : in name ) - s" ufs" R> + 0 0 R> else \ add device, swap with be and receive argc current-dev 2swap R> @@ -348,12 +366,13 @@ builtin: beadm then ; -: be-set-page { | entry count n -- } +: be-set-page { | entry count n device -- } page_count @ 0= if be-pages page_count @ 0= if exit then then + 0 to device s" zfs_be_currpage" getenv dup -1 = if drop s" 1" then @@ -399,25 +418,47 @@ builtin: beadm value_buffer strget 52 i + \ ascii 4 + i s" bootenvansi_caption[4]" 20 +c! setenv - s" set_bootenv" - 52 i + \ ascii 4 + i - s" bootenvmenu_command[4]" 20 +c! setenv + free_buffers read_line \ read value line get_name_value + + \ set menu entry command + name_buffer strget s" chain" compare + 0= if + s" set_be_chain" + else + s" set_bootenv" + then + 52 i + \ ascii 4 + i + s" bootenvmenu_command[4]" 20 +c! setenv + + \ set device name + name_buffer strget s" chain" compare + 0= if + \ for chain, use the value as is + value_buffer strget + else + value_buffer strget 2dup + [char] : strchr nip + 0= if + \ make zfs device name + swap drop + 5 + allocate if + ENOMEM throw + then + s" zfs:" ( addr addr' len' ) + 2 pick swap move ( addr ) + dup to device + 4 value_buffer strget + strcat ( addr len ) + s" :" strcat + then + then + 52 i + \ ascii 4 + i - value_buffer strget swap drop - 5 + allocate if ENOMEM throw then - s" zfs:" ( N addr addr1 len ) - 2 pick swap move ( N addr ) - swap over ( addr N addr ) - 4 value_buffer - strget ( addr N addr 4 addr1 len ) - strcat ( addr N addr 4+len ) - s" :" strcat ( addr N addr 5+len ) - rot ( addr addr 5+len N ) s" bootenv_root[4]" 13 +c! setenv - free-memory + device free-memory 0 to device free_buffers -1 +loop diff --git a/usr/src/boot/sys/boot/forth/menu-commands.4th b/usr/src/boot/sys/boot/forth/menu-commands.4th index 4460ccaf59..cfcecf78b9 100644 --- a/usr/src/boot/sys/boot/forth/menu-commands.4th +++ b/usr/src/boot/sys/boot/forth/menu-commands.4th @@ -565,7 +565,6 @@ also menu-namespace also menu-command-helpers dup s" bootenv_root[E]" 13 +c! getenv s" currdev" getenv compare 0= if s" zfs_be_active" getenv type ." is already active" - 500 ms \ sleep else dup s" set currdev=${bootenv_root[E]}" 27 +c! evaluate dup s" bootenvmenu_caption[E]" 20 +c! getenv @@ -578,13 +577,29 @@ also menu-namespace also menu-command-helpers s" /boot/loader.conf" read-conf s" /boot/loader.conf.local" read-conf init_bootenv + + s" 1" s" zfs_be_currpage" setenv + s" be-set-page" evaluate then + 500 ms \ sleep so user can see the message be_draw_screen menu-redraw TRUE ; +\ +\ Chainload this entry. Normally we do not return, in case of error +\ from chain load, we continue with normal menu code. +\ + +: set_be_chain ( N -- no return | N TRUE ) + dup s" chain ${bootenv_root[E]}" 21 +c! evaluate catch drop + + menu-redraw + TRUE +; + \ \ Switch to the next page of boot environments \ -- cgit v1.2.3 From 4c004ea84c324520a1bac324e9f69d22ab4c5cd9 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Fri, 19 May 2017 03:06:10 +0300 Subject: 8303 loader: biosdisk interface should be able to cope with 4k sectors Reviewed by: Robert Mustacchi Approved by: Hans Rosenfeld --- usr/src/boot/Makefile.version | 2 +- usr/src/boot/sys/boot/i386/libi386/biosdisk.c | 349 ++++++++++++-------------- 2 files changed, 164 insertions(+), 187 deletions(-) (limited to 'usr/src') diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 8884ee547c..ce9a4e112c 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -33,4 +33,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2017.5.25.1 +BOOT_VERSION = $(LOADER_VERSION)-2017.6.10.1 diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c index c30008a734..8f936394ce 100644 --- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c +++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c @@ -93,10 +93,7 @@ static int nbdinfo = 0; #define BD(dev) (bdinfo[(dev)->d_unit]) -static int bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, - caddr_t dest); -static int bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, - caddr_t dest); +static int bd_io(struct disk_devdesc *, daddr_t, int, caddr_t, int); static int bd_int13probe(struct bdinfo *bd); static int bd_init(void); @@ -453,105 +450,144 @@ static int bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) { - struct disk_devdesc *dev = (struct disk_devdesc *)devdata; - uint64_t disk_blocks; - int blks, rc; -#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ - char fragbuf[BIOSDISK_SECSIZE]; - size_t fragsize; - - fragsize = size % BIOSDISK_SECSIZE; -#else - if (size % BD(dev).bd_sectorsize) - panic("bd_strategy: %d bytes I/O not multiple of block size", size); -#endif + struct disk_devdesc *dev = (struct disk_devdesc *)devdata; + uint64_t disk_blocks, offset; + size_t blks, blkoff, bsize, rest; + caddr_t bbuf; + int rc; - DEBUG("open_disk %p", dev); - - /* - * Check the value of the size argument. We do have quite small - * heap (64MB), but we do not know good upper limit, so we check against - * INT_MAX here. This will also protect us against possible overflows - * while translating block count to bytes. - */ - if (size > INT_MAX) { - DEBUG("too large read: %zu bytes", size); - return (EIO); - } + /* + * First make sure the IO is multiple of 512 bytes. While we do + * process partial reads below, the strategy mechanism is built + * assuming IO of multiple of 512B blocks. If the request is not + * multiple of 512B blocks, it has to be some sort of bug. + */ + if (size == 0 || (size % BIOSDISK_SECSIZE) != 0) { + printf("bd_strategy: %d bytes I/O not multiple of %d\n", + size, BIOSDISK_SECSIZE); + return (EIO); + } - blks = size / BD(dev).bd_sectorsize; - if (dblk > dblk + blks) - return (EIO); + DEBUG("open_disk %p", dev); - if (rsize) - *rsize = 0; + offset = dblk * BIOSDISK_SECSIZE; + dblk = offset / BD(dev).bd_sectorsize; + blkoff = offset % BD(dev).bd_sectorsize; - /* Get disk blocks, this value is either for whole disk or for partition */ - if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { - /* DIOCGMEDIASIZE does return bytes. */ - disk_blocks /= BD(dev).bd_sectorsize; - } else { - /* We should not get here. Just try to survive. */ - disk_blocks = BD(dev).bd_sectors - dev->d_offset; - } + /* + * Check the value of the size argument. We do have quite small + * heap (64MB), but we do not know good upper limit, so we check against + * INT_MAX here. This will also protect us against possible overflows + * while translating block count to bytes. + */ + if (size > INT_MAX) { + DEBUG("too large read: %zu bytes", size); + return (EIO); + } - /* Validate source block address. */ - if (dblk < dev->d_offset || dblk >= dev->d_offset + disk_blocks) - return (EIO); - - /* - * Truncate if we are crossing disk or partition end. - */ - if (dblk + blks >= dev->d_offset + disk_blocks) { - blks = dev->d_offset + disk_blocks - dblk; - size = blks * BD(dev).bd_sectorsize; - DEBUG("short read %d", blks); - } + blks = size / BD(dev).bd_sectorsize; + if (blks == 0 || (size % BD(dev).bd_sectorsize) != 0) + blks++; - switch (rw & F_MASK) { - case F_READ: - DEBUG("read %d from %lld to %p", blks, dblk, buf); - - if (blks && (rc = bd_read(dev, dblk, blks, buf))) { - /* Filter out floppy controller errors */ - if (BD(dev).bd_flags != BD_FLOPPY || rc != 0x20) { - printf("read %d from %lld to %p, error: 0x%x\n", blks, dblk, - buf, rc); - } - return (EIO); - } -#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ - DEBUG("bd_strategy: frag read %d from %d+%d to %p", - fragsize, dblk, blks, buf + (blks * BIOSDISK_SECSIZE)); - if (fragsize && bd_read(od, dblk + blks, 1, fragsize)) { - DEBUG("frag read error"); - return(EIO); + if (dblk > dblk + blks) + return (EIO); + + if (rsize) + *rsize = 0; + + /* + * Get disk blocks, this value is either for whole disk or for + * partition. + */ + if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { + /* DIOCGMEDIASIZE does return bytes. */ + disk_blocks /= BD(dev).bd_sectorsize; + } else { + /* We should not get here. Just try to survive. */ + disk_blocks = BD(dev).bd_sectors - dev->d_offset; } - bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize); -#endif - break; - case F_WRITE : - DEBUG("write %d from %d to %p", blks, dblk, buf); - if (blks && bd_write(dev, dblk, blks, buf)) { - DEBUG("write error"); - return (EIO); + /* Validate source block address. */ + if (dblk < dev->d_offset || dblk >= dev->d_offset + disk_blocks) + return (EIO); + + /* + * Truncate if we are crossing disk or partition end. + */ + if (dblk + blks >= dev->d_offset + disk_blocks) { + blks = dev->d_offset + disk_blocks - dblk; + size = blks * BD(dev).bd_sectorsize; + DEBUG("short read %d", blks); } -#ifdef BD_SUPPORT_FRAGS - if(fragsize) { - DEBUG("Attempted to write a frag"); - return (EIO); + + if (V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize == 0) + panic("BUG: Real mode buffer is too small\n"); + + bbuf = PTOV(V86_IO_BUFFER); + rest = size; + + while (blks > 0) { + int x = min(blks, V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize); + + switch (rw & F_MASK) { + case F_READ: + DEBUG("read %d from %lld to %p", x, dblk, buf); + bsize = BD(dev).bd_sectorsize * x - blkoff; + if (rest < bsize) + bsize = rest; + + if ((rc = bd_io(dev, dblk, x, bbuf, 0)) != 0) + return (EIO); + + bcopy(bbuf + blkoff, buf, bsize); + break; + case F_WRITE : + DEBUG("write %d from %lld to %p", x, dblk, buf); + if (blkoff != 0) { + /* + * We got offset to sector, read 1 sector to + * bbuf. + */ + x = 1; + bsize = BD(dev).bd_sectorsize - blkoff; + bsize = min(bsize, rest); + rc = bd_io(dev, dblk, x, bbuf, 0); + } else if (rest < BD(dev).bd_sectorsize) { + /* + * The remaining block is not full + * sector. Read 1 sector to bbuf. + */ + x = 1; + bsize = rest; + rc = bd_io(dev, dblk, x, bbuf, 0); + } else { + /* We can write full sector(s). */ + bsize = BD(dev).bd_sectorsize * x; + } + /* + * Put your Data In, Put your Data out, + * Put your Data In, and shake it all about + */ + bcopy(buf, bbuf + blkoff, bsize); + if ((rc = bd_io(dev, dblk, x, bbuf, 1)) != 0) + return (EIO); + + break; + default: + /* DO NOTHING */ + return (EROFS); + } + + blkoff = 0; + buf += bsize; + rest -= bsize; + blks -= x; + dblk += x; } -#endif - break; - default: - /* DO NOTHING */ - return (EROFS); - } - if (rsize) - *rsize = size; - return (0); + if (rsize != NULL) + *rsize = size; + return (0); } static int @@ -621,116 +657,57 @@ static int bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int dowrite) { - u_int x, sec, result, resid, retry, maxfer; - caddr_t p, xp, bbuf; + u_int result, retry; - /* Just in case some idiot actually tries to read/write -1 blocks... */ - if (blks < 0) - return (-1); + /* Just in case some idiot actually tries to read/write -1 blocks... */ + if (blks < 0) + return (-1); - resid = blks; - p = dest; - - /* Decide whether we have to bounce */ - if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 && - (VTOP(dest) >> 16) != (VTOP(dest + - blks * BD(dev).bd_sectorsize) >> 16))) { - - /* - * There is a 64k physical boundary somewhere in the - * destination buffer, or the destination buffer is above - * first 1MB of physical memory so we have to arrange a - * suitable bounce buffer. Allocate a buffer twice as large - * as we need to. Use the bottom half unless there is a break - * there, in which case we use the top half. - */ - x = V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize; - if (x == 0) - panic("BUG: Real mode buffer is too small\n"); - x = min(x, (unsigned)blks); - bbuf = PTOV(V86_IO_BUFFER); - maxfer = x; /* limit transfers to bounce region size */ - } else { - bbuf = NULL; - maxfer = 0; - } - - while (resid > 0) { /* - * Play it safe and don't cross track boundaries. - * (XXX this is probably unnecessary) + * Loop retrying the operation a couple of times. The BIOS + * may also retry. */ - sec = dblk % BD(dev).bd_sec; /* offset into track */ - x = min(BD(dev).bd_sec - sec, resid); - if (maxfer > 0) - x = min(x, maxfer); /* fit bounce buffer */ + for (retry = 0; retry < 3; retry++) { + /* if retrying, reset the drive */ + if (retry > 0) { + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0; + v86.edx = BD(dev).bd_unit; + v86int(); + } - /* where do we transfer to? */ - xp = bbuf == NULL ? p : bbuf; + if (BD(dev).bd_flags & BD_MODEEDD1) + result = bd_edd_io(dev, dblk, blks, dest, dowrite); + else + result = bd_chs_io(dev, dblk, blks, dest, dowrite); - /* - * Put your Data In, Put your Data out, - * Put your Data In, and shake it all about - */ - if (dowrite && bbuf != NULL) - bcopy(p, bbuf, x * BD(dev).bd_sectorsize); + if (result == 0) + break; + } /* - * Loop retrying the operation a couple of times. The BIOS - * may also retry. + * 0x20 - Controller failure. This is common error when the + * media is not present. */ - for (retry = 0; retry < 3; retry++) { - /* if retrying, reset the drive */ - if (retry > 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0; - v86.edx = BD(dev).bd_unit; - v86int(); - } - - if (BD(dev).bd_flags & BD_MODEEDD1) - result = bd_edd_io(dev, dblk, x, xp, dowrite); - else - result = bd_chs_io(dev, dblk, x, xp, dowrite); - if (result == 0) - break; + if (result != 0 && result != 0x20) { + if (dowrite != 0) { + printf("%s%d: Write %d sector(s) from %p (0x%x) " + "to %lld: 0x%x", dev->d_dev->dv_name, dev->d_unit, + blks, dest, VTOP(dest), dblk, result); + } else { + printf("%s%d: Read %d sector(s) from %lld to %p " + "(0x%x): 0x%x", dev->d_dev->dv_name, dev->d_unit, + blks, dblk, dest, VTOP(dest), result); } - if (dowrite) - DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x, - p, VTOP(p), dblk, result ? "failed" : "ok"); - else - DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x, - dblk, p, VTOP(p), result ? "failed" : "ok"); - if (result) { - return(result); - } - if (!dowrite && bbuf != NULL) - bcopy(bbuf, p, x * BD(dev).bd_sectorsize); - p += (x * BD(dev).bd_sectorsize); - dblk += x; - resid -= x; + if (result != 0) + return (result); } -/* hexdump(dest, (blks * BD(dev).bd_sectorsize)); */ return(0); } -static int -bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) -{ - - return (bd_io(dev, dblk, blks, dest, 0)); -} - -static int -bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) -{ - - return (bd_io(dev, dblk, blks, dest, 1)); -} - /* * Return the BIOS geometry of a given "fixed drive" in a format * suitable for the legacy bootinfo structure. Since the kernel is -- cgit v1.2.3 From bcb81701c49bee8a728b9a14ac9b6675854a7f25 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 16 Feb 2017 08:45:33 +0200 Subject: 8296 tcopy: misleading-indentation Reviewed by: Robert Mustacchi Reviewed by: Igor Kozhukhov Reviewed by: Gordon Ross Reviewed by: Yuri Pankov Approved by: Hans Rosenfeld --- usr/src/cmd/tcopy/tcopy.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'usr/src') diff --git a/usr/src/cmd/tcopy/tcopy.c b/usr/src/cmd/tcopy/tcopy.c index 6fa3e50f3e..5dbf401cfd 100644 --- a/usr/src/cmd/tcopy/tcopy.c +++ b/usr/src/cmd/tcopy/tcopy.c @@ -37,8 +37,6 @@ * contributors. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -63,8 +61,7 @@ size_t size_256K = 256 * 1024; int -main(argc, argv) -char **argv; +main(int argc, char **argv) { int n, nw, inp, outp; struct mtop op; @@ -157,8 +154,8 @@ char **argv; else (void) printf("file %d: record %ld:" " size %d\n", filen, lcount, ln); - (void) printf("file %d: eof after %ld records:" - " %lld bytes\n", filen, count-1, size); + (void) printf("file %d: eof after %ld records:" + " %lld bytes\n", filen, count-1, size); if (copy) { op.mt_op = MTWEOF; op.mt_count = (daddr_t)1; @@ -184,7 +181,7 @@ char **argv; } void -RUBOUT() +RUBOUT(void) { if (count > lcount) --count; -- cgit v1.2.3 From 8487916bce68d458d3da4cba7d0be961dfce786f Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 16 Feb 2017 08:33:27 +0200 Subject: 8316 srchtxt: misleading-indentation Reviewed by: Robert Mustacchi Reviewed by: Gordon Ross Approved by: Hans Rosenfeld --- usr/src/cmd/srchtxt/srchtxt.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'usr/src') diff --git a/usr/src/cmd/srchtxt/srchtxt.c b/usr/src/cmd/srchtxt/srchtxt.c index 30d64f3484..5c1e193a82 100644 --- a/usr/src/cmd/srchtxt/srchtxt.c +++ b/usr/src/cmd/srchtxt/srchtxt.c @@ -27,8 +27,6 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -270,14 +268,12 @@ char *regexpr; num_msgs = *(int *)addr; for (msgnum = 1; msgnum <= num_msgs; msgnum++) { msg = (char *)(*(int *)(addr + sizeof (int) * msgnum) + addr); - if (textflg) - if (step(msg, regexpr)) { + if (textflg) { + if (step(msg, regexpr)) prnt_str(msg); - continue; - } - else - continue; - prnt_str(msg); + continue; + } + prnt_str(msg); } } -- cgit v1.2.3 From 311c88c1ed31408e0998a9aabb8e7d0d12ef83ad Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 16 Feb 2017 02:21:21 +0200 Subject: 8326 logger: misleading-indentation Reviewed by: Robert Mustacchi Reviewed by: Gordon Ross Approved by: Hans Rosenfeld --- usr/src/cmd/logger/logger.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'usr/src') diff --git a/usr/src/cmd/logger/logger.c b/usr/src/cmd/logger/logger.c index 35e3b322cb..d54609102b 100644 --- a/usr/src/cmd/logger/logger.c +++ b/usr/src/cmd/logger/logger.c @@ -103,7 +103,7 @@ static struct code FacNames[] = { NULL, -1 }; -static int pencode(register char *); +static int pencode(char *); static int decode(char *, struct code *); static void bailout(char *, char *); static void usage(void); @@ -174,8 +174,8 @@ main(int argc, char **argv) usage(); } - argc -= optind; - argv = &argv[optind]; + argc -= optind; + argv = &argv[optind]; if ((tag == NULL) && ((tag = getlogin()) == NULL)) { u = getuid(); @@ -307,14 +307,14 @@ main(int argc, char **argv) static int -pencode(s) -register char *s; +pencode(char *s) { - register char *p; + char *p; int lev; int fac = 0; - for (p = s; *s && *s != '.'; s++); + for (p = s; *s && *s != '.'; s++) + ; if (*s) { *s = '\0'; fac = decode(p, FacNames); @@ -332,11 +332,9 @@ register char *s; static int -decode(name, codetab) -char *name; -struct code *codetab; +decode(char *name, struct code *codetab) { - register struct code *c; + struct code *c; if (isdigit(*name)) return (atoi(name)); @@ -350,8 +348,7 @@ struct code *codetab; static void -bailout(a, b) -char *a, *b; +bailout(char *a, char *b) { (void) fprintf(stderr, gettext("logger: %s%s\n"), a, b); exit(1); -- cgit v1.2.3 From 2e10def11ef1a50c25efa2444482670e6b0654ff Mon Sep 17 00:00:00 2001 From: Peter Tribble Date: Sat, 27 May 2017 11:10:43 +0100 Subject: 8302 svr4pkg unused variables Reviewed by: Yuri Pankov Reviewed by: Gordon Ross Approved by: Dan McDonald --- usr/src/cmd/svr4pkg/Makefile.svr4pkg | 5 +- usr/src/cmd/svr4pkg/libinst/Makefile | 3 +- usr/src/cmd/svr4pkg/libinst/ocfile.c | 19 +- usr/src/cmd/svr4pkg/libinst/stub.c | 46 ---- usr/src/cmd/svr4pkg/pkgadd/main.c | 362 ++++++++++++++--------------- usr/src/cmd/svr4pkg/pkgadm/lock.c | 2 - usr/src/cmd/svr4pkg/pkgadm/main.c | 2 +- usr/src/cmd/svr4pkg/pkgcond/main.c | 223 +++++++++--------- usr/src/cmd/svr4pkg/pkginfo/pkginfo.c | 41 ++-- usr/src/cmd/svr4pkg/pkginstall/dockspace.c | 10 +- usr/src/cmd/svr4pkg/pkgremove/check.c | 5 +- usr/src/cmd/svr4pkg/pkgtrans/main.c | 4 +- 12 files changed, 342 insertions(+), 380 deletions(-) delete mode 100644 usr/src/cmd/svr4pkg/libinst/stub.c (limited to 'usr/src') diff --git a/usr/src/cmd/svr4pkg/Makefile.svr4pkg b/usr/src/cmd/svr4pkg/Makefile.svr4pkg index 89c4854e39..fc343556fc 100644 --- a/usr/src/cmd/svr4pkg/Makefile.svr4pkg +++ b/usr/src/cmd/svr4pkg/Makefile.svr4pkg @@ -20,6 +20,7 @@ # # +# Copyright (c) 2017 Peter Tribble. # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -33,12 +34,8 @@ CPPFLAGS += -I$(SRC)/cmd/svr4pkg/hdrs \ -D_FILE_OFFSET_BITS=64 -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-implicit-function-declaration -CERRWARN += -_gcc=-Wno-extra CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-char-subscripts CERRWARN += -_gcc=-Wno-address LIBINST = $(SRC)/cmd/svr4pkg/libinst/libinst.a diff --git a/usr/src/cmd/svr4pkg/libinst/Makefile b/usr/src/cmd/svr4pkg/libinst/Makefile index 89823b854d..3da766690a 100644 --- a/usr/src/cmd/svr4pkg/libinst/Makefile +++ b/usr/src/cmd/svr4pkg/libinst/Makefile @@ -20,6 +20,7 @@ # # +# Copyright (c) 2017 Peter Tribble. # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -32,7 +33,7 @@ OBJS= copyf.o dockdeps.o echo.o eptstat.o \ ocfile.o pathdup.o pkgdbmerg.o procmap.o \ pkgobjmap.o ptext.o putparam.o \ qreason.o qstrdup.o setadmin.o setlist.o \ - srcpath.o scriptvfy.o stub.o doulimit.o \ + srcpath.o scriptvfy.o doulimit.o \ dryrun.o listmgr.o is_local_host.o cvtpath.o \ depchk.o pkgops.o sml.o log.o \ setup_temporary_directory.o open_package_datastream.o \ diff --git a/usr/src/cmd/svr4pkg/libinst/ocfile.c b/usr/src/cmd/svr4pkg/libinst/ocfile.c index 0cbc95516c..938151d39c 100644 --- a/usr/src/cmd/svr4pkg/libinst/ocfile.c +++ b/usr/src/cmd/svr4pkg/libinst/ocfile.c @@ -19,6 +19,10 @@ * CDDL HEADER END */ +/* + * Copyright (c) 2017 Peter Tribble. + */ + /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -206,7 +210,6 @@ ocfile(PKGserver *server, VFP_T **r_tmpvfp, fsblkcnt_t map_blks) VFP_T *tmpvfp = (VFP_T *)NULL; char contents[PATH_MAX]; char logfile[PATH_MAX]; - int n; off_t cdiff_alloc; PKGserver newserver; @@ -371,7 +374,6 @@ ocfile(PKGserver *server, VFP_T **r_tmpvfp, fsblkcnt_t map_blks) int socfile(PKGserver *server, boolean_t quiet) { - char contents[PATH_MAX]; boolean_t readonly = B_FALSE; PKGserver newserver; @@ -513,8 +515,6 @@ swapcfile(PKGserver server, VFP_T **a_cfTmpVfp, char *pkginst, int dbchg) /* commit temporary contents file bytes to storage */ if (pkgservercommitfile(*a_cfTmpVfp, server) != 0) { - int lerrno = errno; - logerr(gettext(ERR_COMMIT)); vfpClose(a_cfTmpVfp); pkgcloseserver(server); @@ -548,14 +548,15 @@ relslock(void) * or not the function displays the error message upon failure. */ int -pkgWlock(int verbose) { +pkgWlock(int verbose) +{ int retry_cnt, retval; char lockpath[PATH_MAX]; active_lock = 0; (void) snprintf(lockpath, sizeof (lockpath), - "%s/%s", pkgadm_dir, LOCKFILE); + "%s/%s", pkgadm_dir, LOCKFILE); retry_cnt = LOCKRETRY; @@ -610,8 +611,7 @@ pkgWlock(int verbose) { (void) signal(SIGALRM, SIG_IGN); - if (retval == 0) - { + if (retval == 0) { if (retry_cnt == -1) { logerr(gettext(ERR_TMOUT)); } @@ -627,7 +627,8 @@ pkgWlock(int verbose) { * failure. */ static int -pkgWunlock(void) { +pkgWunlock(void) +{ if (active_lock) { active_lock = 0; if (close(lock_fd)) diff --git a/usr/src/cmd/svr4pkg/libinst/stub.c b/usr/src/cmd/svr4pkg/libinst/stub.c deleted file mode 100644 index 1deca146eb..0000000000 --- a/usr/src/cmd/svr4pkg/libinst/stub.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 1993 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - - -#ifdef PRESVR4 -int -rename(char *x, char *y) -{ - return (link(x, y) || unlink(x)); -} -#else -static int dummy; /* used to make compillor warning go away */ -#ifdef lint -_______a() -{ - return (dummy++); -} -#endif /* lint */ -#endif diff --git a/usr/src/cmd/svr4pkg/pkgadd/main.c b/usr/src/cmd/svr4pkg/pkgadd/main.c index 1e201f4b5a..c2f0125d55 100644 --- a/usr/src/cmd/svr4pkg/pkgadd/main.c +++ b/usr/src/cmd/svr4pkg/pkgadd/main.c @@ -349,7 +349,7 @@ main(int argc, char **argv) */ while ((c = getopt(argc, argv, - "?Aa:b:B:Cc:D:d:GhIMnO:R:r:Ss:tV:vY:zZ")) != EOF) { + "?Aa:b:B:Cc:D:d:GhIMnO:R:r:Ss:tV:vY:zZ")) != EOF) { switch (c) { /* @@ -529,7 +529,7 @@ main(int argc, char **argv) case 'O': for (p = strtok(optarg, ","); p != (char *)NULL; - p = strtok(NULL, ",")) { + p = strtok(NULL, ",")) { if (strcmp(p, "debug") == 0) { /* set debug flag/enable debug output */ @@ -545,7 +545,7 @@ main(int argc, char **argv) } if (strcmp(p, - "enable-hollow-package-support") == 0) { + "enable-hollow-package-support") == 0) { set_depend_pkginfo_DB(B_TRUE); continue; } @@ -768,7 +768,7 @@ main(int argc, char **argv) echoDebug(DBG_ENTRY_IN_GZ, prog_full_name); } else { echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(), - z_get_zonename()); + z_get_zonename()); } /* @@ -905,8 +905,8 @@ main(int argc, char **argv) set_PKGpaths(get_inst_root()); echoDebug(DBG_PKGADD_PKGPATHS, - get_PKGLOC() ? get_PKGLOC() : "", - get_PKGADM() ? get_PKGADM() : ""); + get_PKGLOC() ? get_PKGLOC() : "", + get_PKGADM() ? get_PKGADM() : ""); /* * This function is in the libinst library; it reads the specified @@ -927,7 +927,7 @@ main(int argc, char **argv) if (is_depend_pkginfo_DB()) { echoDebug(DBG_PKGADD_HOLLOW_ENABLED); } else if ((z_running_in_global_zone() == B_TRUE) && - (z_non_global_zones_exist() == B_TRUE)) { + (z_non_global_zones_exist() == B_TRUE)) { echoDebug(DBG_PKGADD_ENABLING_HOLLOW); set_depend_pkginfo_DB(B_TRUE); } @@ -956,7 +956,7 @@ main(int argc, char **argv) if (respfile) { echoDebug(DBG_PKGADD_RESPFILE, - respfile, respdir ? respdir : ""); + respfile, respdir ? respdir : ""); if (respfile[0] != '/') { progerr(ERR_RSP_FILE_NOTFULLPATH, respfile); @@ -1045,8 +1045,8 @@ main(int argc, char **argv) echoDebug(DBG_INSTALLING_TO_SPOOL, spoolDir); b = open_package_datastream(argc, argv, spoolDir, device, - &repeat, &ids_name, tmpdir, - &pkgdev, optind); + &repeat, &ids_name, tmpdir, + &pkgdev, optind); quitSetIdsName(ids_name); @@ -1090,8 +1090,8 @@ main(int argc, char **argv) */ b = open_package_datastream(argc, argv, spoolDir, device, - &repeat, &ids_name, tmpdir, - &pkgdev, optind); + &repeat, &ids_name, tmpdir, + &pkgdev, optind); quitSetIdsName(ids_name); @@ -1105,11 +1105,9 @@ main(int argc, char **argv) */ b = get_package_list(&pkglist, argv, catg_arg, category, - ids_name, &repeat); + ids_name, &repeat); if (b == B_FALSE) { - char path[PATH_MAX]; - echoDebug(DBG_CANNOT_GET_PKGLIST); progerr(ERR_NOPKGS, pkgdev.dirname); @@ -1141,7 +1139,7 @@ main(int argc, char **argv) */ if ((askflag != 0) && (respdir == (char *)NULL) && - (npkgs > 1)) { + (npkgs > 1)) { progerr(ERR_TOO_MANY_PKGS); quit(1); /* NOTREACHED */ @@ -1152,7 +1150,7 @@ main(int argc, char **argv) */ b = add_packages(pkglist, ids_name, repeat, - altBinDir, device, noZones); + altBinDir, device, noZones); /* * close open input data stream (source package) if left open. @@ -1160,7 +1158,7 @@ main(int argc, char **argv) if (ids_name) { echoDebug(DBG_CLOSING_STREAM, ids_name, - PSTR(pkgdev.dirname)); + PSTR(pkgdev.dirname)); (void) ds_close(1); rrmdir(pkgdev.dirname); ids_name = NULL; @@ -1229,8 +1227,8 @@ main(int argc, char **argv) static int pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, - char *a_idsName, char *a_altBinDir, char *a_adminFile, - char *a_stdoutPath, boolean_t a_tmpzn) + char *a_idsName, char *a_altBinDir, char *a_adminFile, + char *a_stdoutPath, boolean_t a_tmpzn) { char *arg[MAXARGS]; char *p; @@ -1251,14 +1249,14 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, echoDebug(DBG_PKGZONECHECKINSTALL_ENTRY); echoDebug(DBG_PKGZONECHECKINSTALL_ARGS, a_zoneName, PSTR(pkginst), - PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), - a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/", - PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath)); + PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), + a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/", + PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath)); /* generate full path to 'phatinstall' to run in zone */ (void) snprintf(path, sizeof (path), "%s/pkginstall", - "/usr/sadm/install/bin"); + "/usr/sadm/install/bin"); /* start at first file descriptor */ @@ -1371,11 +1369,11 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, fd = openLocal(a_adminFile, O_RDONLY, tmpdir); if (fd < 0) { progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile, - errno, strerror(errno)); + errno, strerror(errno)); return (1); } (void) snprintf(adminfd_path, sizeof (adminfd_path), - "/proc/self/fd/%d", fd); + "/proc/self/fd/%d", fd); fds[maxfds++] = fd; arg[nargs++] = "-a"; arg[nargs++] = adminfd_path; @@ -1411,7 +1409,7 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, if ((p != NULL) && (*p != '\0')) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-name=%s", p); + "parent-zone-name=%s", p); arg[nargs++] = "-O"; arg[nargs++] = strdup(zn); } @@ -1422,14 +1420,14 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, if (z_running_in_global_zone() == B_TRUE) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_GLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_GLOBAL_ZONE); arg[nargs++] = strdup(zn); } else { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_NONGLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_NONGLOBAL_ZONE); arg[nargs++] = strdup(zn); } @@ -1444,11 +1442,11 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, fd = openLocal(a_idsName, O_RDONLY, tmpdir); if (fd < 0) { progerr(ERR_STREAM_UNAVAILABLE, a_idsName, - pkginst, strerror(errno)); + pkginst, strerror(errno)); quit(1); } (void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path), - "/proc/self/fd/%d", fd); + "/proc/self/fd/%d", fd); fds[maxfds++] = fd; arg[nargs++] = pkgstreamfd_path; } else { @@ -1484,7 +1482,7 @@ pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState, n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds); echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n, - PSTR(a_stdoutPath)); + PSTR(a_stdoutPath)); /* * close any files that were opened for use by the @@ -1560,9 +1558,9 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, echoDebug(DBG_PKGZONEINSTALL_ENTRY); echoDebug(DBG_PKGZONEINSTALL_ARGS, a_zoneName, PSTR(pkginst), - PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), - a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName), - a_adminFile); + PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), + a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName), + a_adminFile); /* generate path to pkginstall */ @@ -1684,11 +1682,11 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, fd = openLocal(a_adminFile, O_RDONLY, tmpdir); if (fd < 0) { progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile, - errno, strerror(errno)); + errno, strerror(errno)); return (1); } (void) snprintf(adminfd_path, sizeof (adminfd_path), - "/proc/self/fd/%d", fd); + "/proc/self/fd/%d", fd); fds[maxfds++] = fd; arg[nargs++] = "-a"; arg[nargs++] = adminfd_path; @@ -1725,12 +1723,12 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, fd = openLocal(respfile, O_RDONLY, tmpdir); if (fd < 0) { progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile, - errno, strerror(errno)); + errno, strerror(errno)); return (1); } (void) snprintf(respfilefd_path, - sizeof (respfilefd_path), - "/proc/self/fd/%d", fd); + sizeof (respfilefd_path), + "/proc/self/fd/%d", fd); fds[maxfds++] = fd; arg[nargs++] = "-r"; arg[nargs++] = respfilefd_path; @@ -1749,7 +1747,7 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, if ((p != NULL) && (*p != '\0')) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-name=%s", p); + "parent-zone-name=%s", p); arg[nargs++] = "-O"; arg[nargs++] = strdup(zn); } @@ -1760,14 +1758,14 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, if (z_running_in_global_zone() == B_TRUE) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_GLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_GLOBAL_ZONE); arg[nargs++] = strdup(zn); } else { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_NONGLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_NONGLOBAL_ZONE); arg[nargs++] = strdup(zn); } @@ -1782,11 +1780,11 @@ pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName, fd = openLocal(a_idsName, O_RDONLY, tmpdir); if (fd < 0) { progerr(ERR_STREAM_UNAVAILABLE, a_idsName, - pkginst, strerror(errno)); + pkginst, strerror(errno)); quit(1); } (void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path), - "/proc/self/fd/%d", fd); + "/proc/self/fd/%d", fd); fds[maxfds++] = fd; arg[nargs++] = pkgstreamfd_path; } else { @@ -1882,13 +1880,13 @@ pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir) echoDebug(DBG_PKGINSTALL_ENTRY); echoDebug(DBG_PKGINSTALL_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname), - PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot), - PSTR(a_idsName), PSTR(a_pkgDir)); + PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot), + PSTR(a_idsName), PSTR(a_pkgDir)); /* generate full path to 'pkginstall' to run in zone */ (void) snprintf(path, sizeof (path), "%s/pkginstall", - a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir); + a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir); /* * generate argument list for call to pkginstall */ @@ -2117,7 +2115,7 @@ pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir) if ((p != NULL) && (*p != '\0')) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-name=%s", p); + "parent-zone-name=%s", p); arg[nargs++] = "-O"; arg[nargs++] = strdup(zn); } @@ -2128,14 +2126,14 @@ pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir) if (z_running_in_global_zone() == B_TRUE) { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_GLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_GLOBAL_ZONE); arg[nargs++] = strdup(zn); } else { char zn[MAXPATHLEN]; (void) snprintf(zn, sizeof (zn), - "parent-zone-type=%s", - TAG_VALUE_NONGLOBAL_ZONE); + "parent-zone-type=%s", + TAG_VALUE_NONGLOBAL_ZONE); arg[nargs++] = strdup(zn); } @@ -2211,51 +2209,51 @@ ckreturn(int retcode) needconsult = 0; switch (retcode) { - case 0: /* successful */ - case 10: - case 20: + case 0: /* successful */ + case 10: + case 20: break; /* empty case */ - case 1: /* package operation failed (fatal error) */ - case 11: - case 21: + case 1: /* package operation failed (fatal error) */ + case 11: + case 21: failflag++; interrupted++; needconsult++; break; - case 2: /* non-fatal error (warning) */ - case 12: - case 22: + case 2: /* non-fatal error (warning) */ + case 12: + case 22: warnflag++; interrupted++; needconsult++; break; - case 3: /* user selected quit; operation interrupted */ - case 13: - case 23: + case 3: /* user selected quit; operation interrupted */ + case 13: + case 23: intrflag++; interrupted++; needconsult++; break; - case 4: /* admin settings prevented operation */ - case 14: - case 24: + case 4: /* admin settings prevented operation */ + case 14: + case 24: admnflag++; interrupted++; break; - case 5: /* administration: interaction req (no -n) */ - case 15: - case 25: + case 5: /* administration: interaction req (no -n) */ + case 15: + case 25: nullflag++; interrupted++; needconsult++; break; - default: + default: failflag++; interrupted++; needconsult++; @@ -2278,10 +2276,10 @@ usage(void) (void) fprintf(stderr, ERR_USAGE_PKGASK, prog); } else if (z_running_in_global_zone() == B_FALSE) { (void) fprintf(stderr, ERR_USAGE_PKGADD_NONGLOBALZONE, - prog, prog); + prog, prog); } else { (void) fprintf(stderr, ERR_USAGE_PKGADD_GLOBALZONE, - prog, prog); + prog, prog); } } @@ -2313,7 +2311,7 @@ usage(void) static boolean_t check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, - CAF_T a_flags) + CAF_T a_flags) { FILE *pkginfoFP; FILE *pkgmapFP; @@ -2356,7 +2354,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, /* path to package to be installed top level (main) directory */ len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir, - a_pkgInst); + a_pkgInst); if (len > sizeof (pkgpath)) { progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst); return (B_FALSE); @@ -2372,7 +2370,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, /* path to pkginfo file within the package to be installed */ len = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/pkginfo", - pkgpath); + pkgpath); if (len > sizeof (pkginfoPath)) { progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo"); return (B_FALSE); @@ -2381,7 +2379,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, /* path to highest instance of package currently installed */ pkgLocateHighestInst(instPkgPath, sizeof (instPkgPath), - instPkg, sizeof (instPkg), a_rootPath, a_pkgInst); + instPkg, sizeof (instPkg), a_rootPath, a_pkgInst); /* * gather information from this package's pkginfo file @@ -2391,24 +2389,24 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, if (pkginfoFP == (FILE *)NULL) { progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath, - strerror(errno)); + strerror(errno)); return (B_FALSE); } /* determine "HOLLOW" setting for this package */ is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE, - "true", B_FALSE); + "true", B_FALSE); /* determine "ALLZONES" setting for this package */ all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE, - "true", B_FALSE); + "true", B_FALSE); /* determine "THISZONE" setting for this package */ this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE, - "true", B_FALSE); + "true", B_FALSE); /* close pkginfo file */ @@ -2469,10 +2467,10 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, */ if ((!this_zone) && (instPkgPath[0] != '\0') && - (isfile(instPkgPath, REQUEST_FILE) == 0)) { + (isfile(instPkgPath, REQUEST_FILE) == 0)) { if (a_flags & CAF_IN_GLOBAL_ZONE) { echoDebug(DBG_CHECKAPP_THISZONE_INSTREQ, - a_pkgInst, instPkg); + a_pkgInst, instPkg); } this_zone = B_TRUE; } @@ -2487,7 +2485,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, /* determine if this package is currently installed */ pkg_installed = pkginfoIsPkgInstalled((struct pkginfo **)NULL, - a_pkgInst); + a_pkgInst); /* * verify package applicability based on information gathered, @@ -2527,7 +2525,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, if (all_zones && this_zone) { progerr(ERR_ALLZONES_AND_THISZONE, a_pkgInst, - PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE); + PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE); return (B_FALSE); } @@ -2535,7 +2533,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, if ((!all_zones) && is_hollow) { progerr(ERR_NOW_ALLZONES_AND_HOLLOW, a_pkgInst, - PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE); + PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE); return (B_FALSE); } @@ -2558,7 +2556,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, if (in_gz_only && (!pkg_installed)) { /* MAKE A WARNING */ echo(ERR_IN_GZ_AND_NOT_INSTALLED, a_pkgInst, - pkgGetGzOnlyPath()); + pkgGetGzOnlyPath()); } /* pkg ALLZONES=true & pkg "in gz only" & pkg "is installed" */ @@ -2593,7 +2591,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, if (this_zone && (a_flags & CAF_SCOPE_NONGLOBAL)) { progerr(ERR_THISZONE_AND_Z_USED, PKG_THISZONE_VARIABLE, - a_pkgInst); + a_pkgInst); return (B_FALSE); } @@ -2643,7 +2641,7 @@ check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath, static void create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir, - char *a_admnfile) + char *a_admnfile) { boolean_t b; @@ -2669,7 +2667,7 @@ create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir, b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile); if (b == B_FALSE) { progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile, - strerror(errno)); + strerror(errno)); quit(1); /* NOTREACHED */ } @@ -2857,10 +2855,10 @@ unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir) if (a_idsName != (char *)NULL) { /* create stream out of package if not already one */ if (unpack_package_from_stream(a_idsName, pkginst, - a_packageDir) == B_FALSE) { + a_packageDir) == B_FALSE) { progerr(ERR_CANNOT_UNPACK_PKGSTRM, - PSTR(pkginst), PSTR(a_idsName), - PSTR(a_packageDir)); + PSTR(pkginst), PSTR(a_idsName), + PSTR(a_packageDir)); npkgs = savenpkgs; return (B_FALSE); @@ -2871,7 +2869,7 @@ unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir) /* check package applicability */ if (check_applicability(a_packageDir, - pkginst, get_inst_root(), flags) == B_FALSE) { + pkginst, get_inst_root(), flags) == B_FALSE) { progerr(ERR_PKG_NOT_INSTALLABLE, pkginst); npkgs = savenpkgs; return (B_FALSE); @@ -2892,7 +2890,7 @@ unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir) static boolean_t get_package_list(char ***r_pkgList, char **a_argv, char *a_categories, - char **a_categoryList, char *a_idsName, int *r_repeat) + char **a_categoryList, char *a_idsName, int *r_repeat) { int n; @@ -2904,19 +2902,19 @@ get_package_list(char ***r_pkgList, char **a_argv, char *a_categories, echoDebug(DBG_GETPKGLIST_ENTRY); echoDebug(DBG_GETPKGLIST_ARGS, PSTR(a_idsName), PSTR(pkgdev.dirname), - *r_repeat); + *r_repeat); /* * get the list of the packages to add */ n = pkgGetPackageList(r_pkgList, a_argv, optind, a_categories, - a_categoryList, &pkgdev); + a_categoryList, &pkgdev); switch (n) { case -1: /* no packages found */ echoDebug(DBG_PKGLIST_NONFOUND, PSTR(a_idsName), - pkgdev.dirname); + pkgdev.dirname); return (B_FALSE); case 0: /* packages found */ @@ -2924,7 +2922,7 @@ get_package_list(char ***r_pkgList, char **a_argv, char *a_categories, default: /* "quit" error */ echoDebug(DBG_PKGLIST_ERROR, PSTR(a_idsName), - pkgdev.dirname, n); + pkgdev.dirname, n); quit(n); /* NOTREACHED */ } @@ -2972,8 +2970,8 @@ get_package_list(char ***r_pkgList, char **a_argv, char *a_categories, static void install_in_one_zone(char *a_zoneName, char *a_idsName, - char *a_zoneAdminFile, char *a_zoneTempDir, - char *a_altBinDir, zone_state_t a_zoneState, boolean_t a_tmpzn) + char *a_zoneAdminFile, char *a_zoneTempDir, + char *a_altBinDir, zone_state_t a_zoneState, boolean_t a_tmpzn) { char zoneStreamName[PATH_MAX] = {'\0'}; int n; @@ -2987,8 +2985,8 @@ install_in_one_zone(char *a_zoneName, char *a_idsName, echoDebug(DBG_INSTINONEZONE_ENTRY); echoDebug(DBG_INSTINONEZONE_ARGS, a_zoneName, PSTR(a_idsName), - PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir), - PSTR(a_altBinDir)); + PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir), + PSTR(a_altBinDir)); /* echo operation to perform to stdout */ @@ -2999,11 +2997,11 @@ install_in_one_zone(char *a_zoneName, char *a_idsName, if (a_idsName == (char *)NULL) { /* locate temp stream created earlier */ (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s/%s.dstream", a_zoneTempDir, pkginst); + "%s/%s.dstream", a_zoneTempDir, pkginst); } else { /* use stream passed in on command line */ (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s", a_idsName); + "%s", a_idsName); } echoDebug(DBG_INSTALL_IN_ZONE, pkginst, a_zoneName, zoneStreamName); @@ -3018,8 +3016,8 @@ install_in_one_zone(char *a_zoneName, char *a_idsName, /* exit debugging info */ echoDebug(DBG_INSTALL_FLAG_VALUES, "after install", admnflag, doreboot, - failflag, interrupted, intrflag, ireboot, needconsult, - nullflag, warnflag); + failflag, interrupted, intrflag, ireboot, needconsult, + nullflag, warnflag); } /* @@ -3046,7 +3044,7 @@ install_in_one_zone(char *a_zoneName, char *a_idsName, static int install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, - char *a_zoneAdminFile, char *a_zoneTempDir) + char *a_zoneAdminFile, char *a_zoneTempDir) { char *zoneName; int zoneIndex; @@ -3061,13 +3059,13 @@ install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, echoDebug(DBG_INSTALLINZONES_ENTRY); echoDebug(DBG_INSTALLINZONES_ARGS, PSTR(a_idsName), - PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); + PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); /* process each zone in the list */ for (zoneIndex = 0; - (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; - zoneIndex++) { + (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; + zoneIndex++) { /* skip the zone if it is NOT running */ @@ -3113,7 +3111,7 @@ install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, static int boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, - char *a_zoneAdminFile, char *a_zoneTempDir) + char *a_zoneAdminFile, char *a_zoneTempDir) { boolean_t b; char *zoneName; @@ -3129,13 +3127,13 @@ boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, echoDebug(DBG_BOOTINSTALLINZONES_ENTRY); echoDebug(DBG_BOOTINSTALLINZONES_ARGS, PSTR(a_idsName), - PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); + PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); /* process each zone in the list */ for (zoneIndex = 0; - (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; - zoneIndex++) { + (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; + zoneIndex++) { /* skip the zone if it IS running */ @@ -3159,7 +3157,7 @@ boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, echoDebug(DBG_BOOTING_ZONE, zoneName); b = z_zlist_change_zone_state(a_zlst, zoneIndex, - ZONE_STATE_MOUNTED); + ZONE_STATE_MOUNTED); if (b == B_FALSE) { progerr(ERR_CANNOT_BOOT_ZONE, zoneName); /* set fatal error return condition */ @@ -3219,9 +3217,9 @@ boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, static void pkginstall_check_in_one_zone(char *a_zoneName, - char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir, - char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState, - boolean_t a_tmpzn) + char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir, + char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState, + boolean_t a_tmpzn) { char preinstallcheckPath[PATH_MAX+1]; char zoneStreamName[PATH_MAX] = {'\0'}; @@ -3231,20 +3229,20 @@ pkginstall_check_in_one_zone(char *a_zoneName, echoDebug(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName); (void) snprintf(preinstallcheckPath, sizeof (preinstallcheckPath), - "%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst, - a_zoneName); + "%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst, + a_zoneName); if (a_idsName == (char *)NULL) { /* locate temporary stream created earlier */ (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s/%s.dstream", a_zoneTempDir, pkginst); + "%s/%s.dstream", a_zoneTempDir, pkginst); } else { (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s", a_idsName); + "%s", a_idsName); } echoDebug(DBG_CHECKINSTALL_IN_ZONE, pkginst, a_zoneName, - zoneStreamName); + zoneStreamName); n = pkgZoneCheckInstall(a_scratchName, a_zoneState, zoneStreamName, a_altBinDir, a_zoneAdminFile, preinstallcheckPath, a_tmpzn); @@ -3254,8 +3252,8 @@ pkginstall_check_in_one_zone(char *a_zoneName, ckreturn(n); echoDebug(DBG_INSTALL_FLAG_VALUES, "after preinstall check", - admnflag, doreboot, failflag, interrupted, intrflag, - ireboot, needconsult, nullflag, warnflag); + admnflag, doreboot, failflag, interrupted, intrflag, + ireboot, needconsult, nullflag, warnflag); } /* @@ -3283,7 +3281,7 @@ pkginstall_check_in_one_zone(char *a_zoneName, static int pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, - char *a_zoneAdminFile, char *a_zoneTempDir) + char *a_zoneAdminFile, char *a_zoneTempDir) { char *zoneName; int zoneIndex; @@ -3291,8 +3289,8 @@ pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, zone_state_t zst; for (zoneIndex = 0; - (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; - zoneIndex++) { + (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; + zoneIndex++) { zst = z_zlist_get_current_state(a_zlst, zoneIndex); if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) { @@ -3335,7 +3333,7 @@ pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir, static int boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, - char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir) + char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir) { int zoneIndex; int zonesSkipped = 0; @@ -3351,13 +3349,13 @@ boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, echoDebug(DBG_BOOTCHECKINSTALLINZONES_ENTRY); echoDebug(DBG_BOOTCHECKINSTALLINZONES_ARGS, PSTR(a_idsName), - PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); + PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir)); /* process each zone in the list */ for (zoneIndex = 0; - (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; - zoneIndex++) { + (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL; + zoneIndex++) { /* skip the zone if it IS running */ @@ -3419,8 +3417,8 @@ boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, static boolean_t add_packages_in_global_with_zones(char **a_pkgList, - char *a_idsName, int a_repeat, char *a_altBinDir, - char *a_device, zoneList_t a_zlst) + char *a_idsName, int a_repeat, char *a_altBinDir, + char *a_device, zoneList_t a_zlst) { static char *zoneTempDir = (char *)NULL; static char *zoneAdminFile = (char *)NULL; @@ -3443,7 +3441,7 @@ static char *zoneAdminFile = (char *)NULL; echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY); echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs, - PSTR(a_idsName), a_repeat, PSTR(a_device)); + PSTR(a_idsName), a_repeat, PSTR(a_device)); /* create temporary directory for use by zone operations */ @@ -3487,10 +3485,10 @@ static char *zoneAdminFile = (char *)NULL; /* package is not a stream - create one */ (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s/%s.dstream", zoneTempDir, pkginst); + "%s/%s.dstream", zoneTempDir, pkginst); echoDebug(DBG_CONVERTING_PKG, packageDir, pkginst, - zoneStreamName); + zoneStreamName); /* set up list of packages to be this package only */ @@ -3498,10 +3496,10 @@ static char *zoneAdminFile = (char *)NULL; pkgs[1] = (char *)NULL; n = pkgtrans(packageDir, zoneStreamName, pkgs, - PT_SILENT|PT_ODTSTREAM); + PT_SILENT|PT_ODTSTREAM); if (n != 0) { progerr(ERR_CANNOT_CONVERT_PKGSTRM, - pkginst, packageDir, zoneStreamName); + pkginst, packageDir, zoneStreamName); quit(1); } npkgs--; @@ -3548,8 +3546,8 @@ static char *zoneAdminFile = (char *)NULL; } echoDebug(DBG_INSTALL_FLAG_VALUES, "after pkginstall", - admnflag, doreboot, failflag, interrupted, intrflag, - ireboot, needconsult, nullflag, warnflag); + admnflag, doreboot, failflag, interrupted, intrflag, + ireboot, needconsult, nullflag, warnflag); /* * call pkginstall to verify this package for all non-global @@ -3557,7 +3555,7 @@ static char *zoneAdminFile = (char *)NULL; */ zonesSkipped = pkginstall_check_in_zones(a_zlst, a_idsName, - a_altBinDir, admnfile, zoneTempDir); + a_altBinDir, admnfile, zoneTempDir); /* * if any zones were skipped (becuase they are not currently @@ -3569,13 +3567,13 @@ static char *zoneAdminFile = (char *)NULL; echoDebug(DBG_ZONES_SKIPPED, zonesSkipped); zonesSkipped = - boot_and_pkginstall_check_in_zones(a_zlst, - a_idsName, a_altBinDir, admnfile, - zoneTempDir); + boot_and_pkginstall_check_in_zones(a_zlst, + a_idsName, a_altBinDir, admnfile, + zoneTempDir); if (zonesSkipped > 0) { progerr(ERR_INSTALL_ZONES_SKIPPED, - zonesSkipped); + zonesSkipped); } } @@ -3645,7 +3643,7 @@ static char *zoneAdminFile = (char *)NULL; if ((askflag != 0) && (respdir != (char *)NULL)) { (void) snprintf(respfile_path, sizeof (respfile_path), - "%s/%s", respdir, pkginst); + "%s/%s", respdir, pkginst); respfile = respfile_path; } @@ -3708,13 +3706,13 @@ static char *zoneAdminFile = (char *)NULL; } echoDebug(DBG_INSTALL_FLAG_VALUES, "install in running zones", - admnflag, doreboot, failflag, interrupted, intrflag, - ireboot, needconsult, nullflag, warnflag); + admnflag, doreboot, failflag, interrupted, intrflag, + ireboot, needconsult, nullflag, warnflag); /* install package in currently booted zones */ zonesSkipped = install_in_zones(a_zlst, a_idsName, a_altBinDir, - zoneAdminFile, zoneTempDir); + zoneAdminFile, zoneTempDir); /* install package in zones that are not currently booted */ @@ -3722,12 +3720,12 @@ static char *zoneAdminFile = (char *)NULL; echoDebug(DBG_ZONES_SKIPPED, zonesSkipped); zonesSkipped = boot_and_install_in_zones(a_zlst, - a_idsName, a_altBinDir, zoneAdminFile, - zoneTempDir); + a_idsName, a_altBinDir, zoneAdminFile, + zoneTempDir); if (zonesSkipped > 0) { progerr(ERR_INSTALL_ZONES_SKIPPED, - zonesSkipped); + zonesSkipped); } } @@ -3739,15 +3737,15 @@ static char *zoneAdminFile = (char *)NULL; if (a_idsName == (char *)NULL) { /* locate temporary stream created earlier */ (void) snprintf(zoneStreamName, sizeof (zoneStreamName), - "%s/%s.dstream", zoneTempDir, pkginst); + "%s/%s.dstream", zoneTempDir, pkginst); /* remove stream - no longer needed */ echoDebug(DBG_REMOVING_DSTREAM_PKGDIR, zoneStreamName, - pkginst); + pkginst); (void) remove(zoneStreamName); } else { /* remove package - no longer needed */ if (snprintf(instdir, sizeof (instdir), "%s/%s", - zoneTempDir, pkginst) >= PATH_MAX) { + zoneTempDir, pkginst) >= PATH_MAX) { progerr(ERR_CANNOT_CREATE_PKGPATH, tmpdir); quit(1); } @@ -3768,7 +3766,7 @@ static char *zoneAdminFile = (char *)NULL; (void) chdir("/"); if (!a_idsName) { echoDebug(DBG_UNMOUNTING_DEV, - PSTR(pkgdev.mount)); + PSTR(pkgdev.mount)); (void) pkgumount(&pkgdev); } } @@ -3784,7 +3782,7 @@ static char *zoneAdminFile = (char *)NULL; */ if ((ireboot == 0) && (a_repeat != 0) && - (pkgdev.pathname == (char *)NULL)) { + (pkgdev.pathname == (char *)NULL)) { return (B_TRUE); } @@ -3804,7 +3802,7 @@ static char *zoneAdminFile = (char *)NULL; static boolean_t add_packages_in_nonglobal_zone(char **a_pkgList, - char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device) + char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device) { static char *zoneTempDir = (char *)NULL; @@ -3823,7 +3821,7 @@ static char *zoneTempDir = (char *)NULL; echoDebug(DBG_ADDPACKAGES_LZ_ENTRY); echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_idsName), - a_repeat, PSTR(a_device)); + a_repeat, PSTR(a_device)); /* create temporary directory for use by zone operations */ @@ -3902,7 +3900,7 @@ static char *zoneTempDir = (char *)NULL; if ((askflag != 0) && (respdir != (char *)NULL)) { (void) snprintf(respfile_path, sizeof (respfile_path), - "%s/%s", respdir, pkginst); + "%s/%s", respdir, pkginst); respfile = respfile_path; } @@ -3928,7 +3926,7 @@ static char *zoneTempDir = (char *)NULL; /* call pkginstall for this package */ n = pkgInstall(get_inst_root(), NULL, - packageDir, a_altBinDir); + packageDir, a_altBinDir); /* set success/fail condition variables */ @@ -3961,7 +3959,7 @@ static char *zoneTempDir = (char *)NULL; */ if ((ireboot == 0) && (a_repeat != 0) && - (pkgdev.pathname == (char *)NULL)) { + (pkgdev.pathname == (char *)NULL)) { return (B_TRUE); } @@ -3981,7 +3979,7 @@ static char *zoneTempDir = (char *)NULL; static boolean_t add_packages_in_global_no_zones(char **a_pkgList, - char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device) + char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device) { int n; int i; @@ -3994,7 +3992,7 @@ add_packages_in_global_no_zones(char **a_pkgList, echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY); echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs, - PSTR(a_idsName), a_repeat, PSTR(a_device)); + PSTR(a_idsName), a_repeat, PSTR(a_device)); /* * set flags for applicability check @@ -4039,7 +4037,7 @@ add_packages_in_global_no_zones(char **a_pkgList, */ if (check_applicability(pkgdev.dirname, - pkginst, get_inst_root(), flags) == B_FALSE) { + pkginst, get_inst_root(), flags) == B_FALSE) { progerr(ERR_PKG_NOT_APPLICABLE, pkginst); quit(1); } @@ -4054,7 +4052,7 @@ add_packages_in_global_no_zones(char **a_pkgList, if ((askflag != 0) && (respdir != (char *)NULL)) { (void) snprintf(respfile_path, sizeof (respfile_path), - "%s/%s", respdir, pkginst); + "%s/%s", respdir, pkginst); respfile = respfile_path; } @@ -4080,7 +4078,7 @@ add_packages_in_global_no_zones(char **a_pkgList, /* call pkginstall for this package */ n = pkgInstall(get_inst_root(), a_idsName, - pkgdev.dirname, a_altBinDir); + pkgdev.dirname, a_altBinDir); /* set success/fail condition variables */ @@ -4113,7 +4111,7 @@ add_packages_in_global_no_zones(char **a_pkgList, */ if ((ireboot == 0) && (a_repeat != 0) && - (pkgdev.pathname == (char *)NULL)) { + (pkgdev.pathname == (char *)NULL)) { return (B_TRUE); } @@ -4130,8 +4128,8 @@ add_packages_in_global_no_zones(char **a_pkgList, static boolean_t add_packages(char **a_pkgList, - char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device, - boolean_t a_noZones) + char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device, + boolean_t a_noZones) { zoneList_t zlst; boolean_t b; @@ -4142,7 +4140,7 @@ add_packages(char **a_pkgList, echoDebug(DBG_ADDPACKAGES_ENTRY); echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_idsName), - a_repeat, PSTR(a_altBinDir), PSTR(a_device)); + a_repeat, PSTR(a_altBinDir), PSTR(a_device)); /* * if running in the global zone AND one or more non-global @@ -4164,7 +4162,7 @@ add_packages(char **a_pkgList, } b = add_packages_in_nonglobal_zone(a_pkgList, a_idsName, - a_repeat, a_altBinDir, a_device); + a_repeat, a_altBinDir, a_device); (void) z_unlock_this_zone(ZLOCKS_ALL); @@ -4175,7 +4173,7 @@ add_packages(char **a_pkgList, b = z_non_global_zones_exist(); if ((a_noZones == B_FALSE) && (b == B_TRUE) && - (globalZoneOnly == B_FALSE)) { + (globalZoneOnly == B_FALSE)) { echoDebug(DBG_IN_GZ_WITH_LZ); @@ -4208,7 +4206,7 @@ add_packages(char **a_pkgList, /* add packages to all zones */ b = add_packages_in_global_with_zones(a_pkgList, - a_idsName, a_repeat, a_altBinDir, a_device, zlst); + a_idsName, a_repeat, a_altBinDir, a_device, zlst); /* unlock all zones */ @@ -4235,7 +4233,7 @@ add_packages(char **a_pkgList, } b = add_packages_in_global_no_zones(a_pkgList, a_idsName, - a_repeat, a_altBinDir, a_device); + a_repeat, a_altBinDir, a_device); (void) z_unlock_this_zone(ZLOCKS_ALL); diff --git a/usr/src/cmd/svr4pkg/pkgadm/lock.c b/usr/src/cmd/svr4pkg/pkgadm/lock.c index 7832cd3eae..df0232ee8f 100644 --- a/usr/src/cmd/svr4pkg/pkgadm/lock.c +++ b/usr/src/cmd/svr4pkg/pkgadm/lock.c @@ -2065,8 +2065,6 @@ _getUniqueId(void) { char newkey[LOCK_KEY_MAXLEN]; hrtime_t hretime; - int b; - int execStatus; struct tm tstruct; time_t thetime; diff --git a/usr/src/cmd/svr4pkg/pkgadm/main.c b/usr/src/cmd/svr4pkg/pkgadm/main.c index cd07946284..4ad670d725 100644 --- a/usr/src/cmd/svr4pkg/pkgadm/main.c +++ b/usr/src/cmd/svr4pkg/pkgadm/main.c @@ -75,7 +75,7 @@ struct cmd cmds[] = { int main(int argc, char **argv) { - char cur_cmd; + int cur_cmd; int newargc; char **newargv; int i; diff --git a/usr/src/cmd/svr4pkg/pkgcond/main.c b/usr/src/cmd/svr4pkg/pkgcond/main.c index 2cf036a790..e3f5ac723d 100644 --- a/usr/src/cmd/svr4pkg/pkgcond/main.c +++ b/usr/src/cmd/svr4pkg/pkgcond/main.c @@ -19,6 +19,10 @@ * CDDL HEADER END */ +/* + * Copyright (c) 2017 Peter Tribble. + */ + /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -351,7 +355,7 @@ main(int argc, char **argv) case 'O': for (p = strtok(optarg, ","); p != NULL; - p = strtok(NULL, ",")) { + p = strtok(NULL, ",")) { /* debug - enable all tracing */ @@ -413,7 +417,7 @@ main(int argc, char **argv) if (parseGlobalData(PKGCOND_GLOBAL_VARIABLE, &gdt) != R_SUCCESS) { log_msg(LOG_MSG_ERR, ERR_CANNOT_USE_GLOBAL_DATA, - PKGCOND_GLOBAL_VARIABLE); + PKGCOND_GLOBAL_VARIABLE); return (R_ERROR); } @@ -421,7 +425,7 @@ main(int argc, char **argv) (strcmp(gdt->gd_installRoot, "/") == 0) ? NULL : ENV_VAR_SET, B_TRUE) != R_SUCCESS) { log_msg(LOG_MSG_ERR, ERR_CANNOT_SET_ROOT_PATH, - ENV_VAR_PKGROOT); + ENV_VAR_PKGROOT); return (R_ERROR); } @@ -611,7 +615,7 @@ static int recursion = 0; if (pkgTestInstalled("SUNWdclnt", "/") != B_TRUE) { log_msg(LOG_MSG_DEBUG, DBG_IDLC_PKG_NOT_INSTALLED, - rootPath, "SUNWdclnt", "/"); + rootPath, "SUNWdclnt", "/"); return (R_FAILURE); } @@ -626,7 +630,7 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_BAD, rootPath, - GLOBAL_ZONENAME); + GLOBAL_ZONENAME); return (R_FAILURE); } @@ -637,7 +641,7 @@ static int recursion = 0; */ (void) snprintf(cmd, sizeof (cmd), "%s %s >/dev/null 2>&1", - LS_CMD, "/export/exec/Solaris_*/usr"); + LS_CMD, "/export/exec/Solaris_*/usr"); /* execute command */ @@ -647,7 +651,7 @@ static int recursion = 0; if (rc != 0) { log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_MISSING, - rootPath, "/export/exec/Solaris_*/usr"); + rootPath, "/export/exec/Solaris_*/usr"); return (R_FAILURE); } @@ -657,7 +661,7 @@ static int recursion = 0; * /usr/bin/ls -d1 $ROOTDIR/usr/\* */ (void) snprintf(cmd, sizeof (cmd), "%s %s %s/%s >/dev/null 2>&1", - LS_CMD, "-1d", rootPath, "usr/*"); + LS_CMD, "-1d", rootPath, "usr/*"); /* execute command */ @@ -667,17 +671,17 @@ static int recursion = 0; if (rc == 0) { log_msg(LOG_MSG_DEBUG, DBG_IDLC_USR_IS_NOT_EMPTY, - rootPath); + rootPath); return (R_FAILURE); } /* there must be a templates directory at ${ROOTPATH}/../templates */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, "../templates"); + "%s/%s", rootPath, "../templates"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_IDLC_NO_TEMPLATES_PATH, - rootPath, rootPath, "../templates"); + rootPath, rootPath, "../templates"); return (R_FAILURE); } @@ -856,7 +860,7 @@ static int recursion = 0; /* the path is a global zone */ log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, - rootPath); + rootPath); return (R_SUCCESS); } @@ -868,7 +872,7 @@ static int recursion = 0; /* the path is a global zone */ log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, - rootPath); + rootPath); return (R_SUCCESS); } @@ -876,7 +880,7 @@ static int recursion = 0; /* inside a non-global zone */ log_msg(LOG_MSG_DEBUG, DBG_ISGZ_ZONENAME_ISNT_GLOBAL, - rootPath, a_gdt->gd_zoneName); + rootPath, a_gdt->gd_zoneName); return (R_FAILURE); } @@ -893,30 +897,30 @@ static int recursion = 0; /* not global zone if /etc/zones does not exist */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, "/etc/zones"); + "%s/%s", rootPath, "/etc/zones"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_ISNT_DIRECTORY, - rootPath, "/etc/zones"); + rootPath, "/etc/zones"); return (R_FAILURE); } /* .tmp_proto must not exist */ r = testPath(TEST_NOT_EXISTS, - "%s/%s", rootPath, ".tmp_proto"); + "%s/%s", rootPath, ".tmp_proto"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_EXISTS, - rootPath, "/.tmp_proto"); + rootPath, "/.tmp_proto"); return (R_FAILURE); } /* /var must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/var"); + "%s/%s", rootPath, "/var"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_SYMLINK, - rootPath, "/var"); + rootPath, "/var"); return (R_FAILURE); } @@ -1030,7 +1034,7 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { log_msg(LOG_MSG_DEBUG, DBG_INIM_BAD_CURRENT_ZONE, - rootPath, GLOBAL_ZONENAME); + rootPath, GLOBAL_ZONENAME); return (R_FAILURE); } @@ -1038,47 +1042,47 @@ static int recursion = 0; if (cmd_is_mounted_miniroot(argc, argv, a_gdt) == R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT, - rootPath); + rootPath); return (R_FAILURE); } /* $ROOTDIR/.tmp_proto exists */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, ".tmp_proto"); + "%s/%s", rootPath, ".tmp_proto"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY, - rootPath, "/.tmp_proto"); + rootPath, "/.tmp_proto"); return (R_FAILURE); } /* $ROOTDIR/var is a symbolic link */ r = testPath(TEST_IS_SYMBOLIC_LINK, - "%s/%s", rootPath, "/var"); + "%s/%s", rootPath, "/var"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK, - rootPath, "/var"); + rootPath, "/var"); return (R_FAILURE); } /* $ROOTDIR/tmp/kernel does exist */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, "/tmp/kernel"); + "%s/%s", rootPath, "/tmp/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY, - rootPath, "/tmp/kernel"); + rootPath, "/tmp/kernel"); return (R_FAILURE); } /* $ROOTDIR/.tmp_proto/kernel is a symbolic link */ r = testPath(TEST_IS_SYMBOLIC_LINK, - "%s/%s", rootPath, "/.tmp_proto/kernel"); + "%s/%s", rootPath, "/.tmp_proto/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK, - rootPath, "/.tmp_proto/kernel"); + rootPath, "/.tmp_proto/kernel"); return (R_FAILURE); } @@ -1188,27 +1192,27 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { log_msg(LOG_MSG_DEBUG, DBG_IMRT_BAD_CURRENT_ZONE, - rootPath, GLOBAL_ZONENAME); + rootPath, GLOBAL_ZONENAME); return (R_FAILURE); } /* $ROOTDIR/tmp/kernel is a symbolic link */ r = testPath(TEST_IS_SYMBOLIC_LINK, - "%s/%s", rootPath, "/tmp/kernel"); + "%s/%s", rootPath, "/tmp/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_SYMLINK, - rootPath, "/tmp/kernel"); + rootPath, "/tmp/kernel"); return (R_FAILURE); } /* $ROOTDIR/tmp/root/kernel is a directory */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, "/tmp/root/kernel"); + "%s/%s", rootPath, "/tmp/root/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_DIRECTORY, - rootPath, "/tmp/root/kernel"); + rootPath, "/tmp/root/kernel"); return (R_FAILURE); } @@ -1316,7 +1320,7 @@ static int recursion = 0; if ((a_gdt->gd_nonglobalZoneInstall == B_TRUE) && (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { log_msg(LOG_MSG_DEBUG, DBG_NGZN_INSTALL_ZONENAME_IS_NGZ, - rootPath, a_gdt->gd_zoneName); + rootPath, a_gdt->gd_zoneName); return (R_SUCCESS); } @@ -1352,12 +1356,12 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) { /* in the global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ, - rootPath, a_gdt->gd_zoneName); + rootPath, a_gdt->gd_zoneName); return (R_FAILURE); } /* in a non-global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_IS_NGZ, - rootPath, a_gdt->gd_zoneName); + rootPath, a_gdt->gd_zoneName); return (R_SUCCESS); } @@ -1401,29 +1405,29 @@ static int recursion = 0; if (r != R_SUCCESS) { /* $R/.tmp_proto cannot exist in a non-global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS, - rootPath, "/.tmp_proto"); + rootPath, "/.tmp_proto"); return (R_FAILURE); } /* /var must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/var"); + "%s/%s", rootPath, "/var"); if (r != R_SUCCESS) { /* $R/var cannot be a symbolic link in a non-global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_DOES_NOT_EXIST, - rootPath, "/var"); + rootPath, "/var"); return (R_FAILURE); } /* $ROOTDIR/tmp/root/kernel must not exist */ r = testPath(TEST_NOT_EXISTS, - "%s/%s", rootPath, "/tmp/root/kernel"); + "%s/%s", rootPath, "/tmp/root/kernel"); if (r != R_SUCCESS) { /* $R/tmp/root/kernel cannot exist in a non-global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS, - rootPath, "/tmp/root/kernel"); + rootPath, "/tmp/root/kernel"); return (R_FAILURE); } @@ -1439,7 +1443,7 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) { /* in the global zone */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_IN_GZ_IS_NONGLOBAL_ZONE, - rootPath); + rootPath); return (R_SUCCESS); } @@ -1461,12 +1465,12 @@ static int recursion = 0; */ if ((a_gdt->gd_parentZoneName != NULL) && - (a_gdt->gd_currentZoneName != NULL) && - (strcmp(a_gdt->gd_parentZoneName, - a_gdt->gd_currentZoneName) == 0)) { + (a_gdt->gd_currentZoneName != NULL) && + (strcmp(a_gdt->gd_parentZoneName, + a_gdt->gd_currentZoneName) == 0)) { /* parent and current zone name identical: non-gz */ log_msg(LOG_MSG_DEBUG, DBG_NGZN_PARENT_CHILD_SAMEZONE, - rootPath, a_gdt->gd_parentZoneName); + rootPath, a_gdt->gd_parentZoneName); return (R_SUCCESS); } @@ -1491,18 +1495,18 @@ static int recursion = 0; /* if defined, parent zone type must be "global" */ if ((a_gdt->gd_parentZoneType != NULL) && - (strcmp(a_gdt->gd_parentZoneType, "nonglobal") == 0)) { + (strcmp(a_gdt->gd_parentZoneType, "nonglobal") == 0)) { log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_PARENT_ZONETYPE, - rootPath, "nonglobal"); + rootPath, "nonglobal"); return (R_FAILURE); } /* if defined, current zone type must be "nonglobal" */ if ((a_gdt->gd_currentZoneType != NULL) && - (strcmp(a_gdt->gd_currentZoneType, GLOBAL_ZONENAME) == 0)) { + (strcmp(a_gdt->gd_currentZoneType, GLOBAL_ZONENAME) == 0)) { log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_CURRENT_ZONETYPE, - rootPath, GLOBAL_ZONENAME); + rootPath, GLOBAL_ZONENAME); return (R_FAILURE); } @@ -1623,7 +1627,7 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_BAD, rootPath, - GLOBAL_ZONENAME); + GLOBAL_ZONENAME); return (R_FAILURE); } @@ -1757,30 +1761,30 @@ static int recursion = 0; /* /etc must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/etc"); + "%s/%s", rootPath, "/etc"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, - rootPath, "/etc"); + rootPath, "/etc"); return (R_FAILURE); } /* /platform must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/platform"); + "%s/%s", rootPath, "/platform"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, - rootPath, "/platform"); + rootPath, "/platform"); return (R_FAILURE); } /* /kernel must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/kernel"); + "%s/%s", rootPath, "/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, - rootPath, "/kernel"); + rootPath, "/kernel"); return (R_FAILURE); } @@ -1896,30 +1900,30 @@ static int recursion = 0; /* /etc must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/etc"); + "%s/%s", rootPath, "/etc"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, - rootPath, "/etc"); + rootPath, "/etc"); return (R_FAILURE); } /* /platform must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/platform"); + "%s/%s", rootPath, "/platform"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, - rootPath, "/platform"); + rootPath, "/platform"); return (R_FAILURE); } /* /kernel must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/kernel"); + "%s/%s", rootPath, "/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, - rootPath, "/kernel"); + rootPath, "/kernel"); return (R_FAILURE); } @@ -2035,30 +2039,30 @@ static int recursion = 0; /* /etc must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/etc"); + "%s/%s", rootPath, "/etc"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, - rootPath, "/etc"); + rootPath, "/etc"); return (R_FAILURE); } /* /platform must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/platform"); + "%s/%s", rootPath, "/platform"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, - rootPath, "/platform"); + rootPath, "/platform"); return (R_FAILURE); } /* /kernel must exist and must not be a symbolic link */ r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, - "%s/%s", rootPath, "/kernel"); + "%s/%s", rootPath, "/kernel"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, - rootPath, "/kernel"); + rootPath, "/kernel"); return (R_FAILURE); } @@ -2169,8 +2173,8 @@ static int recursion = 0; } log_msg(LOG_MSG_DEBUG, DBG_PWRT_INFO, - rootPath, list[nn].fsi_mntPoint, list[nn].fsi_fsType, - list[nn].fsi_mntOptions); + rootPath, list[nn].fsi_mntPoint, list[nn].fsi_fsType, + list[nn].fsi_mntOptions); /* * need to determine if the mount point is writeable: @@ -2181,7 +2185,7 @@ static int recursion = 0; r = mountOptionPresent(list[nn].fsi_mntOptions, MNTOPT_RO); if (r == R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_PWRT_READONLY, - rootPath, list[nn].fsi_mntOptions); + rootPath, list[nn].fsi_mntOptions); return (R_FAILURE); } @@ -2348,10 +2352,10 @@ static int recursion = 0; /* /var must exist */ r = testPath(TEST_EXISTS, - "%s/%s", rootPath, "/var"); + "%s/%s", rootPath, "/var"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_IALR_PATH_DOES_NOT_EXIST, - rootPath, "/var"); + rootPath, "/var"); return (R_FAILURE); } @@ -2497,7 +2501,7 @@ static int recursion = 0; if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ZONE, rootPath, - GLOBAL_ZONENAME); + GLOBAL_ZONENAME); return (R_FAILURE); } @@ -2506,14 +2510,14 @@ static int recursion = 0; r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/lutab"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLUTAB, rootPath, - "/etc/lutab"); + "/etc/lutab"); return (R_FAILURE); } /* $ROOTDIR/etc/lu must exist */ r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, - "%s/%s", rootPath, "/etc/lu"); + "%s/%s", rootPath, "/etc/lu"); if (r != R_SUCCESS) { log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLU, rootPath, "/etc/lu"); return (R_FAILURE); @@ -2635,7 +2639,7 @@ static char *cmdName = "is_what"; result = adjustResults(result); log_msg(LOG_MSG_INFO, MSG_IS_WHAT_RESULT, - cmds[cur_cmd].c_name, result); + cmds[cur_cmd].c_name, result); } return (R_SUCCESS); } @@ -2758,7 +2762,7 @@ mountOptionPresent(char *a_mntOptions, char *a_opt) static void sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint, - char *a_fsType, char *a_mntOptions) + char *a_fsType, char *a_mntOptions) { int listSize; FSI_T *list; @@ -2824,7 +2828,7 @@ sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint, /* entry already in list -- merge entries */ len = strlen(list[n].fsi_mntOptions) + - strlen(a_mntOptions) + 2; + strlen(a_mntOptions) + 2; me = (char *)calloc(1, len); /* merge two mount options lists into one */ @@ -2839,9 +2843,9 @@ sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint, list[n].fsi_mntOptions = me; echoDebug(DBG_SORTEDINS_SKIPPED, - n, list[n].fsi_mntPoint, a_fsType, - list[n].fsi_fsType, a_mntOptions, - list[n].fsi_mntOptions); + n, list[n].fsi_mntPoint, a_fsType, + list[n].fsi_fsType, a_mntOptions, + list[n].fsi_mntOptions); continue; } else if (c < 0) { @@ -2856,9 +2860,9 @@ sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint, /* allocate one more entry and make space for new entry */ listSize++; list = (FSI_T *)realloc(list, - sizeof (FSI_T)*(listSize+1)); + sizeof (FSI_T)*(listSize+1)); (void) memmove(&(list[n+1]), &(list[n]), - sizeof (FSI_T)*(listSize-n)); + sizeof (FSI_T)*(listSize-n)); /* insert this entry into list */ list[n].fsi_mntPoint = strdup(a_mntPoint); @@ -2936,9 +2940,10 @@ calculateFileSystemConfig(GLOBALDATA_T *a_gdt) while (getmntent(fp, &mntbuf) == 0) { if (mntbuf.mnt_mountp[0] == '/') { sortedInsert(&list, &listSize, - strdup(mntbuf.mnt_mountp), - strdup(mntbuf.mnt_fstype), - strdup(mntbuf.mnt_mntopts ? mntbuf.mnt_mntopts : "")); + strdup(mntbuf.mnt_mountp), + strdup(mntbuf.mnt_fstype), + strdup(mntbuf.mnt_mntopts ? + mntbuf.mnt_mntopts : "")); } /* @@ -2947,8 +2952,8 @@ calculateFileSystemConfig(GLOBALDATA_T *a_gdt) */ if (strcmp(mntbuf.mnt_mountp, "/a") == 0 && - strcmp(mntbuf.mnt_special, "/a") == 0 && - strcmp(mntbuf.mnt_fstype, "lofs") == 0) { + strcmp(mntbuf.mnt_special, "/a") == 0 && + strcmp(mntbuf.mnt_fstype, "lofs") == 0) { a_gdt->inMountedState = B_TRUE; } @@ -3000,7 +3005,7 @@ adjustResults(int a_result) /* debugging output */ log_msg(LOG_MSG_DEBUG, DBG_ADJUST_RESULTS, a_result, negate, - realResult); + realResult); /* return results */ @@ -3075,7 +3080,7 @@ setRootPath(char *a_path, char *a_envVar, boolean_t a_mustExist) if (a_mustExist == B_TRUE) { /* must exist ... error */ log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID, - a_path, strerror(errno)); + a_path, strerror(errno)); return (R_ERROR); } else { /* may not exist - use path as specified */ @@ -3095,7 +3100,7 @@ setRootPath(char *a_path, char *a_envVar, boolean_t a_mustExist) if (stat(rp, &statbuf) != 0) { log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID, - rp, strerror(errno)); + rp, strerror(errno)); return (R_ERROR); } @@ -3195,7 +3200,7 @@ testPath(TEST_TYPES a_tt, char *a_format, ...) if (lstat(mbPath, &statbuf) != 0) { echoDebug(DBG_CANNOT_LSTAT_PATH, mbPath, - strerror(errno)); + strerror(errno)); free(mbPath); return (R_FAILURE); } @@ -3413,7 +3418,8 @@ findToken(char *path, char *token) } while (fgets(line, sizeof (line), fp) != NULL) { - for (cp = line; *cp && isspace(*cp); cp++); + for (cp = line; *cp && isspace(*cp); cp++) + ; /* skip comments */ if (*cp == '#') { continue; @@ -3482,7 +3488,7 @@ resolvePath(char **r_path) mbPathlen = strlen(*r_path); if ((wcPath = (wchar_t *) - calloc(1, sizeof (wchar_t)*(mbPathlen+1))) == NULL) { + calloc(1, sizeof (wchar_t)*(mbPathlen+1))) == NULL) { return (R_FAILURE); } @@ -3631,7 +3637,7 @@ static char zoneName[ZONENAME_MAX] = { '\0' }; if (zoneName[0] == '\0') { if (getzonenamebyid(getzoneid(), zoneName, - sizeof (zoneName)) < 0) { + sizeof (zoneName)) < 0) { log_msg(LOG_MSG_ERR, ERR_CANNOT_GET_ZONENAME); return (R_ERROR); } @@ -3695,7 +3701,7 @@ static void setNegateResults(boolean_t setting) { log_msg(LOG_MSG_DEBUG, DBG_SET_NEGATE_RESULTS, - _negateResults, setting); + _negateResults, setting); _negateResults = setting; } @@ -3770,7 +3776,7 @@ usage(char *a_format, ...) (void) strlcat(cmdlst, cmds[cur_cmd].c_name, sizeof (cmdlst)); if (cmds[cur_cmd].c_args != NULL) { (void) strlcat(cmdlst, cmds[cur_cmd].c_args, - sizeof (cmdlst)); + sizeof (cmdlst)); } (void) strlcat(cmdlst, "\n", sizeof (cmdlst)); } @@ -3799,7 +3805,6 @@ static int parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt) { int r; - int n; char *a; SML_TAG *tag; SML_TAG *ntag; @@ -3912,7 +3917,7 @@ parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt) ntag = smlGetTagByName(tag, 0, TAG_COND_TOPLEVEL); if (ntag == SML_TAG__NULL) { log_msg(LOG_MSG_WRN, WRN_PARSED_DATA_MISSING, - TAG_COND_TOPLEVEL); + TAG_COND_TOPLEVEL); return (R_FAILURE); } @@ -3933,13 +3938,13 @@ parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt) /* current zone name */ a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE, - TAG_COND_ZONE_NAME); + TAG_COND_ZONE_NAME); (*r_gdt)->gd_currentZoneName = a; /* current zone type */ a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE, - TAG_COND_ZONE_TYPE); + TAG_COND_ZONE_TYPE); (*r_gdt)->gd_currentZoneType = a; return (R_SUCCESS); @@ -3964,11 +3969,11 @@ dumpGlobalData(GLOBALDATA_T *a_gdt) echoDebug(DBG_DUMP_GLOBAL_ENTRY); echoDebug(DBG_DUMP_GLOBAL_PARENT_ZONE, - a_gdt->gd_parentZoneName ? a_gdt->gd_parentZoneName : "", - a_gdt->gd_parentZoneType ? a_gdt->gd_parentZoneType : ""); + a_gdt->gd_parentZoneName ? a_gdt->gd_parentZoneName : "", + a_gdt->gd_parentZoneType ? a_gdt->gd_parentZoneType : ""); echoDebug(DBG_DUMP_GLOBAL_CURRENT_ZONE, - a_gdt->gd_currentZoneName ? a_gdt->gd_currentZoneName : "", - a_gdt->gd_currentZoneType ? a_gdt->gd_currentZoneType : ""); + a_gdt->gd_currentZoneName ? a_gdt->gd_currentZoneName : "", + a_gdt->gd_currentZoneType ? a_gdt->gd_currentZoneType : ""); } diff --git a/usr/src/cmd/svr4pkg/pkginfo/pkginfo.c b/usr/src/cmd/svr4pkg/pkginfo/pkginfo.c index b26bb74350..cdb0397015 100644 --- a/usr/src/cmd/svr4pkg/pkginfo/pkginfo.c +++ b/usr/src/cmd/svr4pkg/pkginfo/pkginfo.c @@ -19,6 +19,10 @@ * CDDL HEADER END */ +/* + * Copyright (c) 2017 Peter Tribble. + */ + /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -176,42 +180,42 @@ main(int argc, char **argv) while ((c = getopt(argc, argv, "LNR:xv:a:d:qrpilc:?")) != EOF) { switch (c) { - case 'v': + case 'v': ckvers = optarg; break; - case 'a': + case 'a': ckarch = optarg; break; - case 'd': + case 'd': /* -d could specify stream or mountable device */ device = flex_device(optarg, 1); break; - case 'q': + case 'q': qflag++; break; - case 'i': + case 'i': iflag = 1; if (pflag > 0) usage(); pflag = 0; break; - case 'p': + case 'p': pflag = 1; if (iflag > 0) usage(); iflag = 0; break; - case 'N': + case 'N': Nflag++; break; - case 'L': + case 'L': if (xflag || lflag || rflag) { progerr(gettext(ERR_INCOMP0)); usage(); @@ -219,7 +223,7 @@ main(int argc, char **argv) Lflag++; break; - case 'l': + case 'l': if (xflag || rflag) { progerr(gettext(ERR_INCOMP1)); usage(); @@ -227,7 +231,7 @@ main(int argc, char **argv) lflag++; break; - case 'x': + case 'x': /* bug # 1081606 */ if (lflag || rflag) { progerr(gettext(ERR_INCOMP2)); @@ -236,7 +240,7 @@ main(int argc, char **argv) xflag++; break; - case 'r': + case 'r': if (lflag || xflag || Lflag) { progerr(gettext(ERR_INCOMP0)); usage(); @@ -244,21 +248,21 @@ main(int argc, char **argv) rflag++; break; - case 'c': + case 'c': ckcatg[ncatg++] = strtok(optarg, " \t\n, "); while (ckcatg[ncatg] = strtok(NULL, " \t\n, ")) ncatg++; break; /* added for newroot functions */ - case 'R': + case 'R': if (!set_inst_root(optarg)) { progerr(gettext(ERR_ROOT_CMD)); exit(1); } break; - default: + default: usage(); } } @@ -370,9 +374,9 @@ report(void) } if (!pflag && + (choice->partial || (info.status == PI_PARTIAL) || + (info.status == PI_UNKNOWN))) { /* don't include partially installed packages */ - (choice->partial || (info.status == PI_PARTIAL) || - (info.status == PI_UNKNOWN))) { choice->installed = (-1); continue; } @@ -599,7 +603,6 @@ static void look_for_installed(void) { struct dirent *drp; - struct stat status; DIR *dirfp; char path[PATH_MAX]; @@ -694,7 +697,7 @@ getinfo(struct cfstat *dp) VFP_T *vfp; (void) snprintf(pkgmap, sizeof (pkgmap), - "%s/%s/pkgmap", pkgdir, dp->pkginst); + "%s/%s/pkgmap", pkgdir, dp->pkginst); if (vfpOpen(&vfp, pkgmap, "r", VFP_NEEDNOW) != 0) { progerr(gettext("unable open \"%s\" for reading"), pkgmap); @@ -738,7 +741,7 @@ pkgusage(struct cfstat *dp, struct cfent *pentry) if (pentry->ainfo.mode & 06000) dp->setuid++; if (!strchr("dxcbp", pentry->ftype) && - (pentry->ainfo.mode & 0111)) + (pentry->ainfo.mode & 0111)) dp->exec++; } } diff --git a/usr/src/cmd/svr4pkg/pkginstall/dockspace.c b/usr/src/cmd/svr4pkg/pkginstall/dockspace.c index e306e0dbef..8d6bf9e0ce 100644 --- a/usr/src/cmd/svr4pkg/pkginstall/dockspace.c +++ b/usr/src/cmd/svr4pkg/pkginstall/dockspace.c @@ -19,6 +19,10 @@ * CDDL HEADER END */ +/* + * Copyright (c) 2017 Peter Tribble. + */ + /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -105,7 +109,7 @@ dockspace(char *spacefile) if (fs_tab->bfree < (LIM_BFREE + fs_tab->bused)) { warn(TYPE_BLCK, fs_tab->name, fs_tab->bused, - fs_tab->bfree, LIM_BFREE); + fs_tab->bfree, LIM_BFREE); error++; } @@ -114,7 +118,7 @@ dockspace(char *spacefile) continue; if (fs_tab->ffree < (LIM_FFREE + fs_tab->fused)) { warn(TYPE_NODE, fs_tab->name, fs_tab->fused, - fs_tab->ffree, LIM_FFREE); + fs_tab->ffree, LIM_FFREE); error++; } } @@ -193,7 +197,7 @@ readmap(int *error) struct stat statbuf; char tpath[PATH_MAX]; fsblkcnt_t blk; - int i, n; + int i; /* * Handle the installation files (ftype i) that are in the diff --git a/usr/src/cmd/svr4pkg/pkgremove/check.c b/usr/src/cmd/svr4pkg/pkgremove/check.c index a013c4cf02..6cf5b4350b 100644 --- a/usr/src/cmd/svr4pkg/pkgremove/check.c +++ b/usr/src/cmd/svr4pkg/pkgremove/check.c @@ -19,6 +19,10 @@ * CDDL HEADER END */ +/* + * Copyright (c) 2017 Peter Tribble. + */ + /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -153,7 +157,6 @@ rckdepend(void) { int n; char ans[MAX_INPUT]; - char **id, **name; if (ADM(rdepend, "nocheck")) { return (0); diff --git a/usr/src/cmd/svr4pkg/pkgtrans/main.c b/usr/src/cmd/svr4pkg/pkgtrans/main.c index 79218e06dd..b13920c2a1 100644 --- a/usr/src/cmd/svr4pkg/pkgtrans/main.c +++ b/usr/src/cmd/svr4pkg/pkgtrans/main.c @@ -59,10 +59,8 @@ main(int argc, char *argv[]) { int c; void (*func)(); - extern char *optarg; extern int optind; - char *homedir = NULL; - int ret, len; + int ret; (void) setlocale(LC_ALL, ""); -- cgit v1.2.3 From 5400f871d9d59398f2c72ca8320aad07c6caa49c Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Mon, 5 Jun 2017 23:20:35 +0000 Subject: 8350 mr_sas - replace sprintf() with snprintf() Reviewed by: Robert Mustacchi Reviewed by: Jason King Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/uts/common/io/mr_sas/mr_sas.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'usr/src') diff --git a/usr/src/uts/common/io/mr_sas/mr_sas.c b/usr/src/uts/common/io/mr_sas/mr_sas.c index 4e3fe4dcce..c0fdf5c8db 100644 --- a/usr/src/uts/common/io/mr_sas/mr_sas.c +++ b/usr/src/uts/common/io/mr_sas/mr_sas.c @@ -891,7 +891,8 @@ mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) instance->unroll.scsictl = 1; - (void) sprintf(instance->iocnode, "%d:lsirdctl", instance_no); + (void) snprintf(instance->iocnode, sizeof (instance->iocnode), + "%d:lsirdctl", instance_no); /* * Create a node for applications @@ -1707,7 +1708,7 @@ mrsas_find_child(struct mrsas_instance *instance, uint16_t tgt, uint8_t lun) char addr[SCSI_MAXNAMELEN]; char tmp[MAXNAMELEN]; - (void) sprintf(addr, "%x,%x", tgt, lun); + (void) snprintf(addr, sizeof (addr), "%x,%x", tgt, lun); for (child = ddi_get_child(instance->dip); child; child = ddi_get_next_sibling(child)) { -- cgit v1.2.3 From 3f068ebd9d125396d22997224889b677a22523fe Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Mon, 15 May 2017 16:16:16 +0300 Subject: 8232 pcmcia: misleading-indentation Reviewed by: Robert Mustacchi Reviewed by: Yuri Pankov Approved by: Dan McDonald --- usr/src/uts/common/pcmcia/nexus/pcmcia.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'usr/src') diff --git a/usr/src/uts/common/pcmcia/nexus/pcmcia.c b/usr/src/uts/common/pcmcia/nexus/pcmcia.c index 3b08cbcc18..e2b6abbedd 100644 --- a/usr/src/uts/common/pcmcia/nexus/pcmcia.c +++ b/usr/src/uts/common/pcmcia/nexus/pcmcia.c @@ -511,7 +511,7 @@ static int (*cs_error_ptr)() = card_services_error; */ int pcmcia_ctlops(dev_info_t *dip, dev_info_t *rdip, - ddi_ctl_enum_t ctlop, void *arg, void *result) + ddi_ctl_enum_t ctlop, void *arg, void *result) { int e; char name[64]; @@ -953,7 +953,7 @@ pcmcia_find_rnum(dev_info_t *dip, struct regspec *reg) int pcmcia_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, - off_t offset, off_t len, caddr_t *vaddrp) + off_t offset, off_t len, caddr_t *vaddrp) { struct pcm_regs *regs, *mregs = NULL, tmp_reg; ddi_map_req_t mr = *mp; @@ -1704,7 +1704,7 @@ pcm_find_parent_dip(int socket) */ int pcmcia_set_em_handler(int (*handler)(), caddr_t events, int elen, - uint32_t id, void **cs, void **ss) + uint32_t id, void **cs, void **ss) { struct pcmcia_mif *mif, *tmp; @@ -2338,7 +2338,7 @@ pcmcia_fix_string(char *str) void pcmcia_1275_name(int socket, struct pcm_device_info *info, - client_handle_t handle) + client_handle_t handle) { cistpl_manfid_t manfid; cistpl_jedec_t jedec; @@ -2453,7 +2453,7 @@ char *pcmcia_lan_types[] = { void pcmcia_generic_name(int socket, struct pcm_device_info *info, - client_handle_t handle) + client_handle_t handle) { cistpl_funcid_t funcid; cistpl_funce_t funce; @@ -2642,7 +2642,7 @@ pcmcia_add_compatible(dev_info_t *dip, struct pcm_device_info *info) */ static int pcmcia_get_mem_regs(struct pcm_regs *regs, struct pcm_device_info *info, - int type, int pctype) + int type, int pctype) { int num_regs = 0; tuple_t tuple; @@ -2711,7 +2711,7 @@ pcmcia_get_mem_regs(struct pcm_regs *regs, struct pcm_device_info *info, */ static int pcmcia_get_io_regs(struct pcm_regs *regs, struct pcm_device_info *info, - int pctype) + int pctype) { int num_regs = 0; tuple_t tuple; @@ -5425,13 +5425,14 @@ pcmcia_intr_disable_isr(dev_info_t *dip, dev_info_t *rdip, /* Check if there is only one handler left */ if ((intr->next == intr) && (intr->prev == intr)) { - if (intr->handler_id != (uint32_t)(uintptr_t)rdip) + if (intr->handler_id != (uint32_t)(uintptr_t)rdip) { /* * need to get the dip that was * used to add the handler */ rdip = sockp->ls_mfintr_dip; - ispecp = (struct intrspec *)&sockp->ls_intrspec; + } + ispecp = (struct intrspec *)&sockp->ls_intrspec; } else { /* Don't call cleanup if list still has members */ mutex_exit(&sockp->ls_ilock); -- cgit v1.2.3 From 92381362ae635a3bea638d87b7119f1623b6212e Mon Sep 17 00:00:00 2001 From: Jerry Jelinek Date: Fri, 12 May 2017 23:01:38 +0000 Subject: 8319 dis support for new xsave instructions Reviewed by: Robert Mustacchi Reviewed by: Gordon Ross Approved by: Richard Lowe --- usr/src/common/dis/i386/dis_tables.c | 21 +++++++++++++++++---- usr/src/test/util-tests/tests/dis/i386/32.xsave.out | 12 ++++++++---- usr/src/test/util-tests/tests/dis/i386/32.xsave.s | 9 +++++++-- usr/src/test/util-tests/tests/dis/i386/64.xsave.out | 12 ++++++++---- usr/src/test/util-tests/tests/dis/i386/64.xsave.s | 10 +++++++--- 5 files changed, 47 insertions(+), 17 deletions(-) (limited to 'usr/src') diff --git a/usr/src/common/dis/i386/dis_tables.c b/usr/src/common/dis/i386/dis_tables.c index 4204f8ab9e..beb1296f57 100644 --- a/usr/src/common/dis/i386/dis_tables.c +++ b/usr/src/common/dis/i386/dis_tables.c @@ -573,8 +573,8 @@ const instable_t dis_op0FBA[8] = { const instable_t dis_op0FC7[8] = { -/* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, INVALID, -/* [4] */ INVALID, INVALID, TNS("vmptrld",MG9), TNS("vmptrst",MG9), +/* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, TNS("xrstors",MG9), +/* [4] */ TNS("xsavec",MG9), TNS("xsaves",MG9), TNS("vmptrld",MG9), TNS("vmptrst",MG9), }; /* @@ -3597,6 +3597,12 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode) opnd_size_prefix = 0; if (opnd_size == SIZE16) opnd_size = SIZE32; + } else if (reg == 4 || reg == 5) { + /* + * We have xsavec (4) or xsaves (5), so rewrite. + */ + dp = (instable_t *)&dis_op0FC7[reg]; + break; } break; @@ -4829,7 +4835,8 @@ xmmprm: case XMMFENCE: /* - * XRSTOR and LFENCE share the same opcode but differ in mode + * XRSTOR, XSAVEOPT and LFENCE share the same opcode but + * differ in mode and reg. */ dtrace_get_modrm(x, &mode, ®, &r_m); @@ -4845,7 +4852,13 @@ xmmprm: goto error; } else { #ifdef DIS_TEXT - (void) strncpy(x->d86_mnem, "xrstor", OPLEN); + if (reg == 5) { + (void) strncpy(x->d86_mnem, "xrstor", OPLEN); + } else if (reg == 6) { + (void) strncpy(x->d86_mnem, "xsaveopt", OPLEN); + } else { + goto error; + } #endif dtrace_rex_adjust(rex_prefix, mode, ®, &r_m); dtrace_get_operand(x, mode, r_m, BYTE_OPND, 0); diff --git a/usr/src/test/util-tests/tests/dis/i386/32.xsave.out b/usr/src/test/util-tests/tests/dis/i386/32.xsave.out index 4ad87bd36c..7b43ae4934 100644 --- a/usr/src/test/util-tests/tests/dis/i386/32.xsave.out +++ b/usr/src/test/util-tests/tests/dis/i386/32.xsave.out @@ -1,4 +1,8 @@ - libdis_test: 0f ae 28 xrstor (%eax) - libdis_test+0x3: 0f ae 20 xsave (%eax) - libdis_test+0x6: 0f 01 d0 xgetbv - libdis_test+0x9: 0f 01 d1 xsetbv + libdis_test: 0f ae 20 xsave (%eax) + libdis_test+0x3: 0f ae 28 xrstor (%eax) + libdis_test+0x6: 0f c7 20 xsavec (%eax) + libdis_test+0x9: 0f ae 30 xsaveopt (%eax) + libdis_test+0xc: 0f c7 28 xsaves (%eax) + libdis_test+0xf: 0f c7 18 xrstors (%eax) + libdis_test+0x12: 0f 01 d0 xgetbv + libdis_test+0x15: 0f 01 d1 xsetbv diff --git a/usr/src/test/util-tests/tests/dis/i386/32.xsave.s b/usr/src/test/util-tests/tests/dis/i386/32.xsave.s index 7f50b17b86..1fe2d35a39 100644 --- a/usr/src/test/util-tests/tests/dis/i386/32.xsave.s +++ b/usr/src/test/util-tests/tests/dis/i386/32.xsave.s @@ -10,7 +10,7 @@ */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2017 Joyent, Inc. */ /* @@ -22,8 +22,13 @@ .globl libdis_test .type libdis_test, @function libdis_test: - xrstor (%eax) xsave (%eax) + xrstor (%eax) + xsavec (%eax) + xsaveopt (%eax) + xsaves (%eax) + xrstors (%eax) + xgetbv xsetbv diff --git a/usr/src/test/util-tests/tests/dis/i386/64.xsave.out b/usr/src/test/util-tests/tests/dis/i386/64.xsave.out index 7e07b6c1ec..b987aa1562 100644 --- a/usr/src/test/util-tests/tests/dis/i386/64.xsave.out +++ b/usr/src/test/util-tests/tests/dis/i386/64.xsave.out @@ -1,4 +1,8 @@ - libdis_test: 0f ae 28 xrstor (%rax) - libdis_test+0x3: 0f ae 20 xsave (%rax) - libdis_test+0x6: 0f 01 d0 xgetbv - libdis_test+0x9: 0f 01 d1 xsetbv + libdis_test: 0f ae 20 xsave (%rax) + libdis_test+0x3: 0f ae 28 xrstor (%rax) + libdis_test+0x6: 0f c7 20 xsavec (%rax) + libdis_test+0x9: 0f ae 30 xsaveopt (%rax) + libdis_test+0xc: 0f c7 28 xsaves (%rax) + libdis_test+0xf: 0f c7 18 xrstors (%rax) + libdis_test+0x12: 0f 01 d0 xgetbv + libdis_test+0x15: 0f 01 d1 xsetbv diff --git a/usr/src/test/util-tests/tests/dis/i386/64.xsave.s b/usr/src/test/util-tests/tests/dis/i386/64.xsave.s index 7f4627e691..b56a22e2dd 100644 --- a/usr/src/test/util-tests/tests/dis/i386/64.xsave.s +++ b/usr/src/test/util-tests/tests/dis/i386/64.xsave.s @@ -10,11 +10,11 @@ */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2017 Joyent, Inc. */ /* - * Test 32-bit xsave related instructions + * Test 64-bit xsave related instructions */ .text @@ -22,8 +22,12 @@ .globl libdis_test .type libdis_test, @function libdis_test: - xrstor (%rax) xsave (%rax) + xrstor (%rax) + xsavec (%rax) + xsaveopt (%rax) + xsaves (%rax) + xrstors (%rax) xgetbv xsetbv -- cgit v1.2.3 From a4b8c9aa65a0a735aba318024a424a90d7b06c37 Mon Sep 17 00:00:00 2001 From: Andrew Stormont Date: Mon, 12 Jun 2017 10:55:33 +0100 Subject: 8264 want support for promoting datasets in libzfs_core Reviewed by: Andriy Gapon Reviewed by: Matthew Ahrens Reviewed by: Dan McDonald Approved by: Dan McDonald --- usr/src/lib/libzfs/common/libzfs_dataset.c | 20 +++++--------- usr/src/lib/libzfs_core/common/libzfs_core.c | 25 +++++++++++++++++- usr/src/lib/libzfs_core/common/libzfs_core.h | 2 ++ usr/src/lib/libzfs_core/common/mapfile-vers | 2 ++ usr/src/uts/common/fs/zfs/zfs_ioctl.c | 39 +++++++++++++++++++++++++--- 5 files changed, 71 insertions(+), 17 deletions(-) (limited to 'usr/src') diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 33803630a1..5255204788 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -30,6 +30,7 @@ * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Nexenta Systems, Inc. * Copyright 2016 Igor Kozhukhov + * Copyright 2017 RackTop Systems. */ #include @@ -3630,8 +3631,7 @@ int zfs_promote(zfs_handle_t *zhp) { libzfs_handle_t *hdl = zhp->zfs_hdl; - zfs_cmd_t zc = { 0 }; - char parent[MAXPATHLEN]; + char snapname[ZFS_MAX_DATASET_NAME_LEN]; int ret; char errbuf[1024]; @@ -3644,31 +3644,25 @@ zfs_promote(zfs_handle_t *zhp) return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); } - (void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent)); - if (parent[0] == '\0') { + if (zhp->zfs_dmustats.dds_origin[0] == '\0') { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "not a cloned filesystem")); return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); } - (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin, - sizeof (zc.zc_value)); - (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); - ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc); + ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname)); if (ret != 0) { - int save_errno = errno; - - switch (save_errno) { + switch (ret) { case EEXIST: /* There is a conflicting snapshot name. */ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "conflicting snapshot '%s' from parent '%s'"), - zc.zc_string, parent); + snapname, zhp->zfs_dmustats.dds_origin); return (zfs_error(hdl, EZFS_EXISTS, errbuf)); default: - return (zfs_standard_error(hdl, save_errno, errbuf)); + return (zfs_standard_error(hdl, ret, errbuf)); } } return (ret); diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.c b/usr/src/lib/libzfs_core/common/libzfs_core.c index 71e4d52351..87f7ea4f46 100644 --- a/usr/src/lib/libzfs_core/common/libzfs_core.c +++ b/usr/src/lib/libzfs_core/common/libzfs_core.c @@ -23,6 +23,7 @@ * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2017 RackTop Systems. */ /* @@ -203,6 +204,28 @@ lzc_clone(const char *fsname, const char *origin, return (error); } +int +lzc_promote(const char *fsname, char *snapnamebuf, int snapnamelen) +{ + /* + * The promote ioctl is still legacy, so we need to construct our + * own zfs_cmd_t rather than using lzc_ioctl(). + */ + zfs_cmd_t zc = { 0 }; + + ASSERT3S(g_refcount, >, 0); + VERIFY3S(g_fd, !=, -1); + + (void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name)); + if (ioctl(g_fd, ZFS_IOC_PROMOTE, &zc) != 0) { + int error = errno; + if (error == EEXIST && snapnamebuf != NULL) + (void) strlcpy(snapnamebuf, zc.zc_string, snapnamelen); + return (error); + } + return (0); +} + /* * Creates snapshots. * @@ -330,7 +353,7 @@ lzc_exists(const char *dataset) { /* * The objset_stats ioctl is still legacy, so we need to construct our - * own zfs_cmd_t rather than using zfsc_ioctl(). + * own zfs_cmd_t rather than using lzc_ioctl(). */ zfs_cmd_t zc = { 0 }; diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.h b/usr/src/lib/libzfs_core/common/libzfs_core.h index 094fa257e4..3d9e14d3da 100644 --- a/usr/src/lib/libzfs_core/common/libzfs_core.h +++ b/usr/src/lib/libzfs_core/common/libzfs_core.h @@ -22,6 +22,7 @@ /* * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2017 RackTop Systems. */ #ifndef _LIBZFS_CORE_H @@ -49,6 +50,7 @@ enum lzc_dataset_type { int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **); int lzc_create(const char *, enum lzc_dataset_type, nvlist_t *); int lzc_clone(const char *, const char *, nvlist_t *); +int lzc_promote(const char *, char *, int); int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **); int lzc_bookmark(nvlist_t *, nvlist_t **); int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **); diff --git a/usr/src/lib/libzfs_core/common/mapfile-vers b/usr/src/lib/libzfs_core/common/mapfile-vers index b699fcbf40..fd7650c977 100644 --- a/usr/src/lib/libzfs_core/common/mapfile-vers +++ b/usr/src/lib/libzfs_core/common/mapfile-vers @@ -20,6 +20,7 @@ # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012, 2014 by Delphix. All rights reserved. +# Copyright 2017 RackTop Systems. # # MAPFILE HEADER START # @@ -43,6 +44,7 @@ SYMBOL_VERSION ILLUMOS_0.1 { libzfs_core_init; lzc_bookmark; lzc_clone; + lzc_promote; lzc_create; lzc_destroy_bookmarks; lzc_destroy_snaps; diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c index da22cb6c81..d93c1f02c3 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c @@ -31,6 +31,7 @@ * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Toomas Soome + * Copyright 2017 RackTop Systems. */ /* @@ -4702,7 +4703,6 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc) /* * inputs: * zc_name name of filesystem - * zc_value name of origin snapshot * * outputs: * zc_string name of conflicting snapshot, if there is one @@ -4710,16 +4710,49 @@ zfs_ioc_pool_reopen(zfs_cmd_t *zc) static int zfs_ioc_promote(zfs_cmd_t *zc) { + dsl_pool_t *dp; + dsl_dataset_t *ds, *ods; + char origin[ZFS_MAX_DATASET_NAME_LEN]; char *cp; + int error; + + error = dsl_pool_hold(zc->zc_name, FTAG, &dp); + if (error != 0) + return (error); + + error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds); + if (error != 0) { + dsl_pool_rele(dp, FTAG); + return (error); + } + + if (!dsl_dir_is_clone(ds->ds_dir)) { + dsl_dataset_rele(ds, FTAG); + dsl_pool_rele(dp, FTAG); + return (SET_ERROR(EINVAL)); + } + + error = dsl_dataset_hold_obj(dp, + dsl_dir_phys(ds->ds_dir)->dd_origin_obj, FTAG, &ods); + if (error != 0) { + dsl_dataset_rele(ds, FTAG); + dsl_pool_rele(dp, FTAG); + return (error); + } + + dsl_dataset_name(ods, origin); + dsl_dataset_rele(ods, FTAG); + dsl_dataset_rele(ds, FTAG); + dsl_pool_rele(dp, FTAG); /* * We don't need to unmount *all* the origin fs's snapshots, but * it's easier. */ - cp = strchr(zc->zc_value, '@'); + cp = strchr(origin, '@'); if (cp) *cp = '\0'; - (void) dmu_objset_find(zc->zc_value, + (void) dmu_objset_find(origin, zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS); return (dsl_dataset_promote(zc->zc_name, zc->zc_string)); } -- cgit v1.2.3 From 336970851eecf9c4348b3de7bbea0687059dd216 Mon Sep 17 00:00:00 2001 From: Gordon Ross Date: Mon, 8 May 2017 10:08:35 -0400 Subject: 6856 sys/stream.h exposes unnecessary macros to userland Portions contributed by: Lauri Tirkkonen Reviewed by: Yuri Pankov Reviewed by: Andy Stormont Approved by: Hans Rosenfeld --- usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h | 4 +++- usr/src/uts/common/fs/smbclnt/netsmb/smb_tran.h | 1 + usr/src/uts/common/inet/ilb/ilb_alg_rr.c | 2 ++ usr/src/uts/common/netinet/in.h | 3 --- usr/src/uts/common/sys/hook_event.h | 8 +++++--- usr/src/uts/common/sys/ksocket.h | 5 +++-- usr/src/uts/common/sys/mac_flow.h | 1 + usr/src/uts/common/sys/neti.h | 12 +++++++----- usr/src/uts/common/sys/netstack.h | 2 ++ usr/src/uts/common/sys/scsi/adapters/iscsi_if.h | 1 + usr/src/uts/common/sys/socket.h | 10 ++++++++++ usr/src/uts/common/sys/socket_proto.h | 1 + 12 files changed, 36 insertions(+), 14 deletions(-) (limited to 'usr/src') diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h b/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h index 601c78ac7c..df0f28ec05 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_subr.h @@ -45,11 +45,13 @@ #include #include +struct msgb; /* avoiding sys/stream.h here */ + /* Helper function for SMBERROR */ /*PRINTFLIKE3*/ extern void smb_errmsg(int, const char *, const char *, ...) __KPRINTFLIKE(3); -void m_dumpm(mblk_t *m); +void m_dumpm(struct msgb *); /* * Let's use C99 standard variadic macros! diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_tran.h b/usr/src/uts/common/fs/smbclnt/netsmb/smb_tran.h index 052759f333..f954056a79 100644 --- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_tran.h +++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_tran.h @@ -41,6 +41,7 @@ #define _NETSMB_SMB_TRAN_H_ #include +#include /* * Known transports diff --git a/usr/src/uts/common/inet/ilb/ilb_alg_rr.c b/usr/src/uts/common/inet/ilb/ilb_alg_rr.c index e88712e19f..c22d7eb027 100644 --- a/usr/src/uts/common/inet/ilb/ilb_alg_rr.c +++ b/usr/src/uts/common/inet/ilb/ilb_alg_rr.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include diff --git a/usr/src/uts/common/netinet/in.h b/usr/src/uts/common/netinet/in.h index d77d014e0c..9ac3066362 100644 --- a/usr/src/uts/common/netinet/in.h +++ b/usr/src/uts/common/netinet/in.h @@ -63,9 +63,6 @@ typedef void *Psocklen_t; #endif /* _SOCKLEN_T */ -#if !defined(_XPG4_2) || defined(__EXTENSIONS__) -#include -#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ /* * Symbols such as htonl() are required to be exposed through this file, * per XNS Issue 5. This is achieved by inclusion of diff --git a/usr/src/uts/common/sys/hook_event.h b/usr/src/uts/common/sys/hook_event.h index 131460343b..193d1f65d4 100644 --- a/usr/src/uts/common/sys/hook_event.h +++ b/usr/src/uts/common/sys/hook_event.h @@ -39,6 +39,8 @@ extern "C" { #endif +struct msgb; /* avoiding sys/stream.h here */ + /* * The hook_pkt_event_t structure is supplied with packet events on * associated network interfaces. @@ -57,8 +59,8 @@ typedef struct hook_pkt_event { phy_if_t hpe_ifp; phy_if_t hpe_ofp; void *hpe_hdr; - mblk_t **hpe_mp; - mblk_t *hpe_mb; + struct msgb **hpe_mp; + struct msgb *hpe_mb; int hpe_flags; void *hpe_reserved[2]; } hook_pkt_event_t; @@ -145,7 +147,7 @@ typedef struct hook_pkt_observe_s { /* * Fields used internally are below. */ - mblk_t *hpo_pkt; + struct msgb *hpo_pkt; void *hpo_ctx; } hook_pkt_observe_t; diff --git a/usr/src/uts/common/sys/ksocket.h b/usr/src/uts/common/sys/ksocket.h index dfe25eec76..5d8827f1ae 100644 --- a/usr/src/uts/common/sys/ksocket.h +++ b/usr/src/uts/common/sys/ksocket.h @@ -33,6 +33,7 @@ extern "C" { /* Opaque kernel socket type */ typedef struct __ksocket *ksocket_t; struct nmsghdr; +struct msgb; /* avoiding sys/stream.h here */ /* flag bit for each Callback Event */ #define KSOCKET_CB_CONNECTED 0x00000001 @@ -96,8 +97,8 @@ extern int ksocket_sendto(ksocket_t, void *, size_t, int, struct sockaddr *, socklen_t, size_t *, struct cred *); extern int ksocket_sendmsg(ksocket_t, struct nmsghdr *, int, size_t *, struct cred *); -extern int ksocket_sendmblk(ksocket_t, struct nmsghdr *, int, mblk_t **, - struct cred *); +extern int ksocket_sendmblk(ksocket_t, struct nmsghdr *, int, + struct msgb **, struct cred *); extern int ksocket_recv(ksocket_t, void *, size_t, int, size_t *, struct cred *); extern int ksocket_recvfrom(ksocket_t, void *, size_t, int, diff --git a/usr/src/uts/common/sys/mac_flow.h b/usr/src/uts/common/sys/mac_flow.h index d43186f2b0..e290ba7dbe 100644 --- a/usr/src/uts/common/sys/mac_flow.h +++ b/usr/src/uts/common/sys/mac_flow.h @@ -37,6 +37,7 @@ extern "C" { #endif #include +#include /* for MAXPATHLEN */ #include /* for IPPROTO_* constants */ #include diff --git a/usr/src/uts/common/sys/neti.h b/usr/src/uts/common/sys/neti.h index 93b5fc3e01..b21504109c 100644 --- a/usr/src/uts/common/sys/neti.h +++ b/usr/src/uts/common/sys/neti.h @@ -36,6 +36,8 @@ extern "C" { #endif +struct msgb; /* avoiding sys/stream.h here */ + #define NETINFO_VERSION 1 /* @@ -109,7 +111,7 @@ typedef enum inject { typedef struct net_inject { int ni_version; netid_t ni_netid; - mblk_t *ni_packet; + struct msgb *ni_packet; struct sockaddr_storage ni_addr; phy_if_t ni_physical; } net_inject_t; @@ -138,8 +140,8 @@ struct net_protocol_s { int (*netp_inject)(net_handle_t, inject_t, net_inject_t *); phy_if_t (*netp_routeto)(net_handle_t, struct sockaddr *, struct sockaddr *); - int (*netp_ispartialchecksum)(net_handle_t, mblk_t *); - int (*netp_isvalidchecksum)(net_handle_t, mblk_t *); + int (*netp_ispartialchecksum)(net_handle_t, struct msgb *); + int (*netp_isvalidchecksum)(net_handle_t, struct msgb *); }; typedef struct net_protocol_s net_protocol_t; @@ -286,8 +288,8 @@ extern phy_if_t net_phylookup(net_handle_t, const char *); extern lif_if_t net_lifgetnext(net_handle_t, phy_if_t, lif_if_t); extern phy_if_t net_routeto(net_handle_t, struct sockaddr *, struct sockaddr *); -extern int net_ispartialchecksum(net_handle_t, mblk_t *); -extern int net_isvalidchecksum(net_handle_t, mblk_t *); +extern int net_ispartialchecksum(net_handle_t, struct msgb *); +extern int net_isvalidchecksum(net_handle_t, struct msgb *); #ifdef __cplusplus } diff --git a/usr/src/uts/common/sys/netstack.h b/usr/src/uts/common/sys/netstack.h index edf703f2ef..b8b46ca350 100644 --- a/usr/src/uts/common/sys/netstack.h +++ b/usr/src/uts/common/sys/netstack.h @@ -32,6 +32,8 @@ #define _SYS_NETSTACK_H #include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/usr/src/uts/common/sys/scsi/adapters/iscsi_if.h b/usr/src/uts/common/sys/scsi/adapters/iscsi_if.h index 501ea9bab1..7043dc6dd9 100644 --- a/usr/src/uts/common/sys/scsi/adapters/iscsi_if.h +++ b/usr/src/uts/common/sys/scsi/adapters/iscsi_if.h @@ -35,6 +35,7 @@ extern "C" { #include #include /* for struct sonode */ #endif +#include /* for MAXPATHLEN */ #include #include #include diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h index 179c64473b..61afedb8ce 100644 --- a/usr/src/uts/common/sys/socket.h +++ b/usr/src/uts/common/sys/socket.h @@ -50,6 +50,16 @@ #ifndef _KERNEL #include #endif /* !_KERNEL */ +/* + * Historically, netinet/in.h included sys/stream.h, which pulled in + * several things. The more troublesome namespace pollution was from + * sys/stream.h so that was removed. To avoid having to fix lots of + * programs, pull in a few things that are now (for better or worse) + * expected by programs that include sys/socket.h + */ +#include +#include +#include #include #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ diff --git a/usr/src/uts/common/sys/socket_proto.h b/usr/src/uts/common/sys/socket_proto.h index 6bc968be1b..cbb3beddaa 100644 --- a/usr/src/uts/common/sys/socket_proto.h +++ b/usr/src/uts/common/sys/socket_proto.h @@ -30,6 +30,7 @@ extern "C" { #endif #include +#include /* * Generation count -- cgit v1.2.3 From d1151f9bab097777251f26772ebcc50468637a12 Mon Sep 17 00:00:00 2001 From: Jason King Date: Sun, 11 Jun 2017 01:01:30 -0500 Subject: 8369 libcmdutils should be better about large file support 8370 libcmdutils needlessly defines its own OFFSETOF() macro Reviewed by: Yuri Pankov Reviewed by: Toomas Soome Reviewed by: Robert Mustacchi Approved by: Gordon Ross --- usr/src/lib/libcmdutils/common/avltree.c | 7 ++++--- usr/src/lib/libcmdutils/libcmdutils.h | 31 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'usr/src') diff --git a/usr/src/lib/libcmdutils/common/avltree.c b/usr/src/lib/libcmdutils/common/avltree.c index 53e919ed34..7146ad4c97 100644 --- a/usr/src/lib/libcmdutils/common/avltree.c +++ b/usr/src/lib/libcmdutils/common/avltree.c @@ -22,13 +22,14 @@ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2017 Joyent, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include +#include #include "libcmdutils.h" /* @@ -175,7 +176,7 @@ add_tnode(avl_tree_t **stree, dev_t device, ino_t inode) avl_create(*stree, tnode_compare, sizeof (tree_node_t), - OFFSETOF(tree_node_t, avl_link)); + offsetof(tree_node_t, avl_link)); } /* Initialize the node */ diff --git a/usr/src/lib/libcmdutils/libcmdutils.h b/usr/src/lib/libcmdutils/libcmdutils.h index 7c3d0ebbc1..933ceb0fde 100644 --- a/usr/src/lib/libcmdutils/libcmdutils.h +++ b/usr/src/lib/libcmdutils/libcmdutils.h @@ -26,7 +26,7 @@ * Copyright (c) 2013 RackTop Systems. */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2017 Joyent, Inc. */ /* @@ -36,6 +36,11 @@ #ifndef _LIBCMDUTILS_H #define _LIBCMDUTILS_H +#if !defined(_LP64) && \ + !((_FILE_OFFSET_BITS == 64) || defined(_LARGEFILE64_SOURCE)) +#error "libcmdutils.h can only be used in a largefile compilation environment" +#endif + /* * This is a private header file. Applications should not directly include * this file. @@ -70,16 +75,21 @@ extern "C" { #define MAXMAPSIZE (1024*1024*8) /* map at most 8MB */ #define SMALLFILESIZE (32*1024) /* don't use mmap on little file */ -/* avltree */ -#define OFFSETOF(s, m) ((size_t)(&(((s *)0)->m))) - /* Type used for a node containing a device id and inode number */ + +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) typedef struct tree_node { dev_t node_dev; ino_t node_ino; avl_node_t avl_link; } tree_node_t; - +#else +typedef struct tree_node { + dev_t node_dev; + ino64_t node_ino; + avl_node_t avl_link; +} tree_node_t; +#endif /* extended system attribute support */ @@ -90,8 +100,13 @@ extern int sysattr_type(char *); extern int sysattr_support(char *, int); /* Copies the content of the source file to the target file */ +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) extern int writefile(int, int, char *, char *, char *, char *, -struct stat *, struct stat *); + struct stat *, struct stat *); +#else +extern int writefile(int, int, char *, char *, char *, char *, + struct stat64 *, struct stat64 *); +#endif /* Gets file descriptors of the source and target attribute files */ extern int get_attrdirs(int, int, char *, int *, int *); @@ -120,7 +135,11 @@ extern int tnode_compare(const void *, const void *); * application must set the tree pointer to NULL before calling * add_tnode() for the first time. */ +#if defined(_LP64) || (_FILE_OFFSET_BITS == 64) extern int add_tnode(avl_tree_t **, dev_t, ino_t); +#else +extern int add_tnode(avl_tree_t **, dev_t, ino64_t); +#endif /* * Used to destroy a whole tree (all nodes) without rebalancing. -- cgit v1.2.3 From dd627ace5d331edb6342d966323629e57008b71f Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 16 Feb 2017 02:16:03 +0200 Subject: 8328 keyserv: sizeof on array function parameter Reviewed by: Marcel Telka Reviewed by: Robert Mustacchi Approved by: Gordon Ross --- usr/src/cmd/keyserv/keyserv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'usr/src') diff --git a/usr/src/cmd/keyserv/keyserv.c b/usr/src/cmd/keyserv/keyserv.c index 393b1635c4..8bb6171772 100644 --- a/usr/src/cmd/keyserv/keyserv.c +++ b/usr/src/cmd/keyserv/keyserv.c @@ -748,15 +748,12 @@ __key_net_get_2_svc(uid, arg, keynetname) } bool_t -__key_get_conv_2_svc(uid, arg, res) - uid_t uid; - keybuf arg; - cryptkeyres *res; +__key_get_conv_2_svc(uid_t uid, keybuf arg, cryptkeyres *res) { if (debugging) (void) fprintf(stderr, "get_conv(%d, %.*s) = ", uid, - sizeof (arg), arg); + sizeof (keybuf), arg); res->status = pk_get_conv_key(uid, arg, res); -- cgit v1.2.3 From 61304e4faaed38301307f7f985160d1843473587 Mon Sep 17 00:00:00 2001 From: Paul Dagnelie Date: Fri, 8 Aug 2014 16:01:22 -0700 Subject: 8086 Add Stride parameter to dd Reviewed by: Alex Reece Reviewed by: Basil Crow Reviewed by: Robert Mustacchi --- usr/src/cmd/dd/dd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++----- usr/src/man/man1m/dd.1m | 48 +++++++++++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 16 deletions(-) (limited to 'usr/src') diff --git a/usr/src/cmd/dd/dd.c b/usr/src/cmd/dd/dd.c index 30f027f85a..6589ba740b 100644 --- a/usr/src/cmd/dd/dd.c +++ b/usr/src/cmd/dd/dd.c @@ -25,6 +25,7 @@ * Use is subject to license terms. * Copyright 2012, Josef 'Jeff' Sipek . All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright (c) 2014 by Delphix. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -103,10 +104,10 @@ #define USAGE\ "usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\ " [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\ - " [iseek=n] [oseek=n] [seek=n] [count=n] [conv=[ascii]\n"\ - " [,ebcdic][,ibm][,asciib][,ebcdicb][,ibmb]\n"\ - " [,block|unblock][,lcase|ucase][,swab]\n"\ - " [,noerror][,notrunc][,sync]]\n"\ + " [iseek=n] [oseek=n] [seek=n] [stride=n] [istride=n]\n"\ + " [ostride=n] [count=n] [conv=[ascii] [,ebcdic][,ibm]\n"\ + " [,asciib][,ebcdicb][,ibmb][,block|unblock][,lcase|ucase]\n"\ + " [,swab][,noerror][,notrunc][,sync]]\n"\ " [oflag=[dsync][sync]]\n" /* Global references */ @@ -148,6 +149,11 @@ static off_t oseekn; /* number of output records to seek past */ static unsigned long long count; /* number of input records to copy */ /* (0 = all) */ static boolean_t ecount; /* explicit count given */ +static off_t ostriden; /* number of output blocks to skip between */ + /* records */ +static off_t istriden; /* number of input blocks to skip between */ + /* records */ + static int trantype; /* BSD or SVr4 compatible EBCDIC */ static char *string; /* command arg pointer */ @@ -569,6 +575,21 @@ main(int argc, char **argv) oseekn = number(BIG); continue; } + if (match("ostride=")) + { + ostriden = ((off_t)number(BIG)) - 1; + continue; + } + if (match("istride=")) + { + istriden = ((off_t)number(BIG)) - 1; + continue; + } + if (match("stride=")) + { + istriden = ostriden = ((off_t)number(BIG)) - 1; + continue; + } if (match("count=")) { count = number(BIG); @@ -720,6 +741,16 @@ main(int argc, char **argv) gettext("buffer sizes cannot be zero")); exit(2); } + if (ostriden == (off_t)-1) { + (void) fprintf(stderr, "dd: %s\n", + gettext("stride must be greater than zero")); + exit(2); + } + if (istriden == (off_t)-1) { + (void) fprintf(stderr, "dd: %s\n", + gettext("stride must be greater than zero")); + exit(2); + } if (conv == COPY) { if ((bs == 0) || (cflag&(LCASE|UCASE))) @@ -1035,6 +1066,12 @@ main(int argc, char **argv) ibc = read(ibf, (char *)ibuf, ibs); + if (istriden > 0 && lseek(ibf, istriden * ((off_t)ibs), + SEEK_CUR) == -1) { + perror("lseek"); + exit(2); + } + /* Process input errors */ if (ibc == (unsigned)-1) @@ -1804,7 +1841,7 @@ long long big; /* Flush the output buffer, move any excess bytes down to the beginning */ /* */ /* Arg: none */ -/* Global args: obuf, obc, obs, nofr, nopr */ +/* Global args: obuf, obc, obs, nofr, nopr, ostriden */ /* */ /* Return: Pointer to the first free byte in the output buffer. */ /* Also reset `obc' to account for moved bytes. */ @@ -1839,6 +1876,13 @@ static unsigned char "wrote %d bytes, expected %d\n"), bc, oc); term(2); } + + if (ostriden > 0 && lseek(obf, ostriden * ((off_t)obs), + SEEK_CUR) == -1) { + perror("lseek"); + exit(2); + } + obc -= oc; op = obuf; obytes += bc; diff --git a/usr/src/man/man1m/dd.1m b/usr/src/man/man1m/dd.1m index a9b8e18a60..8ae530e285 100644 --- a/usr/src/man/man1m/dd.1m +++ b/usr/src/man/man1m/dd.1m @@ -1,5 +1,6 @@ '\" te .\" Copyright (c) 2014, Joyent, Inc. All rights Reserved. +.\" Copyright (c) 2014 by Delphix. All rights reserved. .\" Copyright (c) 1992, X/Open Company Limited All Rights Reserved .\" Copyright 1989 AT&T .\" Portions Copyright (c) 1995, Sun Microsystems, Inc. All Rights Reserved @@ -10,7 +11,7 @@ .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH DD 1M "Jan 04, 2014" +.TH DD 1M "Dec 12, 2014" .SH NAME dd \- convert and copy a file .SH SYNOPSIS @@ -20,7 +21,6 @@ dd \- convert and copy a file .fi .SH DESCRIPTION -.sp .LP The \fBdd\fR utility copies the specified input file to the specified output with possible conversions. The standard input and output are used by default. @@ -54,7 +54,6 @@ character set without changing the input file's block structure. The After completion, \fBdd\fR reports the number of whole and partial input and output blocks. .SH OPERANDS -.sp .LP The following operands are supported: .sp @@ -197,6 +196,41 @@ with null bytes. On seekable files, the implementation seeks to the specified offset or reads the blocks as described for non-seekable files. .RE +.sp +.ne 2 +.na +\fB\fBostride=\fR\fIn\fR\fR +.ad +.sp .6 +.RS 4n +Writes every \fIn\fRth block (using the specified output block size) when +writing output. Skips \fIn\fR - 1 blocks after writing each record. +.RE + +.sp +.ne 2 +.na +\fB\fBistride=\fR\fIn\fR\fR +.ad +.sp .6 +.RS 4n +Reads every \fIn\fRth block (using the specified input block size) when +reading input. Skips \fIn\fR - 1 blocks after reading each record. +.RE + +.sp +.ne 2 +.na +\fB\fBstride=\fR\fIn\fR\fR +.ad +.sp .6 +.RS 4n +Reads every \fIn\fRth block (using the specified input block size) when +reading input. Skips \fIn\fR - 1 blocks after reading each record. Also +writes every \fIn\fRth block (using the specified output block size) when +writing output. Skips \fIn\fR - 1 blocks after writing each record. +.RE + .sp .ne 2 .na @@ -482,7 +516,6 @@ separated by \fBx\fR, specifying the product of the indicated values. .LP All of the operands will be processed before any input is read. .SH SIGNALS -.sp .LP When \fBdd\fR receives either SIGINFO or SIGUSR1, \fBdd\fR will emit the current input and output block counts, total bytes written, total time elapsed, and the @@ -496,7 +529,6 @@ For \fBSIGINT\fR, \fBdd\fR writes status information to standard error before exiting. \fBdd\fR takes the standard action for all other signals. .SH USAGE -.sp .LP See \fBlargefile\fR(5) for the description of the behavior of \fBdd\fR when encountering files greater than or equal to 2 Gbyte ( 2^31 bytes). @@ -560,13 +592,11 @@ example% \fBtar cvf - . | compress | dd obs=1024k of=/dev/rmt/0 conv=sync\fR .sp .SH ENVIRONMENT VARIABLES -.sp .LP See \fBenviron\fR(5) for descriptions of the following environment variables that affect the execution of \fBdd\fR: \fBLANG\fR, \fBLC_ALL\fR, \fBLC_CTYPE\fR, \fBLC_MESSAGES\fR, and \fBNLSPATH\fR. .SH EXIT STATUS -.sp .LP The following exit values are returned: .sp @@ -595,7 +625,6 @@ diagnostic message will be written, and the copy operation will be discontinued. If some other error is detected, a diagnostic message will be written and the copy operation will be discontinued. .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -611,12 +640,10 @@ Interface Stability Standard .TE .SH SEE ALSO -.sp .LP \fBcp\fR(1), \fBsed\fR(1), \fBtr\fR(1), \fBfcntl.h\fR(3HEAD), \fBattributes\fR(5), \fBenviron\fR(5), \fBlargefile\fR(5), \fBstandards\fR(5) .SH DIAGNOSTICS -.sp .ne 2 .na \fB\fBf+p records in(out)\fR\fR @@ -626,7 +653,6 @@ numbers of full and partial blocks read(written) .RE .SH NOTES -.sp .LP Do not use \fBdd\fR to copy files between file systems having different block sizes. -- cgit v1.2.3 From 4585130b259133a26efae68275dbe56b08366deb Mon Sep 17 00:00:00 2001 From: Yuri Pankov Date: Mon, 12 Jun 2017 20:16:28 -0700 Subject: 5428 provide fts(), reallocarray(), and strtonum() Reviewed by: Robert Mustacchi Approved by: Joshua M. Clulow --- usr/src/cmd/cmd-inet/usr.bin/nc/Makefile | 2 +- usr/src/cmd/cmd-inet/usr.bin/nc/THIRDPARTYLICENSE | 15 - usr/src/cmd/cmd-inet/usr.bin/nc/netcat.c | 1 - usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.c | 71 - usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.h | 31 - usr/src/cmd/mandoc/Makefile.common | 6 +- usr/src/cmd/mandoc/compat_reallocarray.c | 49 - usr/src/cmd/mandoc/compat_strtonum.c | 76 - usr/src/cmd/mdb/common/mdb/mdb_cmds.c | 3 +- usr/src/cmd/mdb/common/mdb/mdb_evset.c | 4 +- usr/src/cmd/mdb/common/mdb/mdb_lex.l | 14 +- usr/src/cmd/mdb/common/mdb/mdb_modapi.c | 4 +- usr/src/cmd/mdb/common/mdb/mdb_string.c | 4 +- usr/src/cmd/mdb/common/mdb/mdb_string.h | 4 +- usr/src/head/Makefile | 24 +- usr/src/head/fts.h | 126 + usr/src/head/stdlib.h | 2 + usr/src/lib/fm/topo/modules/common/pcibus/util.c | 12 +- usr/src/lib/fm/topo/modules/common/pcibus/util.h | 4 +- .../lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c | 6 +- usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c | 4 +- usr/src/lib/libc/amd64/Makefile | 44 +- usr/src/lib/libc/i386/Makefile.com | 48 +- usr/src/lib/libc/port/gen/fts.c | 1037 ++++++++ usr/src/lib/libc/port/gen/reallocarray.c | 37 + usr/src/lib/libc/port/gen/strtonum.c | 63 + usr/src/lib/libc/port/llib-lc | 18 +- usr/src/lib/libc/port/mapfile-vers | 11 + usr/src/lib/libc/sparc/Makefile.com | 48 +- usr/src/lib/libc/sparcv9/Makefile.com | 50 +- usr/src/man/man3c/Makefile | 2559 ++++++++++---------- usr/src/man/man3c/fts.3c | 825 +++++++ usr/src/man/man3c/malloc.3c | 525 ++-- usr/src/man/man3c/strtonum.3c | 151 ++ usr/src/pkg/manifests/system-header.mf | 3 +- usr/src/pkg/manifests/system-library.man3c.inc | 10 +- usr/src/tools/mandoc/Makefile | 9 +- usr/src/uts/common/fs/zfs/dsl_deadlist.c | 4 +- usr/src/uts/common/fs/zfs/dsl_scan.c | 2 +- usr/src/uts/common/fs/zfs/dsl_userhold.c | 2 +- usr/src/uts/common/fs/zfs/spa_errlog.c | 8 +- usr/src/uts/common/fs/zfs/spa_misc.c | 2 +- usr/src/uts/common/fs/zfs/sys/spa.h | 2 +- usr/src/uts/common/fs/zfs/zfs_vfsops.c | 2 +- 44 files changed, 4052 insertions(+), 1870 deletions(-) delete mode 100644 usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.c delete mode 100644 usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.h delete mode 100644 usr/src/cmd/mandoc/compat_reallocarray.c delete mode 100644 usr/src/cmd/mandoc/compat_strtonum.c create mode 100644 usr/src/head/fts.h create mode 100644 usr/src/lib/libc/port/gen/fts.c create mode 100644 usr/src/lib/libc/port/gen/reallocarray.c create mode 100644 usr/src/lib/libc/port/gen/strtonum.c create mode 100644 usr/src/man/man3c/fts.3c create mode 100644 usr/src/man/man3c/strtonum.3c (limited to 'usr/src') diff --git a/usr/src/cmd/cmd-inet/usr.bin/nc/Makefile b/usr/src/cmd/cmd-inet/usr.bin/nc/Makefile index e67f95d52c..b93a1c9132 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/nc/Makefile +++ b/usr/src/cmd/cmd-inet/usr.bin/nc/Makefile @@ -24,7 +24,7 @@ # PROG= nc -OBJS= atomicio.o netcat.o socks.o strtonum.o +OBJS= atomicio.o netcat.o socks.o SRCS= $(OBJS:%.o=%.c) diff --git a/usr/src/cmd/cmd-inet/usr.bin/nc/THIRDPARTYLICENSE b/usr/src/cmd/cmd-inet/usr.bin/nc/THIRDPARTYLICENSE index 24a3ba0738..5d5119c2bf 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/nc/THIRDPARTYLICENSE +++ b/usr/src/cmd/cmd-inet/usr.bin/nc/THIRDPARTYLICENSE @@ -52,18 +52,3 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Re-written nc(1) for OpenBSD. Original implementation by *Hobbit* . - -Copyright (c) 2004 Ted Unangst and Todd Miller -All rights reserved. - -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. diff --git a/usr/src/cmd/cmd-inet/usr.bin/nc/netcat.c b/usr/src/cmd/cmd-inet/usr.bin/nc/netcat.c index 13017f6e8f..435597be96 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/nc/netcat.c +++ b/usr/src/cmd/cmd-inet/usr.bin/nc/netcat.c @@ -65,7 +65,6 @@ #include #include "atomicio.h" -#include "strtonum.h" #ifndef SUN_LEN #define SUN_LEN(su) \ diff --git a/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.c b/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.c deleted file mode 100644 index 9752bb29fa..0000000000 --- a/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.c +++ /dev/null @@ -1,71 +0,0 @@ -/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ - -/* - * Copyright (c) 2004 Ted Unangst and Todd Miller - * All rights reserved. - * - * 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. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include -#include -#include - -#define INVALID 1 -#define TOOSMALL 2 -#define TOOLARGE 3 - -unsigned int -strtonum(const char *numstr, unsigned int minval, unsigned int maxval, - const char **errstrp) -{ - long long ll = 0; - char *ep; - int error = 0; - struct errval { - const char *errstr; - int err; - } ev[4] = { - { NULL, 0 }, - { "invalid", EINVAL }, - { "too small", ERANGE }, - { "too large", ERANGE }, - }; - - ev[0].err = errno; - errno = 0; - if (minval > maxval) - error = INVALID; - else { - ll = strtoll(numstr, &ep, 10); - if (numstr == ep || *ep != '\0') - error = INVALID; - else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) - error = TOOSMALL; - else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) - error = TOOLARGE; - } - if (errstrp != NULL) - *errstrp = ev[error].errstr; - errno = ev[error].err; - if (error) - ll = 0; - - /* - * we have already checked boundaries above so we can safely - * convert return type here - */ - return ((unsigned int)ll); -} diff --git a/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.h b/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.h deleted file mode 100644 index 771ebe37dd..0000000000 --- a/usr/src/cmd/cmd-inet/usr.bin/nc/strtonum.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -#ifndef _STRTONUM_H -#define _STRTONUM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -unsigned int -strtonum(const char *numstr, unsigned int minval, unsigned int maxval, - const char **errstrp); - -#endif /* _STRTONUM_H */ diff --git a/usr/src/cmd/mandoc/Makefile.common b/usr/src/cmd/mandoc/Makefile.common index a08580ca1a..c7df2d15a8 100644 --- a/usr/src/cmd/mandoc/Makefile.common +++ b/usr/src/cmd/mandoc/Makefile.common @@ -11,7 +11,7 @@ # # Copyright 2014 Garrett D'Amore -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2017 Nexenta Systems, Inc. # PROG= mandoc @@ -61,9 +61,7 @@ OBJS= att.o \ term_ps.o \ tree.o -OBJS += compat_ohash.o \ - compat_reallocarray.o \ - compat_strtonum.o +OBJS += compat_ohash.o CFLAGS += $(CC_VERBOSE) C99MODE = $(C99_ENABLE) diff --git a/usr/src/cmd/mandoc/compat_reallocarray.c b/usr/src/cmd/mandoc/compat_reallocarray.c deleted file mode 100644 index 6615190425..0000000000 --- a/usr/src/cmd/mandoc/compat_reallocarray.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "config.h" - -#if HAVE_REALLOCARRAY - -int dummy; - -#else - -/* $Id: compat_reallocarray.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */ -/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ -/* - * Copyright (c) 2008 Otto Moerbeek - * - * 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. - */ - -#include -#include -#include -#include - -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - -void * -reallocarray(void *optr, size_t nmemb, size_t size) -{ - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { - errno = ENOMEM; - return NULL; - } - return realloc(optr, size * nmemb); -} - -#endif /*!HAVE_REALLOCARRAY*/ diff --git a/usr/src/cmd/mandoc/compat_strtonum.c b/usr/src/cmd/mandoc/compat_strtonum.c deleted file mode 100644 index 628e5d51b8..0000000000 --- a/usr/src/cmd/mandoc/compat_strtonum.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "config.h" - -#if HAVE_STRTONUM - -int dummy; - -#else - -/* $Id: compat_strtonum.c,v 1.1 2015/02/16 14:56:22 schwarze Exp $ */ -/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ - -/* - * Copyright (c) 2004 Ted Unangst and Todd Miller - * All rights reserved. - * - * 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. - */ - -#include -#include -#include - -#define INVALID 1 -#define TOOSMALL 2 -#define TOOLARGE 3 - -long long -strtonum(const char *numstr, long long minval, long long maxval, - const char **errstrp) -{ - long long ll = 0; - int error = 0; - char *ep; - struct errval { - const char *errstr; - int err; - } ev[4] = { - { NULL, 0 }, - { "invalid", EINVAL }, - { "too small", ERANGE }, - { "too large", ERANGE }, - }; - - ev[0].err = errno; - errno = 0; - if (minval > maxval) { - error = INVALID; - } else { - ll = strtoll(numstr, &ep, 10); - if (numstr == ep || *ep != '\0') - error = INVALID; - else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) - error = TOOSMALL; - else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) - error = TOOLARGE; - } - if (errstrp != NULL) - *errstrp = ev[error].errstr; - errno = ev[error].err; - if (error) - ll = 0; - - return (ll); -} - -#endif /* !HAVE_STRTONUM */ diff --git a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c index f8672df76c..3b61c9ec3f 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c @@ -2785,7 +2785,8 @@ cmd_delete(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) spec.spec_base = mdb_get_dot(); else if (argv->a_type == MDB_TYPE_STRING && strcmp(argv->a_un.a_str, "all") != 0) - spec.spec_id = (int)(intmax_t)strtonum(argv->a_un.a_str, 10); + spec.spec_id = (int)(intmax_t)mdb_strtonum(argv->a_un.a_str, + 10); else if (argv->a_type == MDB_TYPE_IMMEDIATE) spec.spec_id = (int)(intmax_t)argv->a_un.a_val; diff --git a/usr/src/cmd/mdb/common/mdb/mdb_evset.c b/usr/src/cmd/mdb/common/mdb/mdb_evset.c index a30b29b6c8..864d192583 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_evset.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_evset.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -110,7 +108,7 @@ cmd_evset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } } else if (argv->a_un.a_str[0] != '-') { idv[idc++] = (int)(intmax_t) - strtonum(argv->a_un.a_str, 10); + mdb_strtonum(argv->a_un.a_str, 10); } else return (DCMD_USAGE); } else diff --git a/usr/src/cmd/mdb/common/mdb/mdb_lex.l b/usr/src/cmd/mdb/common/mdb/mdb_lex.l index eb2cc129df..b9bee245b6 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_lex.l +++ b/usr/src/cmd/mdb/common/mdb/mdb_lex.l @@ -316,7 +316,7 @@ RGX_COMMENT "//".*\n * Immediate value -- in the format list, all immediates * are assumed to be in decimal. */ - yylval.l_immediate = strtonum(yytext, 10); + yylval.l_immediate = mdb_strtonum(yytext, 10); return (MDB_TOK_IMMEDIATE); } @@ -415,7 +415,7 @@ RGX_COMMENT "//".*\n /* * Binary immediate value. */ - yylval.l_immediate = strtonum(yytext + 2, 2); + yylval.l_immediate = mdb_strtonum(yytext + 2, 2); return (MDB_TOK_IMMEDIATE); } @@ -424,7 +424,7 @@ RGX_COMMENT "//".*\n /* * Octal immediate value. */ - yylval.l_immediate = strtonum(yytext + 2, 8); + yylval.l_immediate = mdb_strtonum(yytext + 2, 8); return (MDB_TOK_IMMEDIATE); } @@ -443,7 +443,7 @@ RGX_COMMENT "//".*\n if ((p = strsplit(yytext, '.')) == NULL) yyerror("internal scanning error -- expected '.'\n"); - d = (double)strtonum(yytext + 2, 10); + d = (double)mdb_strtonum(yytext + 2, 10); for (i = 0; (c = *p++) != '\0'; i++) d = d * 10 + c - '0'; @@ -461,7 +461,7 @@ RGX_COMMENT "//".*\n /* * Decimal immediate value. */ - yylval.l_immediate = strtonum(yytext + 2, 10); + yylval.l_immediate = mdb_strtonum(yytext + 2, 10); return (MDB_TOK_IMMEDIATE); } @@ -470,7 +470,7 @@ RGX_COMMENT "//".*\n /* * Hexadecimal value. */ - yylval.l_immediate = strtonum(yytext + 2, 16); + yylval.l_immediate = mdb_strtonum(yytext + 2, 16); return (MDB_TOK_IMMEDIATE); } @@ -488,7 +488,7 @@ RGX_COMMENT "//".*\n MDB_TGT_OBJ_EVERY, yytext, &sym, NULL) == 0) yylval.l_immediate = (uintmax_t)sym.st_value; else - yylval.l_immediate = strtonum(yytext, mdb.m_radix); + yylval.l_immediate = mdb_strtonum(yytext, mdb.m_radix); return (MDB_TOK_IMMEDIATE); } diff --git a/usr/src/cmd/mdb/common/mdb/mdb_modapi.c b/usr/src/cmd/mdb/common/mdb/mdb_modapi.c index 45f161aed6..b803095843 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_modapi.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_modapi.c @@ -204,7 +204,7 @@ mdb_lookup_by_obj(const char *obj, const char *name, GElf_Sym *sym) int mdb_lookup_by_addr(uintptr_t addr, uint_t flags, char *buf, - size_t nbytes, GElf_Sym *sym) + size_t nbytes, GElf_Sym *sym) { return (mdb_tgt_lookup_by_addr(mdb.m_target, addr, flags, buf, nbytes, sym, NULL)); @@ -246,7 +246,7 @@ mdb_strtoull(const char *s) } } - return (strtonum(s, radix)); + return (mdb_strtonum(s, radix)); } size_t diff --git a/usr/src/cmd/mdb/common/mdb/mdb_string.c b/usr/src/cmd/mdb/common/mdb/mdb_string.c index fc91b2c5e4..fbcfe82755 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_string.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_string.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -110,7 +108,7 @@ numtostr(uintmax_t uvalue, int base, uint_t flags) * error message and longjmp back to the main loop using yyerror(). */ uintmax_t -strtonum(const char *s, int base) +mdb_strtonum(const char *s, int base) { uintmax_t multmax = (uintmax_t)ULLONG_MAX / (uintmax_t)(uint_t)base; uintmax_t val = 0; diff --git a/usr/src/cmd/mdb/common/mdb/mdb_string.h b/usr/src/cmd/mdb/common/mdb/mdb_string.h index 2373103423..d07b9a48da 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_string.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_string.h @@ -27,8 +27,6 @@ #ifndef _MDB_STRING_H #define _MDB_STRING_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include @@ -42,7 +40,7 @@ extern "C" { #define NTOS_SHOWBASE 0x8 /* Show base under appropriate circumstances */ extern const char *numtostr(uintmax_t, int, uint_t); -extern uintmax_t strtonum(const char *, int); +extern uintmax_t mdb_strtonum(const char *, int); extern ulong_t strntoul(const char *, size_t, int); extern int strisnum(const char *); extern int strisbasenum(const char *); diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile index e6397736af..e5cd6e1ef0 100644 --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -24,26 +24,29 @@ # Use is subject to license terms. # Copyright 2013 Garrett D'Amore # Copyright 2015 Igor Kozhukhov -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2017 Nexenta Systems, Inc. # -# -# head/Makefile -# # include global definitions include ../Makefile.master sparc_HDRS= i386_HDRS= stack_unwind.h -# Headers are listed one per line so that TeamWare can auto-merge most changes - -KRB5HDRS= mit_copyright.h mit-sipb-copyright.h +KRB5HDRS= \ + mit_copyright.h \ + mit-sipb-copyright.h -ATTRDB_HDRS= secdb.h auth_attr.h exec_attr.h prof_attr.h user_attr.h \ - auth_list.h +ATTRDB_HDRS= \ + auth_attr.h \ + auth_list.h \ + exec_attr.h \ + prof_attr.h \ + secdb.h \ + user_attr.h -HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \ +HDRS= $($(MACH)_HDRS) \ + $(ATTRDB_HDRS) \ aio.h \ alloca.h \ apptrace.h \ @@ -81,6 +84,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \ floatingpoint.h \ fmtmsg.h \ fnmatch.h \ + fts.h \ ftw.h \ gelf.h \ getopt.h \ diff --git a/usr/src/head/fts.h b/usr/src/head/fts.h new file mode 100644 index 0000000000..dc84d88183 --- /dev/null +++ b/usr/src/head/fts.h @@ -0,0 +1,126 @@ +/* + * 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. + * 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. + */ + +#ifndef _FTS_H +#define _FTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + size_t fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ + int (*fts_compar)(); /* compare function */ + +#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x0002 /* logical walk */ +#define FTS_NOCHDIR 0x0004 /* don't change directories */ +#define FTS_NOSTAT 0x0008 /* don't get stat info */ +#define FTS_PHYSICAL 0x0010 /* physical walk */ +#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */ +#define FTS_XDEV 0x0040 /* don't cross devices */ +#define FTS_OPTIONMASK 0x00ff /* valid user option mask */ + +#define FTS_NAMEONLY 0x1000 /* (private) child names only */ +#define FTS_STOP 0x2000 /* (private) unrecoverable error */ + int fts_options; /* fts_open options, global flags */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink */ + size_t fts_pathlen; /* strlen(fts_path) */ + size_t fts_namelen; /* strlen(fts_name) */ + + ino_t fts_ino; /* inode */ + dev_t fts_dev; /* device */ + nlink_t fts_nlink; /* link count */ + +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 +#define FTS_MAXLEVEL 0x7fffffff + int fts_level; /* depth (-1 to N) */ + +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ + unsigned short fts_info; /* user flags for FTSENT structure */ + +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ + unsigned short fts_flags; /* private flags for FTSENT structure */ + +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + unsigned short fts_instr; /* fts_set() instructions */ + + unsigned short fts_spare; /* unused */ + + struct stat *fts_statp; /* stat(2) information */ + char fts_name[1]; /* file name */ +} FTSENT; + +FTSENT *fts_children(FTS *, int); +int fts_close(FTS *); +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)); +FTSENT *fts_read(FTS *); +int fts_set(FTS *, FTSENT *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* !_FTS_H */ diff --git a/usr/src/head/stdlib.h b/usr/src/head/stdlib.h index 94eaab38fa..47b87d9ff5 100644 --- a/usr/src/head/stdlib.h +++ b/usr/src/head/stdlib.h @@ -290,6 +290,8 @@ extern char *ulltostr(unsigned long long, char *); extern uint32_t arc4random(void); extern void arc4random_buf(void *, size_t); extern uint32_t arc4random_uniform(uint32_t); +extern void *reallocarray(void *, size_t, size_t); +extern long long strtonum(const char *, long long, long long, const char **); #endif /* !_STRICT_SYBMOLS */ diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/util.c b/usr/src/lib/fm/topo/modules/common/pcibus/util.c index cab50058ff..7d1edae6cf 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/util.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/util.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -50,7 +48,7 @@ child_range_add(topo_mod_t *mp, tnode_t *tn, const char *cnm, } ulong_t -strtonum(topo_mod_t *mp, char *str, int *err) +fm_strtonum(topo_mod_t *mp, char *str, int *err) { ulong_t r; char *e; @@ -74,17 +72,17 @@ get_pci_vpd_sn_pn(topo_mod_t *mp, di_node_t dn, char **serial, char **part) if ((promtree = topo_mod_prominfo(mp)) == DI_PROM_HANDLE_NIL) { topo_mod_dprintf(mp, - "get vpd data: di_prom_handle_init failed.\n"); + "get vpd data: di_prom_handle_init failed.\n"); return (-1); } /* Get Serial Number and Part Number */ if ((di_prom_prop_lookup_bytes(promtree, dn, "vpd-serial-number", - (uchar_t **)&s) > 0) && (s != NULL)) + (uchar_t **)&s) > 0) && (s != NULL)) *serial = topo_mod_strdup(mp, s); if ((di_prom_prop_lookup_bytes(promtree, dn, "vpd-part-number", - (uchar_t **)&p) > 0) && (p != NULL)) + (uchar_t **)&p) > 0) && (p != NULL)) *part = topo_mod_strdup(mp, p); return (0); @@ -109,7 +107,7 @@ tnode_create(topo_mod_t *mp, tnode_t *parent, (void) get_pci_vpd_sn_pn(mp, priv, &serial, &part); fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name, i, NULL, - auth, part, NULL, serial); + auth, part, NULL, serial); nvlist_free(auth); topo_mod_strfree(mp, serial); topo_mod_strfree(mp, part); diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/util.h b/usr/src/lib/fm/topo/modules/common/pcibus/util.h index 8dda2b6304..60a72d09f4 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/util.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/util.h @@ -27,8 +27,6 @@ #ifndef _UTIL_H #define _UTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include #ifdef __cplusplus @@ -39,7 +37,7 @@ extern int child_range_add(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t); extern int labelmethod_inherit(topo_mod_t *, tnode_t *, nvlist_t *, nvlist_t **); -extern ulong_t strtonum(topo_mod_t *, char *, int *); +extern ulong_t fm_strtonum(topo_mod_t *, char *, int *); extern tnode_t *tnode_create(topo_mod_t *, tnode_t *, const char *, topo_instance_t, void *); diff --git a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c index 7494152283..700058c9a5 100644 --- a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c +++ b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -52,7 +50,7 @@ busorrc_new(topo_mod_t *mod, const char *bus_addr, di_node_t di) bac = topo_mod_strdup(mod, bus_addr); if ((comma = strchr(bac, ',')) != NULL) *comma = '\0'; - pp->br_ba_bc = strtonum(mod, bac, &e); + pp->br_ba_bc = fm_strtonum(mod, bac, &e); if (e < 0) { topo_mod_dprintf(mod, "Trouble interpreting bus_addr before comma.\n"); @@ -67,7 +65,7 @@ busorrc_new(topo_mod_t *mod, const char *bus_addr, di_node_t di) topo_mod_strfree(mod, bac); return (pp); } - pp->br_ba_ac = strtonum(mod, comma + 1, &e); + pp->br_ba_ac = fm_strtonum(mod, comma + 1, &e); if (e < 0) { topo_mod_dprintf(mod, "Trouble interpreting bus_addr after comma.\n"); diff --git a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c index ad5bc5dcad..70f1108f1b 100644 --- a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c +++ b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c @@ -239,7 +239,7 @@ split_bus_address(topo_mod_t *mod, di_node_t dp, uint_t baseaddr, return (NULL); } *comma = '\0'; - bc = strtonum(mod, bac, &e); + bc = fm_strtonum(mod, bac, &e); *comma = ','; if (e < 0) { topo_mod_dprintf(mod, @@ -247,7 +247,7 @@ split_bus_address(topo_mod_t *mod, di_node_t dp, uint_t baseaddr, topo_mod_strfree(mod, bac); return (NULL); } - ac = strtonum(mod, comma + 1, &e); + ac = fm_strtonum(mod, comma + 1, &e); if (e < 0) { topo_mod_dprintf(mod, "Trouble interpreting %s after comma.\n", bac); diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index e77dd63255..8cee9dee02 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -18,14 +18,13 @@ # # CDDL HEADER END # + # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2016 Joyent, Inc. -# # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore -# Copyright 2011 Nexenta Systems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright 2017 Nexenta Systems, Inc. # LIBCBASE= . @@ -350,13 +349,13 @@ PORTGEN= \ ascii_strcasecmp.o \ ascii_strncasecmp.o \ assert.o \ + atexit.o \ + atfork.o \ atof.o \ atoi.o \ atol.o \ atoll.o \ attropen.o \ - atexit.o \ - atfork.o \ basename.o \ calloc.o \ catgets.o \ @@ -398,8 +397,10 @@ PORTGEN= \ fmtmsg.o \ ftime.o \ ftok.o \ + fts.o \ ftw.o \ gcvt.o \ + get_nprocs.o \ getauxv.o \ getcwd.o \ getdate_err.o \ @@ -417,7 +418,6 @@ PORTGEN= \ getlogin.o \ getmntent.o \ getnetgrent.o \ - get_nprocs.o \ getopt.o \ getopt_long.o \ getpagesize.o \ @@ -498,8 +498,8 @@ PORTGEN= \ posix_madvise.o \ posix_memalign.o \ priocntl.o \ - privlib.o \ priv_str_xlate.o \ + privlib.o \ psecflags.o \ psiginfo.o \ psignal.o \ @@ -512,6 +512,7 @@ PORTGEN= \ rctlops.o \ readdir.o \ readdir_r.o \ + reallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ @@ -555,6 +556,7 @@ PORTGEN= \ strtoimax.o \ strtok.o \ strtok_r.o \ + strtonum.o \ strtoumax.o \ swab.o \ swapctl.o \ @@ -1088,24 +1090,24 @@ SRCS= \ $(ATOMICOBJS:%.o=$(SRC)/common/atomic/%.c) \ $(XATTROBJS:%.o=$(SRC)/common/xattr/%.c) \ $(COMOBJS:%.o=$(SRC)/common/util/%.c) \ - $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ - $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ - $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ - $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ - $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ - $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ - $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ - $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ - $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ - $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ - $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ - $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ - $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ + $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ + $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ + $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ + $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ + $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ + $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ + $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ + $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ + $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ + $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ + $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ + $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ $(THREADSMACHOBJS:%.o=threads/%.c) \ $(UNICODEOBJS:%.o=$(SRC)/common/unicode/%.c) \ $(UNWINDMACHOBJS:%.o=unwind/%.c) \ $(FPOBJS:%.o=fp/%.c) \ - $(I386FPOBJS:%.o=$(LIBCDIR)/i386/fp/%.c) \ + $(I386FPOBJS:%.o=$(LIBCDIR)/i386/fp/%.c) \ $(LIBCBASE)/gen/ecvt.c \ $(LIBCBASE)/gen/makectxt.c \ $(LIBCBASE)/gen/siginfolst.c \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 4d24e7f176..0a879e1508 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -18,14 +18,13 @@ # # CDDL HEADER END # + # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2016 Joyent, Inc. # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore -# -# Copyright 2011 Nexenta Systems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright 2017 Nexenta Systems, Inc. # LIBCDIR= $(SRC)/lib/libc @@ -385,14 +384,14 @@ PORTGEN= \ ascii_strcasecmp.o \ ascii_strncasecmp.o \ assert.o \ + atexit.o \ + atfork.o \ atof.o \ atoi.o \ atol.o \ atoll.o \ attrat.o \ attropen.o \ - atexit.o \ - atfork.o \ basename.o \ calloc.o \ catgets.o \ @@ -434,8 +433,10 @@ PORTGEN= \ fmtmsg.o \ ftime.o \ ftok.o \ + fts.o \ ftw.o \ gcvt.o \ + get_nprocs.o \ getauxv.o \ getcwd.o \ getdate_err.o \ @@ -453,7 +454,6 @@ PORTGEN= \ getlogin.o \ getmntent.o \ getnetgrent.o \ - get_nprocs.o \ getopt.o \ getopt_long.o \ getpagesize.o \ @@ -534,8 +534,8 @@ PORTGEN= \ posix_madvise.o \ posix_memalign.o \ priocntl.o \ - privlib.o \ priv_str_xlate.o \ + privlib.o \ psecflags.o \ psiginfo.o \ psignal.o \ @@ -548,6 +548,7 @@ PORTGEN= \ rctlops.o \ readdir.o \ readdir_r.o \ + reallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ @@ -587,6 +588,7 @@ PORTGEN= \ strtoimax.o \ strtok.o \ strtok_r.o \ + strtonum.o \ strtoumax.o \ swab.o \ swapctl.o \ @@ -1151,23 +1153,23 @@ SRCS= \ $(XATTROBJS:%.o=$(SRC)/common/xattr/%.c) \ $(COMOBJS:%.o=$(SRC)/common/util/%.c) \ $(DTRACEOBJS:%.o=$(SRC)/common/dtrace/%.c) \ - $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ - $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ - $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ - $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ - $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ - $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ - $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ - $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ - $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ - $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ - $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ - $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ - $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ - $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ + $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ + $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ + $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ + $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ + $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ + $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ + $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ + $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ + $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ + $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ + $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ + $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ + $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ $(UNICODEOBJS:%.o=$(SRC)/common/unicode/%.c) \ - $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ - $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ + $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ + $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ $(LIBCBASE)/gen/ecvt.c \ $(LIBCBASE)/gen/makectxt.c \ $(LIBCBASE)/gen/siginfolst.c \ diff --git a/usr/src/lib/libc/port/gen/fts.c b/usr/src/lib/libc/port/gen/fts.c new file mode 100644 index 0000000000..eac375ee6a --- /dev/null +++ b/usr/src/lib/libc/port/gen/fts.c @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 1990, 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) + +#define ALIGNBYTES _POINTER_ALIGNMENT +#define ALIGN(p) (((unsigned long)(p) + ALIGNBYTES) & ~ALIGNBYTES) + +static FTSENT *fts_alloc(FTS *, char *, size_t); +static FTSENT *fts_build(FTS *, int); +static void fts_lfree(FTSENT *); +static void fts_load(FTS *, FTSENT *); +static size_t fts_maxarglen(char * const *); +static void fts_padjust(FTS *, FTSENT *); +static int fts_palloc(FTS *, size_t); +static FTSENT *fts_sort(FTS *, FTSENT *, int); +static ushort_t fts_stat(FTS *, FTSENT *, int, int); +static int fts_safe_changedir(FTS *, FTSENT *, int, char *); + +#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) + +#define CLR(opt) (sp->fts_options &= ~(opt)) +#define ISSET(opt) (sp->fts_options & (opt)) +#define SET(opt) (sp->fts_options |= (opt)) + +#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) + +/* fts_build flags */ +#define BCHILD 1 /* fts_children */ +#define BNAMES 2 /* fts_children, names only */ +#define BREAD 3 /* fts_read */ + +FTS * +fts_open(char * const *argv, int options, + int (*compar)(const FTSENT **, const FTSENT **)) +{ + FTS *sp; + FTSENT *p, *root; + int nitems; + FTSENT *parent, *prev; + + /* Options check. */ + if (options & ~FTS_OPTIONMASK) { + errno = EINVAL; + return (NULL); + } + + /* At least one path must be specified. */ + if (*argv == NULL) { + errno = EINVAL; + return (NULL); + } + + /* Allocate/initialize the stream */ + if ((sp = calloc(1, sizeof (FTS))) == NULL) + return (NULL); + sp->fts_compar = compar; + sp->fts_options = options; + + /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ + if (ISSET(FTS_LOGICAL)) + SET(FTS_NOCHDIR); + + /* + * Start out with 1K of path space, and enough, in any case, + * to hold the user's paths. + */ + if (fts_palloc(sp, MAXIMUM(fts_maxarglen(argv), PATH_MAX))) + goto mem1; + + /* Allocate/initialize root's parent. */ + if ((parent = fts_alloc(sp, "", 0)) == NULL) + goto mem2; + parent->fts_level = FTS_ROOTPARENTLEVEL; + + /* Allocate/initialize root(s). */ + for (root = prev = NULL, nitems = 0; *argv; ++argv, ++nitems) { + if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) + goto mem3; + p->fts_level = FTS_ROOTLEVEL; + p->fts_parent = parent; + p->fts_accpath = p->fts_name; + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); + + /* Command-line "." and ".." are real directories. */ + if (p->fts_info == FTS_DOT) + p->fts_info = FTS_D; + + /* + * If comparison routine supplied, traverse in sorted + * order; otherwise traverse in the order specified. + */ + if (compar) { + p->fts_link = root; + root = p; + } else { + p->fts_link = NULL; + if (root == NULL) + root = p; + else + prev->fts_link = p; + prev = p; + } + } + if (compar && nitems > 1) + root = fts_sort(sp, root, nitems); + + /* + * Allocate a dummy pointer and make fts_read think that we've just + * finished the node before the root(s); set p->fts_info to FTS_INIT + * so that everything about the "current" node is ignored. + */ + if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) + goto mem3; + sp->fts_cur->fts_link = root; + sp->fts_cur->fts_info = FTS_INIT; + + /* + * If using chdir(2), grab a file descriptor pointing to dot to ensure + * that we can get back here; this could be avoided for some paths, + * but almost certainly not worth the effort. Slashes, symbolic links, + * and ".." are all fairly nasty problems. Note, if we can't get the + * descriptor we run anyway, just more slowly. + */ + if (!ISSET(FTS_NOCHDIR) && + (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0) + SET(FTS_NOCHDIR); + + if (nitems == 0) + free(parent); + + return (sp); + +mem3: fts_lfree(root); + free(parent); +mem2: free(sp->fts_path); +mem1: free(sp); + return (NULL); +} + +static void +fts_load(FTS *sp, FTSENT *p) +{ + size_t len; + char *cp; + + /* + * Load the stream structure for the next traversal. Since we don't + * actually enter the directory until after the preorder visit, set + * the fts_accpath field specially so the chdir gets done to the right + * place and the user can access the first node. From fts_open it's + * known that the path will fit. + */ + len = p->fts_pathlen = p->fts_namelen; + (void) memmove(sp->fts_path, p->fts_name, len + 1); + if (((cp = strrchr(p->fts_name, '/')) != NULL) && + (cp != p->fts_name || cp[1])) { + len = strlen(++cp); + (void) memmove(p->fts_name, cp, len + 1); + p->fts_namelen = len; + } + p->fts_accpath = p->fts_path = sp->fts_path; + sp->fts_dev = p->fts_dev; +} + +int +fts_close(FTS *sp) +{ + FTSENT *freep, *p; + int rfd, error = 0; + + /* + * This still works if we haven't read anything -- the dummy structure + * points to the root list, so we step through to the end of the root + * list which has a valid parent pointer. + */ + if (sp->fts_cur) { + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL; ) { + freep = p; + p = p->fts_link ? p->fts_link : p->fts_parent; + free(freep); + } + free(p); + } + + /* Stash the original directory fd if needed. */ + rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd; + + /* Free up child linked list, sort array, path buffer, stream ptr. */ + if (sp->fts_child) + fts_lfree(sp->fts_child); + free(sp->fts_array); + free(sp->fts_path); + free(sp); + + /* Return to original directory, checking for error. */ + if (rfd != -1) { + int saved_errno; + error = fchdir(rfd); + saved_errno = errno; + (void) close(rfd); + errno = saved_errno; + } + + return (error); +} + +/* + * Special case of "/" at the end of the path so that slashes aren't + * appended which would cause paths to be written as "....//foo". + */ +#define NAPPEND(p) \ + (p->fts_path[p->fts_pathlen - 1] == '/' \ + ? p->fts_pathlen - 1 : p->fts_pathlen) + +FTSENT * +fts_read(FTS *sp) +{ + FTSENT *p, *tmp; + int instr; + char *t; + int saved_errno; + + /* If finished or unrecoverable error, return NULL. */ + if (sp->fts_cur == NULL || ISSET(FTS_STOP)) + return (NULL); + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* Save and zero out user instructions. */ + instr = p->fts_instr; + p->fts_instr = FTS_NOINSTR; + + /* Any type of file may be re-visited; re-stat and re-turn. */ + if (instr == FTS_AGAIN) { + p->fts_info = fts_stat(sp, p, 0, -1); + return (p); + } + + /* + * Following a symlink -- SLNONE test allows application to see + * SLNONE and recover. If indirecting through a symlink, have + * keep a pointer to current location. If unable to get that + * pointer, follow fails. + */ + if (instr == FTS_FOLLOW && + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { + p->fts_info = fts_stat(sp, p, 1, -1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { + if ((p->fts_symfd = + open(".", O_RDONLY | O_CLOEXEC)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + } + return (p); + } + + /* Directory in pre-order. */ + if (p->fts_info == FTS_D) { + /* If skipped or crossed mount point, do post-order visit. */ + if (instr == FTS_SKIP || + (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { + if (p->fts_flags & FTS_SYMFOLLOW) + (void) close(p->fts_symfd); + if (sp->fts_child) { + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + p->fts_info = FTS_DP; + return (p); + } + + /* Rebuild if only read the names and now traversing. */ + if (sp->fts_child && ISSET(FTS_NAMEONLY)) { + CLR(FTS_NAMEONLY); + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + + /* + * Cd to the subdirectory. + * + * If have already read and now fail to chdir, whack the list + * to make the names come out right, and set the parent errno + * so the application will eventually get an error condition. + * Set the FTS_DONTCHDIR flag so that when we logically change + * directories back to the parent we don't do a chdir. + * + * If haven't read do so. If the read fails, fts_build sets + * FTS_STOP or the fts_info field of the node. + */ + if (sp->fts_child) { + if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { + p->fts_errno = errno; + p->fts_flags |= FTS_DONTCHDIR; + for (p = sp->fts_child; p; p = p->fts_link) + p->fts_accpath = + p->fts_parent->fts_accpath; + } + } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { + if (ISSET(FTS_STOP)) + return (NULL); + return (p); + } + p = sp->fts_child; + sp->fts_child = NULL; + goto name; + } + + /* Move to the next node on this level. */ +next: tmp = p; + if ((p = p->fts_link) != NULL) { + free(tmp); + + /* + * If reached the top, return to the original directory (or + * the root of the tree), and load the paths for the next root. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + return (NULL); + } + fts_load(sp, p); + return (sp->fts_cur = p); + } + + /* + * User may have called fts_set on the node. If skipped, + * ignore. If followed, get a file descriptor so we can + * get back if necessary. + */ + if (p->fts_instr == FTS_SKIP) + goto next; + if (p->fts_instr == FTS_FOLLOW) { + p->fts_info = fts_stat(sp, p, 1, -1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { + if ((p->fts_symfd = + open(".", O_RDONLY | O_CLOEXEC)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + } + p->fts_instr = FTS_NOINSTR; + } + +name: t = sp->fts_path + NAPPEND(p->fts_parent); + *t++ = '/'; + (void) memmove(t, p->fts_name, p->fts_namelen + 1); + return (sp->fts_cur = p); + } + + /* Move up to the parent node. */ + p = tmp->fts_parent; + free(tmp); + + if (p->fts_level == FTS_ROOTPARENTLEVEL) { + /* + * Done; free everything up and set errno to 0 so the user + * can distinguish between error and EOF. + */ + free(p); + errno = 0; + return (sp->fts_cur = NULL); + } + + /* NUL terminate the pathname. */ + sp->fts_path[p->fts_pathlen] = '\0'; + + /* + * Return to the parent directory. If at a root node or came through + * a symlink, go back through the file descriptor. Otherwise, cd up + * one directory. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + sp->fts_cur = p; + return (NULL); + } + } else if (p->fts_flags & FTS_SYMFOLLOW) { + if (FCHDIR(sp, p->fts_symfd)) { + saved_errno = errno; + (void) close(p->fts_symfd); + errno = saved_errno; + SET(FTS_STOP); + sp->fts_cur = p; + return (NULL); + } + (void) close(p->fts_symfd); + } else if (!(p->fts_flags & FTS_DONTCHDIR) && + fts_safe_changedir(sp, p->fts_parent, -1, "..")) { + SET(FTS_STOP); + sp->fts_cur = p; + return (NULL); + } + p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; + return (sp->fts_cur = p); +} + +/* + * Fts_set takes the stream as an argument although it's not used in this + * implementation; it would be necessary if anyone wanted to add global + * semantics to fts using fts_set. An error return is allowed for similar + * reasons. + */ +/*ARGSUSED*/ +int +fts_set(FTS *sp, FTSENT *p, int instr) +{ + if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && + instr != FTS_NOINSTR && instr != FTS_SKIP) { + errno = EINVAL; + return (1); + } + p->fts_instr = instr; + return (0); +} + +FTSENT * +fts_children(FTS *sp, int instr) +{ + FTSENT *p; + int fd; + + if (instr && instr != FTS_NAMEONLY) { + errno = EINVAL; + return (NULL); + } + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* + * Errno set to 0 so user can distinguish empty directory from + * an error. + */ + errno = 0; + + /* Fatal errors stop here. */ + if (ISSET(FTS_STOP)) + return (NULL); + + /* Return logical hierarchy of user's arguments. */ + if (p->fts_info == FTS_INIT) + return (p->fts_link); + + /* + * If not a directory being visited in pre-order, stop here. Could + * allow FTS_DNR, assuming the user has fixed the problem, but the + * same effect is available with FTS_AGAIN. + */ + if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) + return (NULL); + + /* Free up any previous child list. */ + if (sp->fts_child) + fts_lfree(sp->fts_child); + + if (instr == FTS_NAMEONLY) { + SET(FTS_NAMEONLY); + instr = BNAMES; + } else + instr = BCHILD; + + /* + * If using chdir on a relative path and called BEFORE fts_read does + * its chdir to the root of a traversal, we can lose -- we need to + * chdir into the subdirectory, and we don't know where the current + * directory is, so we can't get back so that the upcoming chdir by + * fts_read will work. + */ + if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || + ISSET(FTS_NOCHDIR)) + return (sp->fts_child = fts_build(sp, instr)); + + if ((fd = open(".", O_RDONLY | O_CLOEXEC)) < 0) + return (NULL); + sp->fts_child = fts_build(sp, instr); + if (fchdir(fd)) { + (void) close(fd); + return (NULL); + } + (void) close(fd); + return (sp->fts_child); +} + +/* + * This is the tricky part -- do not casually change *anything* in here. The + * idea is to build the linked list of entries that are used by fts_children + * and fts_read. There are lots of special cases. + * + * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is + * set and it's a physical walk (so that symbolic links can't be directories), + * we can do things quickly. First, if it's a 4.4BSD file system, the type + * of the file is in the directory entry. Otherwise, we assume that the number + * of subdirectories in a node is equal to the number of links to the parent. + * The former skips all stat calls. The latter skips stat calls in any leaf + * directories and for any files after the subdirectories in the directory have + * been found, cutting the stat calls by about 2/3. + */ +static FTSENT * +fts_build(FTS *sp, int type) +{ + struct dirent *dp; + FTSENT *p, *head; + FTSENT *cur, *tail; + DIR *dirp; + void *oldaddr; + size_t len, maxlen; + int nitems, cderrno, descend, level, nlinks, doadjust; + int saved_errno; + char *cp; + + /* Set current node pointer. */ + cur = sp->fts_cur; + + /* + * Open the directory for reading. If this fails, we're done. + * If being called from fts_read, set the fts_info field. + */ + if ((dirp = opendir(cur->fts_accpath)) == NULL) { + if (type == BREAD) { + cur->fts_info = FTS_DNR; + cur->fts_errno = errno; + } + return (NULL); + } + + /* + * Nlinks is the number of possible entries of type directory in the + * directory if we're cheating on stat calls, 0 if we're not doing + * any stat calls at all, -1 if we're doing stats on everything. + */ + if (type == BNAMES) + nlinks = 0; + else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) + nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); + else + nlinks = -1; + + /* + * If we're going to need to stat anything or we want to descend + * and stay in the directory, chdir. If this fails we keep going, + * but set a flag so we don't chdir after the post-order visit. + * We won't be able to stat anything, but we can still return the + * names themselves. Note, that since fts_read won't be able to + * chdir into the directory, it will have to return different path + * names than before, i.e. "a/b" instead of "b". Since the node + * has already been visited in pre-order, have to wait until the + * post-order visit to return the error. There is a special case + * here, if there was nothing to stat then it's not an error to + * not be able to stat. This is all fairly nasty. If a program + * needed sorted entries or stat information, they had better be + * checking FTS_NS on the returned nodes. + */ + cderrno = 0; + if (nlinks || type == BREAD) { + if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) { + if (nlinks && type == BREAD) + cur->fts_errno = errno; + cur->fts_flags |= FTS_DONTCHDIR; + descend = 0; + cderrno = errno; + (void) closedir(dirp); + dirp = NULL; + } else + descend = 1; + } else + descend = 0; + + /* + * Figure out the max file name length that can be stored in the + * current path -- the inner loop allocates more path as necessary. + * We really wouldn't have to do the maxlen calculations here, we + * could do them in fts_read before returning the path, but it's a + * lot easier here since the length is part of the dirent structure. + * + * If not changing directories set a pointer so that can just append + * each new name into the path. + */ + len = NAPPEND(cur); + if (ISSET(FTS_NOCHDIR)) { + cp = sp->fts_path + len; + *cp++ = '/'; + } + len++; + maxlen = sp->fts_pathlen - len; + + /* + * fts_level is signed so we must prevent it from wrapping + * around to FTS_ROOTLEVEL and FTS_ROOTPARENTLEVEL. + */ + level = cur->fts_level; + if (level < FTS_MAXLEVEL) + level++; + + /* Read the directory, attaching each entry to the `link' pointer. */ + doadjust = 0; + for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp)); ) { + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) + continue; + + if (!(p = fts_alloc(sp, dp->d_name, strlen(dp->d_name)))) + goto mem1; + if (strlen(dp->d_name) >= maxlen) { /* include space for NUL */ + oldaddr = sp->fts_path; + if (fts_palloc(sp, strlen(dp->d_name) +len + 1)) { + /* + * No more memory for path or structures. Save + * errno, free up the current structure and the + * structures already allocated. + */ +mem1: saved_errno = errno; + free(p); + fts_lfree(head); + (void) closedir(dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + errno = saved_errno; + return (NULL); + } + /* Did realloc() change the pointer? */ + if (oldaddr != sp->fts_path) { + doadjust = 1; + if (ISSET(FTS_NOCHDIR)) + cp = sp->fts_path + len; + } + maxlen = sp->fts_pathlen - len; + } + + p->fts_level = level; + p->fts_parent = sp->fts_cur; + p->fts_pathlen = len + strlen(dp->d_name); + if (p->fts_pathlen < len) { + /* + * If we wrap, free up the current structure and + * the structures already allocated, then error + * out with ENAMETOOLONG. + */ + free(p); + fts_lfree(head); + (void) closedir(dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + errno = ENAMETOOLONG; + return (NULL); + } + + if (cderrno) { + if (nlinks) { + p->fts_info = FTS_NS; + p->fts_errno = cderrno; + } else + p->fts_info = FTS_NSOK; + p->fts_accpath = cur->fts_accpath; + } else if (nlinks == 0) { + p->fts_accpath = + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; + p->fts_info = FTS_NSOK; + } else { + /* Build a file name for fts_stat to stat. */ + if (ISSET(FTS_NOCHDIR)) { + p->fts_accpath = p->fts_path; + (void) memmove(cp, p->fts_name, + p->fts_namelen + 1); + p->fts_info = fts_stat(sp, p, 0, dirfd(dirp)); + } else { + p->fts_accpath = p->fts_name; + p->fts_info = fts_stat(sp, p, 0, -1); + } + + /* Decrement link count if applicable. */ + if (nlinks > 0 && (p->fts_info == FTS_D || + p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) + --nlinks; + } + + /* We walk in directory order so "ls -f" doesn't get upset. */ + p->fts_link = NULL; + if (head == NULL) + head = tail = p; + else { + tail->fts_link = p; + tail = p; + } + ++nitems; + } + if (dirp) + (void) closedir(dirp); + + /* + * If realloc() changed the address of the path, adjust the + * addresses for the rest of the tree and the dir list. + */ + if (doadjust) + fts_padjust(sp, head); + + /* + * If not changing directories, reset the path back to original + * state. + */ + if (ISSET(FTS_NOCHDIR)) { + if (len == sp->fts_pathlen || nitems == 0) + --cp; + *cp = '\0'; + } + + /* + * If descended after called from fts_children or after called from + * fts_read and nothing found, get back. At the root level we use + * the saved fd; if one of fts_open()'s arguments is a relative path + * to an empty directory, we wind up here with no other way back. If + * can't get back, we're done. + */ + if (descend && (type == BCHILD || !nitems) && + (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : + fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + return (NULL); + } + + /* If didn't find anything, return NULL. */ + if (!nitems) { + if (type == BREAD) + cur->fts_info = FTS_DP; + return (NULL); + } + + /* Sort the entries. */ + if (sp->fts_compar && nitems > 1) + head = fts_sort(sp, head, nitems); + return (head); +} + +static ushort_t +fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) +{ + FTSENT *t; + dev_t dev; + ino_t ino; + struct stat *sbp, sb; + int saved_errno; + const char *path; + + if (dfd == -1) { + path = p->fts_accpath; + dfd = AT_FDCWD; + } else + path = p->fts_name; + + /* If user needs stat info, stat buffer already allocated. */ + sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; + + /* + * If doing a logical walk, or application requested FTS_FOLLOW, do + * a stat(2). If that fails, check for a non-existent symlink. If + * fail, set the errno from the stat call. + */ + if (ISSET(FTS_LOGICAL) || follow) { + if (fstatat(dfd, path, sbp, 0)) { + saved_errno = errno; + if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { + errno = 0; + return (FTS_SLNONE); + } + p->fts_errno = saved_errno; + goto err; + } + } else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { + p->fts_errno = errno; +err: (void) memset(sbp, 0, sizeof (struct stat)); + return (FTS_NS); + } + + if (S_ISDIR(sbp->st_mode)) { + /* + * Set the device/inode. Used to find cycles and check for + * crossing mount points. Also remember the link count, used + * in fts_build to limit the number of stat calls. It is + * understood that these fields are only referenced if fts_info + * is set to FTS_D. + */ + dev = p->fts_dev = sbp->st_dev; + ino = p->fts_ino = sbp->st_ino; + p->fts_nlink = sbp->st_nlink; + + if (ISDOT(p->fts_name)) + return (FTS_DOT); + + /* + * Cycle detection is done by brute force when the directory + * is first encountered. If the tree gets deep enough or the + * number of symbolic links to directories is high enough, + * something faster might be worthwhile. + */ + for (t = p->fts_parent; + t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) + if (ino == t->fts_ino && dev == t->fts_dev) { + p->fts_cycle = t; + return (FTS_DC); + } + return (FTS_D); + } + if (S_ISLNK(sbp->st_mode)) + return (FTS_SL); + if (S_ISREG(sbp->st_mode)) + return (FTS_F); + return (FTS_DEFAULT); +} + +static FTSENT * +fts_sort(FTS *sp, FTSENT *head, int nitems) +{ + FTSENT **ap, *p; + + /* + * Construct an array of pointers to the structures and call qsort(3). + * Reassemble the array in the order returned by qsort. If unable to + * sort for memory reasons, return the directory entries in their + * current order. Allocate enough space for the current needs plus + * 40 so don't realloc one entry at a time. + */ + if (nitems > sp->fts_nitems) { + struct _ftsent **a; + + sp->fts_nitems = nitems + 40; + if ((a = reallocarray(sp->fts_array, + sp->fts_nitems, sizeof (FTSENT *))) == NULL) { + free(sp->fts_array); + sp->fts_array = NULL; + sp->fts_nitems = 0; + return (head); + } + sp->fts_array = a; + } + for (ap = sp->fts_array, p = head; p; p = p->fts_link) + *ap++ = p; + qsort(sp->fts_array, nitems, sizeof (FTSENT *), sp->fts_compar); + for (head = *(ap = sp->fts_array); --nitems; ++ap) + ap[0]->fts_link = ap[1]; + ap[0]->fts_link = NULL; + return (head); +} + +static FTSENT * +fts_alloc(FTS *sp, char *name, size_t namelen) +{ + FTSENT *p; + size_t len; + + /* + * The file name is a variable length array and no stat structure is + * necessary if the user has set the nostat bit. Allocate the FTSENT + * structure, the file name and the stat structure in one chunk, but + * be careful that the stat structure is reasonably aligned. Since the + * fts_name field is declared to be of size 1, the fts_name pointer is + * namelen + 2 before the first possible address of the stat structure. + */ + len = sizeof (FTSENT) + namelen; + if (!ISSET(FTS_NOSTAT)) + len += sizeof (struct stat) + ALIGNBYTES; + if ((p = calloc(1, len)) == NULL) + return (NULL); + + p->fts_path = sp->fts_path; + p->fts_namelen = namelen; + p->fts_instr = FTS_NOINSTR; + if (!ISSET(FTS_NOSTAT)) + p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); + (void) memcpy(p->fts_name, name, namelen); + + return (p); +} + +static void +fts_lfree(FTSENT *head) +{ + FTSENT *p; + + /* Free a linked list of structures. */ + while ((p = head) != NULL) { + head = head->fts_link; + free(p); + } +} + +/* + * Allow essentially unlimited paths; find, rm, ls should all work on any tree. + * Most systems will allow creation of paths much longer than PATH_MAX, even + * though the kernel won't resolve them. Add the size (not just what's needed) + * plus 256 bytes so don't realloc the path 2 bytes at a time. + */ +static int +fts_palloc(FTS *sp, size_t more) +{ + char *p; + + /* + * Check for possible wraparound. + */ + more += 256; + if (sp->fts_pathlen + more < sp->fts_pathlen) { + free(sp->fts_path); + sp->fts_path = NULL; + errno = ENAMETOOLONG; + return (1); + } + sp->fts_pathlen += more; + p = realloc(sp->fts_path, sp->fts_pathlen); + if (p == NULL) { + free(sp->fts_path); + sp->fts_path = NULL; + return (1); + } + sp->fts_path = p; + return (0); +} + +/* + * When the path is realloc'd, have to fix all of the pointers in structures + * already returned. + */ +static void +fts_padjust(FTS *sp, FTSENT *head) +{ + FTSENT *p; + char *addr = sp->fts_path; + +#define ADJUST(p) { \ + if ((p)->fts_accpath != (p)->fts_name) { \ + (p)->fts_accpath = \ + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ + } \ + (p)->fts_path = addr; \ +} + /* Adjust the current set of children. */ + for (p = sp->fts_child; p; p = p->fts_link) + ADJUST(p); + + /* Adjust the rest of the tree, including the current level. */ + for (p = head; p->fts_level >= FTS_ROOTLEVEL; ) { + ADJUST(p); + p = p->fts_link ? p->fts_link : p->fts_parent; + } +} + +static size_t +fts_maxarglen(char * const *argv) +{ + size_t len, max; + + for (max = 0; *argv; ++argv) + if ((len = strlen(*argv)) > max) + max = len; + return (max + 1); +} + +/* + * Change to dir specified by fd or p->fts_accpath without getting + * tricked by someone changing the world out from underneath us. + * Assumes p->fts_dev and p->fts_ino are filled in. + */ +static int +fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) +{ + int ret, oerrno, newfd; + struct stat sb; + + newfd = fd; + if (ISSET(FTS_NOCHDIR)) + return (0); + /* + * This originally specified O_DIRECTORY as well - restore once/if we + * implement the flag. + */ + if (fd < 0 && (newfd = open(path, O_RDONLY|O_CLOEXEC)) < 0) + return (-1); + if (fstat(newfd, &sb)) { + ret = -1; + goto bail; + } + if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { + errno = ENOENT; /* disinformation */ + ret = -1; + goto bail; + } + ret = fchdir(newfd); +bail: + oerrno = errno; + if (fd < 0) + (void) close(newfd); + errno = oerrno; + return (ret); +} diff --git a/usr/src/lib/libc/port/gen/reallocarray.c b/usr/src/lib/libc/port/gen/reallocarray.c new file mode 100644 index 0000000000..ecc4d25fa9 --- /dev/null +++ b/usr/src/lib/libc/port/gen/reallocarray.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 Otto Moerbeek + * + * 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. + */ + +#include +#include +#include +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof (size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return (NULL); + } + return (realloc(optr, size * nmemb)); +} diff --git a/usr/src/lib/libc/port/gen/strtonum.c b/usr/src/lib/libc/port/gen/strtonum.c new file mode 100644 index 0000000000..e180769313 --- /dev/null +++ b/usr/src/lib/libc/port/gen/strtonum.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * 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. + */ + +#include +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index d33a1d39c2..db73a140f9 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -21,7 +21,7 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2013 Gary Mills * Copyright 2014 Garrett D'Amore @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -435,7 +436,7 @@ int flock(int filedes, int operation); /* fmtmsg.c */ int addseverity(int value, const char *string); int fmtmsg(long class, const char *label, int severity, const char *text, - const char *action, const char *tag); + const char *action, const char *tag); /* ftime.c */ int ftime(struct timeb *tp); @@ -443,6 +444,13 @@ int ftime(struct timeb *tp); /* ftok.c */ key_t ftok(const char *path, int id); +/* fts.c */ +FTSENT *fts_children(FTS *, int); +int fts_close(FTS *); +FTS *fts_open(char * const *, int, int (*)(const FTSENT **, const FTSENT **)); +FTSENT *fts_read(FTS *); +int fts_set(FTS *, FTSENT *, int); + /* gcvt.c */ char *gcvt(double number, int ndigit, char *buf); @@ -820,6 +828,9 @@ size_t rctlblk_size(void); /* readdir.c */ struct dirent *readdir(DIR *dirp); +/* reallocarray.c */ +void *reallocarray(void *, size_t, size_t); + /* realpath.c */ char *realpath(const char *_RESTRICT_KYWD raw, char *_RESTRICT_KYWD canon); @@ -973,6 +984,9 @@ char *strtok_r(char *_RESTRICT_KYWD, const char *_RESTRICT_KYWD, long strtol(const char *_RESTRICT_KYWD str, char **_RESTRICT_KYWD nptr, int base); +/* strtonum.c */ +long long strtonum(const char *, long long, long long, const char **); + /* strtoul.c */ unsigned long strtoul(const char *_RESTRICT_KYWD str, char **_RESTRICT_KYWD nptr, int base); diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 9392abc540..c9e03580e2 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -93,6 +93,17 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.23 { # openbsd compat + protected: + fts_children; + fts_close; + fts_open; + fts_read; + fts_set; + reallocarray; + strtonum; +} ILLUMOS_0.22; + SYMBOL_VERSION ILLUMOS_0.22 { # endian(3C) protected: htobe16; diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 7c8f14372d..b478c61a74 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -18,14 +18,13 @@ # # CDDL HEADER END # + # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2016 Joyent, Inc. # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore -# -# Copyright 2011 Nexenta Systems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright 2017 Nexenta Systems, Inc. # LIBCDIR= $(SRC)/lib/libc @@ -410,14 +409,14 @@ PORTGEN= \ addsev.o \ ascii_strncasecmp.o \ assert.o \ + atexit.o \ + atfork.o \ atof.o \ atoi.o \ atol.o \ atoll.o \ attrat.o \ attropen.o \ - atexit.o \ - atfork.o \ basename.o \ calloc.o \ catgets.o \ @@ -459,8 +458,10 @@ PORTGEN= \ fmtmsg.o \ ftime.o \ ftok.o \ + fts.o \ ftw.o \ gcvt.o \ + get_nprocs.o \ getauxv.o \ getcwd.o \ getdate_err.o \ @@ -478,7 +479,6 @@ PORTGEN= \ getlogin.o \ getmntent.o \ getnetgrent.o \ - get_nprocs.o \ getopt.o \ getopt_long.o \ getpagesize.o \ @@ -560,8 +560,8 @@ PORTGEN= \ posix_madvise.o \ posix_memalign.o \ priocntl.o \ - privlib.o \ priv_str_xlate.o \ + privlib.o \ psecflags.o \ psiginfo.o \ psignal.o \ @@ -574,6 +574,7 @@ PORTGEN= \ rctlops.o \ readdir.o \ readdir_r.o \ + reallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ @@ -615,6 +616,7 @@ PORTGEN= \ strtoimax.o \ strtok.o \ strtok_r.o \ + strtonum.o \ strtoumax.o \ swab.o \ swapctl.o \ @@ -1175,23 +1177,23 @@ SRCS= \ $(XATTROBJS:%.o=$(SRC)/common/xattr/%.c) \ $(COMOBJS:%.o=$(SRC)/common/util/%.c) \ $(DTRACEOBJS:%.o=$(SRC)/common/dtrace/%.c) \ - $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ - $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ - $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ - $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ - $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ - $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ - $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ - $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ - $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ - $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ - $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ - $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ - $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ - $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ + $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ + $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ + $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ + $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ + $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ + $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ + $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ + $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ + $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ + $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ + $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ + $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ + $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ $(UNICODEOBJS:%.o=$(SRC)/common/unicode/%.c) \ - $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ - $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ + $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ + $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ $(LIBCBASE)/crt/_ftou.c \ $(LIBCBASE)/gen/_xregs_clrptr.c \ $(LIBCBASE)/gen/byteorder.c \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 6744289046..70d1fdea43 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -18,15 +18,14 @@ # # CDDL HEADER END # + # # Copyright 2016 Gary Mills # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2015, Joyent, Inc. All rights reserved. # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2013 Garrett D'Amore -# -# Copyright 2011 Nexenta Systems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright 2017 Nexenta Systems, Inc. # LIBCDIR= $(SRC)/lib/libc @@ -368,14 +367,14 @@ PORTGEN= \ addsev.o \ ascii_strncasecmp.o \ assert.o \ - attrat.o \ + atexit.o \ + atfork.o \ atof.o \ atoi.o \ atol.o \ atoll.o \ + attrat.o \ attropen.o \ - atexit.o \ - atfork.o \ basename.o \ calloc.o \ catgets.o \ @@ -417,8 +416,10 @@ PORTGEN= \ fmtmsg.o \ ftime.o \ ftok.o \ + fts.o \ ftw.o \ gcvt.o \ + get_nprocs.o \ getauxv.o \ getcwd.o \ getdate_err.o \ @@ -436,7 +437,6 @@ PORTGEN= \ getlogin.o \ getmntent.o \ getnetgrent.o \ - get_nprocs.o \ getopt.o \ getopt_long.o \ getpagesize.o \ @@ -518,8 +518,8 @@ PORTGEN= \ posix_madvise.o \ posix_memalign.o \ priocntl.o \ - privlib.o \ priv_str_xlate.o \ + privlib.o \ psecflags.o \ psiginfo.o \ psignal.o \ @@ -532,6 +532,7 @@ PORTGEN= \ rctlops.o \ readdir.o \ readdir_r.o \ + reallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ @@ -573,6 +574,7 @@ PORTGEN= \ strtoimax.o \ strtok.o \ strtok_r.o \ + strtonum.o \ strtoumax.o \ swab.o \ swapctl.o \ @@ -1105,23 +1107,23 @@ SRCS= \ $(ATOMICOBJS:%.o=$(SRC)/common/atomic/%.c) \ $(XATTROBJS:%.o=$(SRC)/common/xattr/%.c) \ $(COMOBJS:%.o=$(SRC)/common/util/%.c) \ - $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ - $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ - $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ - $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ - $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ - $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ - $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ - $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ - $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ - $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ - $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ - $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ - $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ - $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ + $(PORTFP:%.o=$(LIBCDIR)/port/fp/%.c) \ + $(PORTGEN:%.o=$(LIBCDIR)/port/gen/%.c) \ + $(PORTI18N:%.o=$(LIBCDIR)/port/i18n/%.c) \ + $(PORTLOCALE:%.o=$(LIBCDIR)/port/locale/%.c) \ + $(PORTPRINT:%.o=$(LIBCDIR)/port/print/%.c) \ + $(PORTREGEX:%.o=$(LIBCDIR)/port/regex/%.c) \ + $(PORTSTDIO:%.o=$(LIBCDIR)/port/stdio/%.c) \ + $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ + $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ + $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ + $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ + $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ + $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ $(UNICODEOBJS:%.o=$(SRC)/common/unicode/%.c) \ - $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ - $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ + $(UNWINDMACHOBJS:%.o=$(LIBCDIR)/port/unwind/%.c) \ + $(FPOBJS:%.o=$(LIBCDIR)/$(MACH)/fp/%.c) \ $(FPOBJS64:%.o=$(LIBCBASE)/fp/%.c) \ $(LIBCBASE)/crt/_ftou.c \ $(LIBCBASE)/gen/_xregs_clrptr.c \ diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile index 64e8b512cc..0d8c89c217 100644 --- a/usr/src/man/man3c/Makefile +++ b/usr/src/man/man3c/Makefile @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright 2013 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. # Copyright 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore # Copyright 2016 Joyent, Inc. @@ -19,466 +19,468 @@ include $(SRC)/Makefile.master -MANSECT= 3c - -MANFILES= __fbufsize.3c \ - _longjmp.3c \ - _stack_grow.3c \ - a64l.3c \ - abort.3c \ - abs.3c \ - addsev.3c \ - addseverity.3c \ - aio_cancel.3c \ - aio_error.3c \ - aio_fsync.3c \ - aio_read.3c \ - aio_return.3c \ - aio_suspend.3c \ - aio_waitn.3c \ - aio_write.3c \ - aiocancel.3c \ - aioread.3c \ - aiowait.3c \ +MANSECT= 3c + +MANFILES= __fbufsize.3c \ + _longjmp.3c \ + _stack_grow.3c \ + a64l.3c \ + abort.3c \ + abs.3c \ + addsev.3c \ + addseverity.3c \ + aio_cancel.3c \ + aio_error.3c \ + aio_fsync.3c \ + aio_read.3c \ + aio_return.3c \ + aio_suspend.3c \ + aio_waitn.3c \ + aio_write.3c \ + aiocancel.3c \ + aioread.3c \ + aiowait.3c \ aligned_alloc.3c \ arc4random.3c \ - assert.3c \ - atexit.3c \ - atomic_add.3c \ - atomic_and.3c \ - atomic_bits.3c \ - atomic_cas.3c \ - atomic_dec.3c \ - atomic_inc.3c \ - atomic_ops.3c \ - atomic_or.3c \ - atomic_swap.3c \ - attropen.3c \ - basename.3c \ - bsd_signal.3c \ - bsearch.3c \ - bstring.3c \ - btowc.3c \ + assert.3c \ + atexit.3c \ + atomic_add.3c \ + atomic_and.3c \ + atomic_bits.3c \ + atomic_cas.3c \ + atomic_dec.3c \ + atomic_inc.3c \ + atomic_ops.3c \ + atomic_or.3c \ + atomic_swap.3c \ + attropen.3c \ + basename.3c \ + bsd_signal.3c \ + bsearch.3c \ + bstring.3c \ + btowc.3c \ call_once.3c \ - catgets.3c \ - catopen.3c \ - cfgetispeed.3c \ - cfsetispeed.3c \ + catgets.3c \ + catopen.3c \ + cfgetispeed.3c \ + cfsetispeed.3c \ clearenv.3c \ - clock.3c \ - clock_nanosleep.3c \ - clock_settime.3c \ - closedir.3c \ - closefrom.3c \ + clock.3c \ + clock_nanosleep.3c \ + clock_settime.3c \ + closedir.3c \ + closefrom.3c \ cnd.3c \ - cond_init.3c \ - confstr.3c \ - crypt.3c \ - crypt_genhash_impl.3c \ - crypt_gensalt.3c \ - crypt_gensalt_impl.3c \ - cset.3c \ - ctermid.3c \ - ctime.3c \ - ctype.3c \ - cuserid.3c \ - daemon.3c \ - decimal_to_floating.3c \ - difftime.3c \ - directio.3c \ - dirfd.3c \ - dirname.3c \ - div.3c \ - dladdr.3c \ - dlclose.3c \ - dldump.3c \ - dlerror.3c \ - dlinfo.3c \ - dlopen.3c \ - dlsym.3c \ - door_bind.3c \ - door_call.3c \ - door_create.3c \ - door_cred.3c \ - door_getparam.3c \ - door_info.3c \ - door_return.3c \ - door_revoke.3c \ - door_server_create.3c \ - door_ucred.3c \ - drand48.3c \ - dup2.3c \ - econvert.3c \ - ecvt.3c \ - enable_extended_FILE_stdio.3c \ - encrypt.3c \ - end.3c \ + cond_init.3c \ + confstr.3c \ + crypt.3c \ + crypt_genhash_impl.3c \ + crypt_gensalt.3c \ + crypt_gensalt_impl.3c \ + cset.3c \ + ctermid.3c \ + ctime.3c \ + ctype.3c \ + cuserid.3c \ + daemon.3c \ + decimal_to_floating.3c \ + difftime.3c \ + directio.3c \ + dirfd.3c \ + dirname.3c \ + div.3c \ + dladdr.3c \ + dlclose.3c \ + dldump.3c \ + dlerror.3c \ + dlinfo.3c \ + dlopen.3c \ + dlsym.3c \ + door_bind.3c \ + door_call.3c \ + door_create.3c \ + door_cred.3c \ + door_getparam.3c \ + door_info.3c \ + door_return.3c \ + door_revoke.3c \ + door_server_create.3c \ + door_ucred.3c \ + drand48.3c \ + dup2.3c \ + econvert.3c \ + ecvt.3c \ + enable_extended_FILE_stdio.3c \ + encrypt.3c \ + end.3c \ endian.3c \ - epoll_create.3c \ - epoll_ctl.3c \ - epoll_wait.3c \ - err.3c \ - euclen.3c \ + epoll_create.3c \ + epoll_ctl.3c \ + epoll_wait.3c \ + err.3c \ + euclen.3c \ eventfd.3c \ - exit.3c \ - fattach.3c \ - fclose.3c \ + exit.3c \ + fattach.3c \ + fclose.3c \ fcloseall.3c \ - fdatasync.3c \ - fdetach.3c \ - fdopen.3c \ - ferror.3c \ - fflush.3c \ - ffs.3c \ - fgetattr.3c \ - fgetc.3c \ - fgetpos.3c \ - fgetwc.3c \ - floating_to_decimal.3c \ + fdatasync.3c \ + fdetach.3c \ + fdopen.3c \ + ferror.3c \ + fflush.3c \ + ffs.3c \ + fgetattr.3c \ + fgetc.3c \ + fgetpos.3c \ + fgetwc.3c \ + floating_to_decimal.3c \ flock.3c \ - flockfile.3c \ - fmtmsg.3c \ - fnmatch.3c \ - fopen.3c \ - fpgetround.3c \ - fputc.3c \ - fputwc.3c \ - fputws.3c \ - fread.3c \ - freopen.3c \ - fseek.3c \ - fsetpos.3c \ - fsync.3c \ - ftell.3c \ - ftime.3c \ - ftok.3c \ - ftw.3c \ - fwide.3c \ - fwprintf.3c \ - fwrite.3c \ - fwscanf.3c \ - getcpuid.3c \ - getcwd.3c \ - getdate.3c \ - getdtablesize.3c \ + flockfile.3c \ + fmtmsg.3c \ + fnmatch.3c \ + fopen.3c \ + fpgetround.3c \ + fputc.3c \ + fputwc.3c \ + fputws.3c \ + fread.3c \ + freopen.3c \ + fseek.3c \ + fsetpos.3c \ + fsync.3c \ + ftell.3c \ + ftime.3c \ + ftok.3c \ + fts.3c \ + ftw.3c \ + fwide.3c \ + fwprintf.3c \ + fwrite.3c \ + fwscanf.3c \ + get_nprocs.3c \ + getcpuid.3c \ + getcwd.3c \ + getdate.3c \ + getdtablesize.3c \ getentropy.3c \ - getenv.3c \ - getexecname.3c \ - getgrnam.3c \ - gethostid.3c \ - gethostname.3c \ - gethrtime.3c \ + getenv.3c \ + getexecname.3c \ + getgrnam.3c \ + gethostid.3c \ + gethostname.3c \ + gethrtime.3c \ getline.3c \ - getloadavg.3c \ - getlogin.3c \ - getmntent.3c \ - getnetgrent.3c \ - get_nprocs.3c \ - getopt.3c \ - getpagesize.3c \ - getpagesizes.3c \ - getpass.3c \ - getpeerucred.3c \ - getpriority.3c \ + getloadavg.3c \ + getlogin.3c \ + getmntent.3c \ + getnetgrent.3c \ + getopt.3c \ + getpagesize.3c \ + getpagesizes.3c \ + getpass.3c \ + getpeerucred.3c \ + getpriority.3c \ getprogname.3c \ - getpw.3c \ - getpwnam.3c \ - getrusage.3c \ - gets.3c \ - getspnam.3c \ - getsubopt.3c \ - gettext.3c \ - gettimeofday.3c \ - gettxt.3c \ - getusershell.3c \ - getutent.3c \ - getutxent.3c \ - getvfsent.3c \ - getwc.3c \ - getwchar.3c \ - getwd.3c \ - getwidth.3c \ - getws.3c \ - getzoneid.3c \ - glob.3c \ - grantpt.3c \ - hsearch.3c \ - iconv.3c \ - iconv_close.3c \ - iconv_open.3c \ - imaxabs.3c \ - imaxdiv.3c \ - index.3c \ - initgroups.3c \ - insque.3c \ - is_system_labeled.3c \ - isaexec.3c \ - isastream.3c \ - isatty.3c \ - isnand.3c \ - iswalpha.3c \ - iswctype.3c \ - killpg.3c \ - lckpwdf.3c \ - lfmt.3c \ - lio_listio.3c \ - localeconv.3c \ - lockf.3c \ - lsearch.3c \ - madvise.3c \ - makecontext.3c \ - makedev.3c \ - malloc.3c \ - mblen.3c \ - mbrlen.3c \ - mbrtowc.3c \ - mbsinit.3c \ - mbsrtowcs.3c \ + getpw.3c \ + getpwnam.3c \ + getrusage.3c \ + gets.3c \ + getspnam.3c \ + getsubopt.3c \ + gettext.3c \ + gettimeofday.3c \ + gettxt.3c \ + getusershell.3c \ + getutent.3c \ + getutxent.3c \ + getvfsent.3c \ + getwc.3c \ + getwchar.3c \ + getwd.3c \ + getwidth.3c \ + getws.3c \ + getzoneid.3c \ + glob.3c \ + grantpt.3c \ + hsearch.3c \ + iconv.3c \ + iconv_close.3c \ + iconv_open.3c \ + imaxabs.3c \ + imaxdiv.3c \ + index.3c \ + initgroups.3c \ + insque.3c \ + is_system_labeled.3c \ + isaexec.3c \ + isastream.3c \ + isatty.3c \ + isnand.3c \ + iswalpha.3c \ + iswctype.3c \ + killpg.3c \ + lckpwdf.3c \ + lfmt.3c \ + lio_listio.3c \ + localeconv.3c \ + lockf.3c \ + lsearch.3c \ + madvise.3c \ + makecontext.3c \ + makedev.3c \ + malloc.3c \ + mblen.3c \ + mbrlen.3c \ + mbrtowc.3c \ + mbsinit.3c \ + mbsrtowcs.3c \ mbstowcs.3c \ - mbtowc.3c \ - membar_ops.3c \ - memory.3c \ - mkfifo.3c \ - mkstemp.3c \ - mktemp.3c \ - mktime.3c \ - mlock.3c \ - mlockall.3c \ - monitor.3c \ - mq_close.3c \ - mq_getattr.3c \ - mq_notify.3c \ - mq_open.3c \ - mq_receive.3c \ - mq_send.3c \ - mq_setattr.3c \ - mq_unlink.3c \ - msync.3c \ + mbtowc.3c \ + membar_ops.3c \ + memory.3c \ + mkfifo.3c \ + mkstemp.3c \ + mktemp.3c \ + mktime.3c \ + mlock.3c \ + mlockall.3c \ + monitor.3c \ + mq_close.3c \ + mq_getattr.3c \ + mq_notify.3c \ + mq_open.3c \ + mq_receive.3c \ + mq_send.3c \ + mq_setattr.3c \ + mq_unlink.3c \ + msync.3c \ mtx.3c \ - mutex_init.3c \ - nanosleep.3c \ - ndbm.3c \ - newlocale.3c \ - nl_langinfo.3c \ - offsetof.3c \ - opendir.3c \ - perror.3c \ - pfmt.3c \ - plock.3c \ - popen.3c \ - port_alert.3c \ - port_associate.3c \ - port_create.3c \ - port_get.3c \ - port_send.3c \ - posix_fadvise.3c \ - posix_fallocate.3c \ - posix_madvise.3c \ - posix_memalign.3c \ - posix_openpt.3c \ - posix_spawn.3c \ - posix_spawn_file_actions_addclose.3c \ - posix_spawn_file_actions_addclosefrom_np.3c \ - posix_spawn_file_actions_adddup2.3c \ - posix_spawn_file_actions_destroy.3c \ - posix_spawn_pipe_np.3c \ - posix_spawnattr_destroy.3c \ - posix_spawnattr_getflags.3c \ - posix_spawnattr_getpgroup.3c \ - posix_spawnattr_getschedparam.3c \ - posix_spawnattr_getschedpolicy.3c \ - posix_spawnattr_getsigdefault.3c \ - posix_spawnattr_getsigignore_np.3c \ - posix_spawnattr_getsigmask.3c \ - printf.3c \ - priv_addset.3c \ - priv_set.3c \ - priv_str_to_set.3c \ - pset_getloadavg.3c \ - psignal.3c \ - pthread_atfork.3c \ - pthread_attr_getdetachstate.3c \ - pthread_attr_getguardsize.3c \ - pthread_attr_getinheritsched.3c \ - pthread_attr_getschedparam.3c \ - pthread_attr_getschedpolicy.3c \ - pthread_attr_getscope.3c \ - pthread_attr_getstack.3c \ - pthread_attr_getstackaddr.3c \ - pthread_attr_getstacksize.3c \ + mutex_init.3c \ + nanosleep.3c \ + ndbm.3c \ + newlocale.3c \ + nl_langinfo.3c \ + offsetof.3c \ + opendir.3c \ + perror.3c \ + pfmt.3c \ + plock.3c \ + popen.3c \ + port_alert.3c \ + port_associate.3c \ + port_create.3c \ + port_get.3c \ + port_send.3c \ + posix_fadvise.3c \ + posix_fallocate.3c \ + posix_madvise.3c \ + posix_memalign.3c \ + posix_openpt.3c \ + posix_spawn.3c \ + posix_spawn_file_actions_addclose.3c \ + posix_spawn_file_actions_addclosefrom_np.3c \ + posix_spawn_file_actions_adddup2.3c \ + posix_spawn_file_actions_destroy.3c \ + posix_spawn_pipe_np.3c \ + posix_spawnattr_destroy.3c \ + posix_spawnattr_getflags.3c \ + posix_spawnattr_getpgroup.3c \ + posix_spawnattr_getschedparam.3c \ + posix_spawnattr_getschedpolicy.3c \ + posix_spawnattr_getsigdefault.3c \ + posix_spawnattr_getsigignore_np.3c \ + posix_spawnattr_getsigmask.3c \ + printf.3c \ + priv_addset.3c \ + priv_set.3c \ + priv_str_to_set.3c \ + pset_getloadavg.3c \ + psignal.3c \ + pthread_atfork.3c \ pthread_attr_get_np.3c \ - pthread_attr_init.3c \ - pthread_barrier_destroy.3c \ - pthread_barrier_wait.3c \ - pthread_barrierattr_destroy.3c \ - pthread_barrierattr_getpshared.3c \ - pthread_cancel.3c \ - pthread_cleanup_pop.3c \ - pthread_cleanup_push.3c \ - pthread_cond_init.3c \ - pthread_cond_signal.3c \ - pthread_cond_wait.3c \ - pthread_condattr_getclock.3c \ - pthread_condattr_getpshared.3c \ - pthread_condattr_init.3c \ - pthread_create.3c \ - pthread_detach.3c \ - pthread_equal.3c \ - pthread_exit.3c \ - pthread_getconcurrency.3c \ - pthread_getschedparam.3c \ - pthread_getspecific.3c \ - pthread_join.3c \ - pthread_key_create.3c \ - pthread_key_delete.3c \ - pthread_kill.3c \ + pthread_attr_getdetachstate.3c \ + pthread_attr_getguardsize.3c \ + pthread_attr_getinheritsched.3c \ + pthread_attr_getschedparam.3c \ + pthread_attr_getschedpolicy.3c \ + pthread_attr_getscope.3c \ + pthread_attr_getstack.3c \ + pthread_attr_getstackaddr.3c \ + pthread_attr_getstacksize.3c \ + pthread_attr_init.3c \ + pthread_barrier_destroy.3c \ + pthread_barrier_wait.3c \ + pthread_barrierattr_destroy.3c \ + pthread_barrierattr_getpshared.3c \ + pthread_cancel.3c \ + pthread_cleanup_pop.3c \ + pthread_cleanup_push.3c \ + pthread_cond_init.3c \ + pthread_cond_signal.3c \ + pthread_cond_wait.3c \ + pthread_condattr_getclock.3c \ + pthread_condattr_getpshared.3c \ + pthread_condattr_init.3c \ + pthread_create.3c \ + pthread_detach.3c \ + pthread_equal.3c \ + pthread_exit.3c \ + pthread_getconcurrency.3c \ + pthread_getschedparam.3c \ + pthread_getspecific.3c \ + pthread_join.3c \ + pthread_key_create.3c \ + pthread_key_delete.3c \ + pthread_kill.3c \ pthread_mutex_consistent.3c \ - pthread_mutex_getprioceiling.3c \ - pthread_mutex_init.3c \ - pthread_mutex_lock.3c \ - pthread_mutex_timedlock.3c \ - pthread_mutexattr_getprioceiling.3c \ - pthread_mutexattr_getprotocol.3c \ - pthread_mutexattr_getpshared.3c \ + pthread_mutex_getprioceiling.3c \ + pthread_mutex_init.3c \ + pthread_mutex_lock.3c \ + pthread_mutex_timedlock.3c \ + pthread_mutexattr_getprioceiling.3c \ + pthread_mutexattr_getprotocol.3c \ + pthread_mutexattr_getpshared.3c \ pthread_mutexattr_getrobust.3c \ - pthread_mutexattr_gettype.3c \ - pthread_mutexattr_init.3c \ - pthread_once.3c \ - pthread_rwlock_init.3c \ - pthread_rwlock_rdlock.3c \ - pthread_rwlock_timedrdlock.3c \ - pthread_rwlock_timedwrlock.3c \ - pthread_rwlock_unlock.3c \ - pthread_rwlock_wrlock.3c \ - pthread_rwlockattr_getpshared.3c \ - pthread_rwlockattr_init.3c \ - pthread_self.3c \ - pthread_setcancelstate.3c \ - pthread_setcanceltype.3c \ - pthread_setschedprio.3c \ - pthread_sigmask.3c \ - pthread_spin_destroy.3c \ - pthread_spin_lock.3c \ - pthread_spin_unlock.3c \ - pthread_testcancel.3c \ - ptrace.3c \ - ptsname.3c \ - putenv.3c \ - putpwent.3c \ - puts.3c \ - putspent.3c \ - putws.3c \ - qsort.3c \ + pthread_mutexattr_gettype.3c \ + pthread_mutexattr_init.3c \ + pthread_once.3c \ + pthread_rwlock_init.3c \ + pthread_rwlock_rdlock.3c \ + pthread_rwlock_timedrdlock.3c \ + pthread_rwlock_timedwrlock.3c \ + pthread_rwlock_unlock.3c \ + pthread_rwlock_wrlock.3c \ + pthread_rwlockattr_getpshared.3c \ + pthread_rwlockattr_init.3c \ + pthread_self.3c \ + pthread_setcancelstate.3c \ + pthread_setcanceltype.3c \ + pthread_setschedprio.3c \ + pthread_sigmask.3c \ + pthread_spin_destroy.3c \ + pthread_spin_lock.3c \ + pthread_spin_unlock.3c \ + pthread_testcancel.3c \ + ptrace.3c \ + ptsname.3c \ + putenv.3c \ + putpwent.3c \ + puts.3c \ + putspent.3c \ + putws.3c \ + qsort.3c \ quick_exit.3c \ - raise.3c \ - rand.3c \ - random.3c \ - rctl_walk.3c \ - rctlblk_set_value.3c \ - re_comp.3c \ - readdir.3c \ - realpath.3c \ - reboot.3c \ - regcmp.3c \ - regcomp.3c \ - remove.3c \ - rewind.3c \ - rewinddir.3c \ - rwlock.3c \ - scandir.3c \ - scanf.3c \ - sched_get_priority_max.3c \ - sched_getparam.3c \ - sched_getscheduler.3c \ - sched_rr_get_interval.3c \ - sched_setparam.3c \ - sched_setscheduler.3c \ - sched_yield.3c \ - schedctl_init.3c \ - seekdir.3c \ - select.3c \ - sem_close.3c \ - sem_destroy.3c \ - sem_getvalue.3c \ - sem_init.3c \ - sem_open.3c \ - sem_post.3c \ - sem_timedwait.3c \ - sem_unlink.3c \ - sem_wait.3c \ - semaphore.3c \ - setbuf.3c \ - setbuffer.3c \ - setcat.3c \ - setenv.3c \ - setjmp.3c \ - setkey.3c \ - setlabel.3c \ - setlocale.3c \ - shm_open.3c \ - shm_unlink.3c \ - sigfpe.3c \ - siginterrupt.3c \ - signal.3c \ + raise.3c \ + rand.3c \ + random.3c \ + rctl_walk.3c \ + rctlblk_set_value.3c \ + re_comp.3c \ + readdir.3c \ + realpath.3c \ + reboot.3c \ + regcmp.3c \ + regcomp.3c \ + remove.3c \ + rewind.3c \ + rewinddir.3c \ + rwlock.3c \ + scandir.3c \ + scanf.3c \ + sched_get_priority_max.3c \ + sched_getparam.3c \ + sched_getscheduler.3c \ + sched_rr_get_interval.3c \ + sched_setparam.3c \ + sched_setscheduler.3c \ + sched_yield.3c \ + schedctl_init.3c \ + seekdir.3c \ + select.3c \ + sem_close.3c \ + sem_destroy.3c \ + sem_getvalue.3c \ + sem_init.3c \ + sem_open.3c \ + sem_post.3c \ + sem_timedwait.3c \ + sem_unlink.3c \ + sem_wait.3c \ + semaphore.3c \ + setbuf.3c \ + setbuffer.3c \ + setcat.3c \ + setenv.3c \ + setjmp.3c \ + setkey.3c \ + setlabel.3c \ + setlocale.3c \ + shm_open.3c \ + shm_unlink.3c \ + sigfpe.3c \ + siginterrupt.3c \ + signal.3c \ signalfd.3c \ - sigqueue.3c \ - sigsetops.3c \ - sigstack.3c \ - sigwaitinfo.3c \ - sleep.3c \ - ssignal.3c \ + sigqueue.3c \ + sigsetops.3c \ + sigstack.3c \ + sigwaitinfo.3c \ + sleep.3c \ smt_pause.3c \ - stack_getbounds.3c \ - stack_inbounds.3c \ - stack_setbounds.3c \ - stack_violation.3c \ - stdio.3c \ - str2sig.3c \ - strcoll.3c \ - strerror.3c \ - strfmon.3c \ - strftime.3c \ - string.3c \ - string_to_decimal.3c \ - strptime.3c \ - strsignal.3c \ - strtod.3c \ - strtoimax.3c \ - strtol.3c \ - strtoul.3c \ - strtows.3c \ - strxfrm.3c \ - swab.3c \ - sync_instruction_memory.3c \ - sysconf.3c \ - syslog.3c \ - system.3c \ - tcdrain.3c \ - tcflow.3c \ - tcflush.3c \ - tcgetattr.3c \ - tcgetpgrp.3c \ - tcgetsid.3c \ - tcsendbreak.3c \ - tcsetattr.3c \ - tcsetpgrp.3c \ - tell.3c \ - telldir.3c \ - termios.3c \ - thr_create.3c \ - thr_exit.3c \ - thr_getconcurrency.3c \ - thr_getprio.3c \ - thr_join.3c \ - thr_keycreate.3c \ - thr_kill.3c \ - thr_main.3c \ - thr_min_stack.3c \ - thr_self.3c \ - thr_sigsetmask.3c \ - thr_stksegment.3c \ - thr_suspend.3c \ - thr_yield.3c \ + ssignal.3c \ + stack_getbounds.3c \ + stack_inbounds.3c \ + stack_setbounds.3c \ + stack_violation.3c \ + stdio.3c \ + str2sig.3c \ + strcoll.3c \ + strerror.3c \ + strfmon.3c \ + strftime.3c \ + string.3c \ + string_to_decimal.3c \ + strptime.3c \ + strsignal.3c \ + strtod.3c \ + strtoimax.3c \ + strtol.3c \ + strtonum.3c \ + strtoul.3c \ + strtows.3c \ + strxfrm.3c \ + swab.3c \ + sync_instruction_memory.3c \ + sysconf.3c \ + syslog.3c \ + system.3c \ + tcdrain.3c \ + tcflow.3c \ + tcflush.3c \ + tcgetattr.3c \ + tcgetpgrp.3c \ + tcgetsid.3c \ + tcsendbreak.3c \ + tcsetattr.3c \ + tcsetpgrp.3c \ + tell.3c \ + telldir.3c \ + termios.3c \ + thr_create.3c \ + thr_exit.3c \ + thr_getconcurrency.3c \ + thr_getprio.3c \ + thr_join.3c \ + thr_keycreate.3c \ + thr_kill.3c \ + thr_main.3c \ + thr_min_stack.3c \ + thr_self.3c \ + thr_sigsetmask.3c \ + thr_stksegment.3c \ + thr_suspend.3c \ + thr_yield.3c \ thrd_create.3c \ thrd_current.3c \ thrd_detach.3c \ @@ -486,917 +488,923 @@ MANFILES= __fbufsize.3c \ thrd_exit.3c \ thrd_join.3c \ thrd_yield.3c \ - timer_create.3c \ - timer_delete.3c \ - timer_settime.3c \ - timeradd.3c \ + timer_create.3c \ + timer_delete.3c \ + timer_settime.3c \ + timeradd.3c \ timerfd_create.3c \ timespec_get.3c \ - tmpfile.3c \ - tmpnam.3c \ - toascii.3c \ - tolower.3c \ - toupper.3c \ - towlower.3c \ - towupper.3c \ - truncate.3c \ - tsearch.3c \ + tmpfile.3c \ + tmpnam.3c \ + toascii.3c \ + tolower.3c \ + toupper.3c \ + towlower.3c \ + towupper.3c \ + truncate.3c \ + tsearch.3c \ tss.3c \ - ttyname.3c \ - ttyslot.3c \ - u8_strcmp.3c \ - u8_textprep_str.3c \ - u8_validate.3c \ - ualarm.3c \ - uconv_u16tou32.3c \ - ucred.3c \ - ungetc.3c \ - ungetwc.3c \ - unlockpt.3c \ - unsetenv.3c \ - uselocale.3c \ - usleep.3c \ - vfwprintf.3c \ - vlfmt.3c \ - vpfmt.3c \ - vprintf.3c \ - vsyslog.3c \ - wait.3c \ - wait3.3c \ - waitpid.3c \ - walkcontext.3c \ + ttyname.3c \ + ttyslot.3c \ + u8_strcmp.3c \ + u8_textprep_str.3c \ + u8_validate.3c \ + ualarm.3c \ + uconv_u16tou32.3c \ + ucred.3c \ + ungetc.3c \ + ungetwc.3c \ + unlockpt.3c \ + unsetenv.3c \ + uselocale.3c \ + usleep.3c \ + vfwprintf.3c \ + vlfmt.3c \ + vpfmt.3c \ + vprintf.3c \ + vsyslog.3c \ + wait.3c \ + wait3.3c \ + waitpid.3c \ + walkcontext.3c \ wcpcpy.3c \ - wcrtomb.3c \ + wcrtomb.3c \ wcscasecmp.3c \ - wcscoll.3c \ + wcscoll.3c \ wcsdup.3c \ + wcsftime.3c \ wcslen.3c \ - wcsftime.3c \ - wcsrtombs.3c \ - wcsstr.3c \ - wcstod.3c \ - wcstoimax.3c \ - wcstol.3c \ + wcsrtombs.3c \ + wcsstr.3c \ + wcstod.3c \ + wcstoimax.3c \ + wcstol.3c \ wcstombs.3c \ - wcstoul.3c \ - wcstring.3c \ - wcswidth.3c \ - wcsxfrm.3c \ - wctob.3c \ - wctomb.3c \ - wctrans.3c \ - wctype.3c \ - wcwidth.3c \ - wmemchr.3c \ - wmemcmp.3c \ - wmemcpy.3c \ - wmemmove.3c \ - wmemset.3c \ - wordexp.3c \ - wsprintf.3c \ - wsscanf.3c \ - wstring.3c \ + wcstoul.3c \ + wcstring.3c \ + wcswidth.3c \ + wcsxfrm.3c \ + wctob.3c \ + wctomb.3c \ + wctrans.3c \ + wctype.3c \ + wcwidth.3c \ + wmemchr.3c \ + wmemcmp.3c \ + wmemcpy.3c \ + wmemmove.3c \ + wmemset.3c \ + wordexp.3c \ + wsprintf.3c \ + wsscanf.3c \ + wstring.3c \ MANLINKS= FD_CLR.3c \ - FD_ISSET.3c \ - FD_SET.3c \ - FD_ZERO.3c \ - __flbf.3c \ - __fpending.3c \ - __fpurge.3c \ - __freadable.3c \ - __freading.3c \ - __fsetlocking.3c \ - __fwritable.3c \ - __fwriting.3c \ - _edata.3c \ - _end.3c \ - _etext.3c \ - _exithandle.3c \ - _flushlbf.3c \ - _setjmp.3c \ - addrtosymstr.3c \ - aiowrite.3c \ - alloca.3c \ - alphasort.3c \ - ascftime.3c \ - asctime.3c \ - asctime_r.3c \ - asprintf.3c \ - at_quick_exit.3c \ - atof.3c \ - atoi.3c \ - atol.3c \ - atoll.3c \ + FD_ISSET.3c \ + FD_SET.3c \ + FD_ZERO.3c \ + __flbf.3c \ + __fpending.3c \ + __fpurge.3c \ + __freadable.3c \ + __freading.3c \ + __fsetlocking.3c \ + __fwritable.3c \ + __fwriting.3c \ + _edata.3c \ + _end.3c \ + _etext.3c \ + _exithandle.3c \ + _flushlbf.3c \ + _setjmp.3c \ + addrtosymstr.3c \ + aiowrite.3c \ + alloca.3c \ + alphasort.3c \ arc4random_buf.3c \ arc4random_uniform.3c \ - atomic_add_16.3c \ - atomic_add_16_nv.3c \ - atomic_add_32.3c \ - atomic_add_32_nv.3c \ - atomic_add_64.3c \ - atomic_add_64_nv.3c \ - atomic_add_8.3c \ - atomic_add_8_nv.3c \ - atomic_add_char.3c \ - atomic_add_char_nv.3c \ - atomic_add_int.3c \ - atomic_add_int_nv.3c \ - atomic_add_long.3c \ - atomic_add_long_nv.3c \ - atomic_add_ptr.3c \ - atomic_add_ptr_nv.3c \ - atomic_add_short.3c \ - atomic_add_short_nv.3c \ - atomic_and_16.3c \ - atomic_and_16_nv.3c \ - atomic_and_32.3c \ - atomic_and_32_nv.3c \ - atomic_and_64.3c \ - atomic_and_64_nv.3c \ - atomic_and_8.3c \ - atomic_and_8_nv.3c \ - atomic_and_uchar.3c \ - atomic_and_uchar_nv.3c \ - atomic_and_uint.3c \ - atomic_and_uint_nv.3c \ - atomic_and_ulong.3c \ - atomic_and_ulong_nv.3c \ - atomic_and_ushort.3c \ - atomic_and_ushort_nv.3c \ - atomic_cas_16.3c \ - atomic_cas_32.3c \ - atomic_cas_64.3c \ - atomic_cas_8.3c \ - atomic_cas_ptr.3c \ - atomic_cas_uchar.3c \ - atomic_cas_uint.3c \ - atomic_cas_ulong.3c \ - atomic_cas_ushort.3c \ - atomic_clear_long_excl.3c \ - atomic_dec_16.3c \ - atomic_dec_16_nv.3c \ - atomic_dec_32.3c \ - atomic_dec_32_nv.3c \ - atomic_dec_64.3c \ - atomic_dec_64_nv.3c \ - atomic_dec_8.3c \ - atomic_dec_8_nv.3c \ - atomic_dec_ptr.3c \ - atomic_dec_ptr_nv.3c \ - atomic_dec_uchar.3c \ - atomic_dec_uchar_nv.3c \ - atomic_dec_uint.3c \ - atomic_dec_uint_nv.3c \ - atomic_dec_ulong.3c \ - atomic_dec_ulong_nv.3c \ - atomic_dec_ushort.3c \ - atomic_dec_ushort_nv.3c \ - atomic_inc_16.3c \ - atomic_inc_16_nv.3c \ - atomic_inc_32.3c \ - atomic_inc_32_nv.3c \ - atomic_inc_64.3c \ - atomic_inc_64_nv.3c \ - atomic_inc_8.3c \ - atomic_inc_8_nv.3c \ - atomic_inc_ptr.3c \ - atomic_inc_ptr_nv.3c \ - atomic_inc_uchar.3c \ - atomic_inc_uchar_nv.3c \ - atomic_inc_uint.3c \ - atomic_inc_uint_nv.3c \ - atomic_inc_ulong.3c \ - atomic_inc_ulong_nv.3c \ - atomic_inc_ushort.3c \ - atomic_inc_ushort_nv.3c \ - atomic_or_16.3c \ - atomic_or_16_nv.3c \ - atomic_or_32.3c \ - atomic_or_32_nv.3c \ - atomic_or_64.3c \ - atomic_or_64_nv.3c \ - atomic_or_8.3c \ - atomic_or_8_nv.3c \ - atomic_or_uchar.3c \ - atomic_or_uchar_nv.3c \ - atomic_or_uint.3c \ - atomic_or_uint_nv.3c \ - atomic_or_ulong.3c \ - atomic_or_ulong_nv.3c \ - atomic_or_ushort.3c \ - atomic_or_ushort_nv.3c \ - atomic_set_long_excl.3c \ - atomic_swap_16.3c \ - atomic_swap_32.3c \ - atomic_swap_64.3c \ - atomic_swap_8.3c \ - atomic_swap_ptr.3c \ - atomic_swap_uchar.3c \ - atomic_swap_uint.3c \ - atomic_swap_ulong.3c \ - atomic_swap_ushort.3c \ - backtrace.3c \ - backtrace_symbols.3c \ - backtrace_symbols_fd.3c \ - bcmp.3c \ - bcopy.3c \ + ascftime.3c \ + asctime.3c \ + asctime_r.3c \ + asprintf.3c \ + at_quick_exit.3c \ + atof.3c \ + atoi.3c \ + atol.3c \ + atoll.3c \ + atomic_add_16.3c \ + atomic_add_16_nv.3c \ + atomic_add_32.3c \ + atomic_add_32_nv.3c \ + atomic_add_64.3c \ + atomic_add_64_nv.3c \ + atomic_add_8.3c \ + atomic_add_8_nv.3c \ + atomic_add_char.3c \ + atomic_add_char_nv.3c \ + atomic_add_int.3c \ + atomic_add_int_nv.3c \ + atomic_add_long.3c \ + atomic_add_long_nv.3c \ + atomic_add_ptr.3c \ + atomic_add_ptr_nv.3c \ + atomic_add_short.3c \ + atomic_add_short_nv.3c \ + atomic_and_16.3c \ + atomic_and_16_nv.3c \ + atomic_and_32.3c \ + atomic_and_32_nv.3c \ + atomic_and_64.3c \ + atomic_and_64_nv.3c \ + atomic_and_8.3c \ + atomic_and_8_nv.3c \ + atomic_and_uchar.3c \ + atomic_and_uchar_nv.3c \ + atomic_and_uint.3c \ + atomic_and_uint_nv.3c \ + atomic_and_ulong.3c \ + atomic_and_ulong_nv.3c \ + atomic_and_ushort.3c \ + atomic_and_ushort_nv.3c \ + atomic_cas_16.3c \ + atomic_cas_32.3c \ + atomic_cas_64.3c \ + atomic_cas_8.3c \ + atomic_cas_ptr.3c \ + atomic_cas_uchar.3c \ + atomic_cas_uint.3c \ + atomic_cas_ulong.3c \ + atomic_cas_ushort.3c \ + atomic_clear_long_excl.3c \ + atomic_dec_16.3c \ + atomic_dec_16_nv.3c \ + atomic_dec_32.3c \ + atomic_dec_32_nv.3c \ + atomic_dec_64.3c \ + atomic_dec_64_nv.3c \ + atomic_dec_8.3c \ + atomic_dec_8_nv.3c \ + atomic_dec_ptr.3c \ + atomic_dec_ptr_nv.3c \ + atomic_dec_uchar.3c \ + atomic_dec_uchar_nv.3c \ + atomic_dec_uint.3c \ + atomic_dec_uint_nv.3c \ + atomic_dec_ulong.3c \ + atomic_dec_ulong_nv.3c \ + atomic_dec_ushort.3c \ + atomic_dec_ushort_nv.3c \ + atomic_inc_16.3c \ + atomic_inc_16_nv.3c \ + atomic_inc_32.3c \ + atomic_inc_32_nv.3c \ + atomic_inc_64.3c \ + atomic_inc_64_nv.3c \ + atomic_inc_8.3c \ + atomic_inc_8_nv.3c \ + atomic_inc_ptr.3c \ + atomic_inc_ptr_nv.3c \ + atomic_inc_uchar.3c \ + atomic_inc_uchar_nv.3c \ + atomic_inc_uint.3c \ + atomic_inc_uint_nv.3c \ + atomic_inc_ulong.3c \ + atomic_inc_ulong_nv.3c \ + atomic_inc_ushort.3c \ + atomic_inc_ushort_nv.3c \ + atomic_or_16.3c \ + atomic_or_16_nv.3c \ + atomic_or_32.3c \ + atomic_or_32_nv.3c \ + atomic_or_64.3c \ + atomic_or_64_nv.3c \ + atomic_or_8.3c \ + atomic_or_8_nv.3c \ + atomic_or_uchar.3c \ + atomic_or_uchar_nv.3c \ + atomic_or_uint.3c \ + atomic_or_uint_nv.3c \ + atomic_or_ulong.3c \ + atomic_or_ulong_nv.3c \ + atomic_or_ushort.3c \ + atomic_or_ushort_nv.3c \ + atomic_set_long_excl.3c \ + atomic_swap_16.3c \ + atomic_swap_32.3c \ + atomic_swap_64.3c \ + atomic_swap_8.3c \ + atomic_swap_ptr.3c \ + atomic_swap_uchar.3c \ + atomic_swap_uint.3c \ + atomic_swap_ulong.3c \ + atomic_swap_ushort.3c \ + backtrace.3c \ + backtrace_symbols.3c \ + backtrace_symbols_fd.3c \ + bcmp.3c \ + bcopy.3c \ be16toh.3c \ be32toh.3c \ be64toh.3c \ betoh16.3c \ betoh32.3c \ betoh64.3c \ - bind_textdomain_codeset.3c \ - bindtextdomain.3c \ - btowc_l.3c \ - bzero.3c \ - calloc.3c \ + bind_textdomain_codeset.3c \ + bindtextdomain.3c \ + btowc_l.3c \ + bzero.3c \ + calloc.3c \ canonicalize_file_name.3c \ - catclose.3c \ - cfgetospeed.3c \ - cfsetospeed.3c \ - cftime.3c \ - clearerr.3c \ - clock_getres.3c \ - clock_gettime.3c \ - closelog.3c \ + catclose.3c \ + cfgetospeed.3c \ + cfsetospeed.3c \ + cftime.3c \ + clearerr.3c \ + clock_getres.3c \ + clock_gettime.3c \ + closelog.3c \ cnd_broadcast.3c \ cnd_destroy.3c \ cnd_init.3c \ cnd_signal.3c \ cnd_timedwait.3c \ cnd_wait.3c \ - cond_broadcast.3c \ - cond_destroy.3c \ - cond_reltimedwait.3c \ - cond_signal.3c \ - cond_timedwait.3c \ - cond_wait.3c \ - csetcol.3c \ - csetlen.3c \ - csetno.3c \ - ctermid_r.3c \ - ctime_r.3c \ - dbm_clearerr.3c \ - dbm_close.3c \ - dbm_delete.3c \ - dbm_error.3c \ - dbm_fetch.3c \ - dbm_firstkey.3c \ - dbm_nextkey.3c \ - dbm_open.3c \ - dbm_store.3c \ - dcgettext.3c \ - dcngettext.3c \ - decimal_to_double.3c \ - decimal_to_extended.3c \ - decimal_to_quadruple.3c \ - decimal_to_single.3c \ - dgettext.3c \ - dladdr1.3c \ - dlmopen.3c \ - dngettext.3c \ - door_setparam.3c \ - door_unbind.3c \ - double_to_decimal.3c \ + cond_broadcast.3c \ + cond_destroy.3c \ + cond_reltimedwait.3c \ + cond_signal.3c \ + cond_timedwait.3c \ + cond_wait.3c \ + csetcol.3c \ + csetlen.3c \ + csetno.3c \ + ctermid_r.3c \ + ctime_r.3c \ + dbm_clearerr.3c \ + dbm_close.3c \ + dbm_delete.3c \ + dbm_error.3c \ + dbm_fetch.3c \ + dbm_firstkey.3c \ + dbm_nextkey.3c \ + dbm_open.3c \ + dbm_store.3c \ + dcgettext.3c \ + dcngettext.3c \ + decimal_to_double.3c \ + decimal_to_extended.3c \ + decimal_to_quadruple.3c \ + decimal_to_single.3c \ + dgettext.3c \ + dladdr1.3c \ + dlmopen.3c \ + dngettext.3c \ + door_setparam.3c \ + door_unbind.3c \ + double_to_decimal.3c \ dup3.3c \ - duplocale.3c \ - edata.3c \ - endgrent.3c \ - endnetgrent.3c \ - endpwent.3c \ - endspent.3c \ - endusershell.3c \ - endutent.3c \ - endutxent.3c \ - epoll_create1.3c \ - epoll_pwait.3c \ - erand48.3c \ - errno.3c \ - errx.3c \ - etext.3c \ - euccol.3c \ - eucscol.3c \ + duplocale.3c \ + edata.3c \ + endgrent.3c \ + endnetgrent.3c \ + endpwent.3c \ + endspent.3c \ + endusershell.3c \ + endutent.3c \ + endutxent.3c \ + epoll_create1.3c \ + epoll_pwait.3c \ + erand48.3c \ + errno.3c \ + errx.3c \ + etext.3c \ + euccol.3c \ + eucscol.3c \ explicit_bzero.3c \ - extended_to_decimal.3c \ - fconvert.3c \ - fcvt.3c \ - fdopendir.3c \ - fdwalk.3c \ - feof.3c \ + extended_to_decimal.3c \ + fconvert.3c \ + fcvt.3c \ + fdopendir.3c \ + fdwalk.3c \ + feof.3c \ ffsl.3c \ ffsll.3c \ - fgetgrent.3c \ - fgetgrent_r.3c \ - fgetpwent.3c \ - fgetpwent_r.3c \ - fgets.3c \ - fgetspent.3c \ - fgetspent_r.3c \ - fgetwc_l.3c \ - fgetws.3c \ - file_to_decimal.3c \ - fileno.3c \ - finite.3c \ + fgetgrent.3c \ + fgetgrent_r.3c \ + fgetpwent.3c \ + fgetpwent_r.3c \ + fgets.3c \ + fgetspent.3c \ + fgetspent_r.3c \ + fgetwc_l.3c \ + fgetws.3c \ + file_to_decimal.3c \ + fileno.3c \ + finite.3c \ fls.3c \ flsl.3c \ flsll.3c \ - fpclass.3c \ - fpgetmask.3c \ - fpgetsticky.3c \ - fprintf.3c \ - fpsetmask.3c \ - fpsetround.3c \ - fpsetsticky.3c \ - fputs.3c \ - free.3c \ - freelocale.3c \ - fscanf.3c \ - fseeko.3c \ - fsetattr.3c \ - ftello.3c \ - ftruncate.3c \ - ftrylockfile.3c \ - func_to_decimal.3c \ - funlockfile.3c \ - gconvert.3c \ - gcvt.3c \ - getattrat.3c \ - getc.3c \ - getc_unlocked.3c \ - getchar.3c \ - getchar_unlocked.3c \ - getdelim.3c \ - getextmntent.3c \ - getgrent.3c \ - getgrent_r.3c \ - getgrgid.3c \ - getgrgid_r.3c \ - getgrnam_r.3c \ - gethomelgroup.3c \ - gethrvtime.3c \ - getlogin_r.3c \ - getmntany.3c \ - getnetgrent_r.3c \ + fpclass.3c \ + fpgetmask.3c \ + fpgetsticky.3c \ + fprintf.3c \ + fpsetmask.3c \ + fpsetround.3c \ + fpsetsticky.3c \ + fputs.3c \ + free.3c \ + freelocale.3c \ + fscanf.3c \ + fseeko.3c \ + fsetattr.3c \ + ftello.3c \ + ftruncate.3c \ + ftrylockfile.3c \ + fts_children.3c \ + fts_close.3c \ + fts_open.3c \ + fts_read.3c \ + fts_set.3c \ + func_to_decimal.3c \ + funlockfile.3c \ + gconvert.3c \ + gcvt.3c \ get_nprocs_conf.3c \ - getpassphrase.3c \ - getpwent.3c \ - getpwent_r.3c \ - getpwnam_r.3c \ - getpwuid.3c \ - getpwuid_r.3c \ - getspent.3c \ - getspent_r.3c \ - getspnam_r.3c \ - getutid.3c \ - getutline.3c \ - getutmp.3c \ - getutmpx.3c \ - getutxid.3c \ - getutxline.3c \ - getvfsany.3c \ - getvfsfile.3c \ - getvfsspec.3c \ - getw.3c \ - getwc_l.3c \ - getwchar_l.3c \ - getzoneidbyname.3c \ - getzonenamebyid.3c \ - globfree.3c \ - gmtime.3c \ - gmtime_r.3c \ - gsignal.3c \ - hasmntopt.3c \ - hcreate.3c \ - hdestroy.3c \ + getattrat.3c \ + getc.3c \ + getc_unlocked.3c \ + getchar.3c \ + getchar_unlocked.3c \ + getdelim.3c \ + getextmntent.3c \ + getgrent.3c \ + getgrent_r.3c \ + getgrgid.3c \ + getgrgid_r.3c \ + getgrnam_r.3c \ + gethomelgroup.3c \ + gethrvtime.3c \ + getlogin_r.3c \ + getmntany.3c \ + getnetgrent_r.3c \ + getpassphrase.3c \ + getpwent.3c \ + getpwent_r.3c \ + getpwnam_r.3c \ + getpwuid.3c \ + getpwuid_r.3c \ + getspent.3c \ + getspent_r.3c \ + getspnam_r.3c \ + getutid.3c \ + getutline.3c \ + getutmp.3c \ + getutmpx.3c \ + getutxid.3c \ + getutxline.3c \ + getvfsany.3c \ + getvfsfile.3c \ + getvfsspec.3c \ + getw.3c \ + getwc_l.3c \ + getwchar_l.3c \ + getzoneidbyname.3c \ + getzonenamebyid.3c \ + globfree.3c \ + gmtime.3c \ + gmtime_r.3c \ + gsignal.3c \ + hasmntopt.3c \ + hcreate.3c \ + hdestroy.3c \ htobe16.3c \ htobe32.3c \ htobe64.3c \ htole16.3c \ htole32.3c \ htole64.3c \ - initstate.3c \ - innetgr.3c \ - isalnum.3c \ - isalnum_l.3c \ - isalpha.3c \ - isalpha_l.3c \ - isascii.3c \ - isblank.3c \ - isblank_l.3c \ - iscntrl.3c \ - iscntrl_l.3c \ - isdigit.3c \ - isdigit_l.3c \ - isenglish.3c \ - isgraph.3c \ - isgraph_l.3c \ - isideogram.3c \ - islower.3c \ - islower_l.3c \ - isnanf.3c \ - isnumber.3c \ - isphonogram.3c \ - isprint.3c \ - isprint_l.3c \ - ispunct.3c \ - ispunct_l.3c \ - isspace.3c \ - isspace_l.3c \ - isspecial.3c \ - isupper.3c \ - isupper_l.3c \ - iswalnum.3c \ - iswalnum_l.3c \ - iswalpha_l.3c \ - iswascii.3c \ - iswblank.3c \ - iswblank_l.3c \ - iswcntrl.3c \ - iswcntrl_l.3c \ - iswctype_l.3c \ - iswdigit.3c \ - iswdigit_l.3c \ - iswgraph.3c \ - iswgraph_l.3c \ - iswideogram.3c \ - iswideogram_l.3c \ - iswhexnumber.3c \ - iswhexnumber_l.3c \ - iswlower.3c \ - iswlower_l.3c \ - iswnumber.3c \ - iswnumber_l.3c \ - iswphonogram.3c \ - iswphonogram_l.3c \ - iswprint.3c \ - iswprint_l.3c \ - iswpunct.3c \ - iswpunct_l.3c \ - iswspace.3c \ - iswspace_l.3c \ - iswspecial.3c \ - iswspecial_l.3c \ - iswupper.3c \ - iswupper_l.3c \ - iswxdigit.3c \ - iswxdigit_l.3c \ - isxdigit.3c \ - isxdigit_l.3c \ - jrand48.3c \ - l64a.3c \ - labs.3c \ - lcong48.3c \ - ldiv.3c \ + initstate.3c \ + innetgr.3c \ + isalnum.3c \ + isalnum_l.3c \ + isalpha.3c \ + isalpha_l.3c \ + isascii.3c \ + isblank.3c \ + isblank_l.3c \ + iscntrl.3c \ + iscntrl_l.3c \ + isdigit.3c \ + isdigit_l.3c \ + isenglish.3c \ + isgraph.3c \ + isgraph_l.3c \ + isideogram.3c \ + islower.3c \ + islower_l.3c \ + isnanf.3c \ + isnumber.3c \ + isphonogram.3c \ + isprint.3c \ + isprint_l.3c \ + ispunct.3c \ + ispunct_l.3c \ + isspace.3c \ + isspace_l.3c \ + isspecial.3c \ + isupper.3c \ + isupper_l.3c \ + iswalnum.3c \ + iswalnum_l.3c \ + iswalpha_l.3c \ + iswascii.3c \ + iswblank.3c \ + iswblank_l.3c \ + iswcntrl.3c \ + iswcntrl_l.3c \ + iswctype_l.3c \ + iswdigit.3c \ + iswdigit_l.3c \ + iswgraph.3c \ + iswgraph_l.3c \ + iswhexnumber.3c \ + iswhexnumber_l.3c \ + iswideogram.3c \ + iswideogram_l.3c \ + iswlower.3c \ + iswlower_l.3c \ + iswnumber.3c \ + iswnumber_l.3c \ + iswphonogram.3c \ + iswphonogram_l.3c \ + iswprint.3c \ + iswprint_l.3c \ + iswpunct.3c \ + iswpunct_l.3c \ + iswspace.3c \ + iswspace_l.3c \ + iswspecial.3c \ + iswspecial_l.3c \ + iswupper.3c \ + iswupper_l.3c \ + iswxdigit.3c \ + iswxdigit_l.3c \ + isxdigit.3c \ + isxdigit_l.3c \ + jrand48.3c \ + l64a.3c \ + labs.3c \ + lcong48.3c \ + ldiv.3c \ le16toh.3c \ le32toh.3c \ le64toh.3c \ letoh16.3c \ letoh32.3c \ letoh64.3c \ - lfind.3c \ - llabs.3c \ - lldiv.3c \ - lltostr.3c \ - localtime.3c \ - localtime_r.3c \ - longjmp.3c \ - lrand48.3c \ - major.3c \ - mblen_l.3c \ - mbrlen_l.3c \ - mbrtowc_l.3c \ - mbsinit_l.3c \ - mbsnrtowcs.3c \ - mbsnrtowcs_l.3c \ - mbsrtowcs_l.3c \ - mbstowcs_l.3c \ - mbtowc_l.3c \ - memalign.3c \ - membar_consumer.3c \ - membar_enter.3c \ - membar_exit.3c \ - membar_producer.3c \ - memccpy.3c \ - memchr.3c \ - memcmp.3c \ - memcpy.3c \ - memmem.3c \ - memmove.3c \ - memset.3c \ - minor.3c \ - mkdtemp.3c \ + lfind.3c \ + llabs.3c \ + lldiv.3c \ + lltostr.3c \ + localtime.3c \ + localtime_r.3c \ + longjmp.3c \ + lrand48.3c \ + major.3c \ + mblen_l.3c \ + mbrlen_l.3c \ + mbrtowc_l.3c \ + mbsinit_l.3c \ + mbsnrtowcs.3c \ + mbsnrtowcs_l.3c \ + mbsrtowcs_l.3c \ + mbstowcs_l.3c \ + mbtowc_l.3c \ + memalign.3c \ + membar_consumer.3c \ + membar_enter.3c \ + membar_exit.3c \ + membar_producer.3c \ + memccpy.3c \ + memchr.3c \ + memcmp.3c \ + memcpy.3c \ + memmem.3c \ + memmove.3c \ + memset.3c \ + minor.3c \ + mkdtemp.3c \ mkfifoat.3c \ mkostemp.3c \ mkostemps.3c \ - mkstemps.3c \ - mq_reltimedreceive_np.3c \ - mq_reltimedsend_np.3c \ - mq_timedreceive.3c \ - mq_timedsend.3c \ - mrand48.3c \ + mkstemps.3c \ + mq_reltimedreceive_np.3c \ + mq_reltimedsend_np.3c \ + mq_timedreceive.3c \ + mq_timedsend.3c \ + mrand48.3c \ mtx_destroy.3c \ mtx_init.3c \ mtx_lock.3c \ mtx_timedlock.3c \ mtx_trylock.3c \ mtx_unlock.3c \ - munlock.3c \ - munlockall.3c \ - mutex_consistent.3c \ - mutex_destroy.3c \ - mutex_lock.3c \ - mutex_trylock.3c \ - mutex_unlock.3c \ - nl_langinfo_l.3c \ - nftw.3c \ - ngettext.3c \ - nrand48.3c \ - openlog.3c \ - pclose.3c \ - port_dissociate.3c \ - port_getn.3c \ - port_sendn.3c \ - posix_spawn_file_actions_addopen.3c \ - posix_spawn_file_actions_init.3c \ - posix_spawnattr_init.3c \ - posix_spawnattr_setflags.3c \ - posix_spawnattr_setpgroup.3c \ - posix_spawnattr_setschedparam.3c \ - posix_spawnattr_setschedpolicy.3c \ - posix_spawnattr_setsigdefault.3c \ - posix_spawnattr_setsigignore_np.3c \ - posix_spawnattr_setsigmask.3c \ - posix_spawnp.3c \ - printstack.3c \ - priv_allocset.3c \ - priv_basicset.3c \ - priv_copyset.3c \ - priv_delset.3c \ - priv_emptyset.3c \ - priv_fillset.3c \ - priv_freeset.3c \ - priv_getbyname.3c \ - priv_getbynum.3c \ - priv_getsetbyname.3c \ - priv_getsetbynum.3c \ - priv_gettext.3c \ - priv_ineffect.3c \ - priv_intersect.3c \ - priv_inverse.3c \ - priv_isemptyset.3c \ - priv_isequalset.3c \ - priv_isfullset.3c \ - priv_ismember.3c \ - priv_issubset.3c \ - priv_set_to_str.3c \ - priv_union.3c \ - pselect.3c \ - psiginfo.3c \ - pthread_attr_destroy.3c \ - pthread_attr_setdetachstate.3c \ - pthread_attr_setguardsize.3c \ - pthread_attr_setinheritsched.3c \ - pthread_attr_setschedparam.3c \ - pthread_attr_setschedpolicy.3c \ - pthread_attr_setscope.3c \ - pthread_attr_setstack.3c \ - pthread_attr_setstackaddr.3c \ - pthread_attr_setstacksize.3c \ - pthread_barrier_init.3c \ - pthread_barrierattr_init.3c \ - pthread_barrierattr_setpshared.3c \ - pthread_cond_broadcast.3c \ - pthread_cond_destroy.3c \ - pthread_cond_reltimedwait_np.3c \ - pthread_cond_timedwait.3c \ - pthread_condattr_destroy.3c \ - pthread_condattr_setclock.3c \ - pthread_condattr_setpshared.3c \ - pthread_key_create_once_np.3c \ - pthread_mutex_destroy.3c \ - pthread_mutex_reltimedlock_np.3c \ - pthread_mutex_setprioceiling.3c \ - pthread_mutex_trylock.3c \ - pthread_mutex_unlock.3c \ - pthread_mutexattr_destroy.3c \ - pthread_mutexattr_setprioceiling.3c \ - pthread_mutexattr_setprotocol.3c \ - pthread_mutexattr_setpshared.3c \ - pthread_mutexattr_setrobust.3c \ - pthread_mutexattr_settype.3c \ - pthread_rwlock_destroy.3c \ - pthread_rwlock_reltimedrdlock_np.3c \ - pthread_rwlock_reltimedwrlock_np.3c \ - pthread_rwlock_tryrdlock.3c \ - pthread_rwlock_trywrlock.3c \ - pthread_rwlockattr_destroy.3c \ - pthread_rwlockattr_setpshared.3c \ - pthread_setconcurrency.3c \ - pthread_setschedparam.3c \ - pthread_setspecific.3c \ - pthread_spin_init.3c \ - pthread_spin_trylock.3c \ - putc.3c \ - putc_unlocked.3c \ - putchar.3c \ - putchar_unlocked.3c \ - putmntent.3c \ - pututline.3c \ - pututxline.3c \ - putw.3c \ - putwc.3c \ - putwchar.3c \ - qeconvert.3c \ - qfconvert.3c \ - qgconvert.3c \ - quadruple_to_decimal.3c \ - rand_r.3c \ - rctlblk_get_enforced_value.3c \ - rctlblk_get_firing_time.3c \ - rctlblk_get_global_action.3c \ - rctlblk_get_global_flags.3c \ - rctlblk_get_local_action.3c \ - rctlblk_get_local_flags.3c \ - rctlblk_get_privilege.3c \ - rctlblk_get_recipient_pid.3c \ - rctlblk_get_value.3c \ - rctlblk_set_local_action.3c \ - rctlblk_set_local_flags.3c \ - rctlblk_set_privilege.3c \ - rctlblk_set_recipient_pid.3c \ - rctlblk_size.3c \ - re_exec.3c \ - readdir_r.3c \ - realloc.3c \ - regerror.3c \ - regex.3c \ - regexec.3c \ - regfree.3c \ - remque.3c \ - resetmnttab.3c \ - rindex.3c \ - rw_rdlock.3c \ - rw_tryrdlock.3c \ - rw_trywrlock.3c \ - rw_unlock.3c \ - rw_wrlock.3c \ - rwlock_destroy.3c \ - rwlock_init.3c \ - sched_get_priority_min.3c \ - schedctl_exit.3c \ - schedctl_lookup.3c \ - schedctl_start.3c \ - schedctl_stop.3c \ - seconvert.3c \ - seed48.3c \ - sem_reltimedwait_np.3c \ - sem_trywait.3c \ - sema_destroy.3c \ - sema_init.3c \ - sema_post.3c \ - sema_trywait.3c \ - sema_wait.3c \ - setattrat.3c \ - setgrent.3c \ - sethostname.3c \ - setlinebuf.3c \ - setlogmask.3c \ - setnetgrent.3c \ - setpriority.3c \ + munlock.3c \ + munlockall.3c \ + mutex_consistent.3c \ + mutex_destroy.3c \ + mutex_lock.3c \ + mutex_trylock.3c \ + mutex_unlock.3c \ + nftw.3c \ + ngettext.3c \ + nl_langinfo_l.3c \ + nrand48.3c \ + openlog.3c \ + pclose.3c \ + port_dissociate.3c \ + port_getn.3c \ + port_sendn.3c \ + posix_spawn_file_actions_addopen.3c \ + posix_spawn_file_actions_init.3c \ + posix_spawnattr_init.3c \ + posix_spawnattr_setflags.3c \ + posix_spawnattr_setpgroup.3c \ + posix_spawnattr_setschedparam.3c \ + posix_spawnattr_setschedpolicy.3c \ + posix_spawnattr_setsigdefault.3c \ + posix_spawnattr_setsigignore_np.3c \ + posix_spawnattr_setsigmask.3c \ + posix_spawnp.3c \ + printstack.3c \ + priv_allocset.3c \ + priv_basicset.3c \ + priv_copyset.3c \ + priv_delset.3c \ + priv_emptyset.3c \ + priv_fillset.3c \ + priv_freeset.3c \ + priv_getbyname.3c \ + priv_getbynum.3c \ + priv_getsetbyname.3c \ + priv_getsetbynum.3c \ + priv_gettext.3c \ + priv_ineffect.3c \ + priv_intersect.3c \ + priv_inverse.3c \ + priv_isemptyset.3c \ + priv_isequalset.3c \ + priv_isfullset.3c \ + priv_ismember.3c \ + priv_issubset.3c \ + priv_set_to_str.3c \ + priv_union.3c \ + pselect.3c \ + psiginfo.3c \ + pthread_attr_destroy.3c \ + pthread_attr_setdetachstate.3c \ + pthread_attr_setguardsize.3c \ + pthread_attr_setinheritsched.3c \ + pthread_attr_setschedparam.3c \ + pthread_attr_setschedpolicy.3c \ + pthread_attr_setscope.3c \ + pthread_attr_setstack.3c \ + pthread_attr_setstackaddr.3c \ + pthread_attr_setstacksize.3c \ + pthread_barrier_init.3c \ + pthread_barrierattr_init.3c \ + pthread_barrierattr_setpshared.3c \ + pthread_cond_broadcast.3c \ + pthread_cond_destroy.3c \ + pthread_cond_reltimedwait_np.3c \ + pthread_cond_timedwait.3c \ + pthread_condattr_destroy.3c \ + pthread_condattr_setclock.3c \ + pthread_condattr_setpshared.3c \ + pthread_key_create_once_np.3c \ + pthread_mutex_destroy.3c \ + pthread_mutex_reltimedlock_np.3c \ + pthread_mutex_setprioceiling.3c \ + pthread_mutex_trylock.3c \ + pthread_mutex_unlock.3c \ + pthread_mutexattr_destroy.3c \ + pthread_mutexattr_setprioceiling.3c \ + pthread_mutexattr_setprotocol.3c \ + pthread_mutexattr_setpshared.3c \ + pthread_mutexattr_setrobust.3c \ + pthread_mutexattr_settype.3c \ + pthread_rwlock_destroy.3c \ + pthread_rwlock_reltimedrdlock_np.3c \ + pthread_rwlock_reltimedwrlock_np.3c \ + pthread_rwlock_tryrdlock.3c \ + pthread_rwlock_trywrlock.3c \ + pthread_rwlockattr_destroy.3c \ + pthread_rwlockattr_setpshared.3c \ + pthread_setconcurrency.3c \ + pthread_setschedparam.3c \ + pthread_setspecific.3c \ + pthread_spin_init.3c \ + pthread_spin_trylock.3c \ + putc.3c \ + putc_unlocked.3c \ + putchar.3c \ + putchar_unlocked.3c \ + putmntent.3c \ + pututline.3c \ + pututxline.3c \ + putw.3c \ + putwc.3c \ + putwchar.3c \ + qeconvert.3c \ + qfconvert.3c \ + qgconvert.3c \ + quadruple_to_decimal.3c \ + rand_r.3c \ + rctlblk_get_enforced_value.3c \ + rctlblk_get_firing_time.3c \ + rctlblk_get_global_action.3c \ + rctlblk_get_global_flags.3c \ + rctlblk_get_local_action.3c \ + rctlblk_get_local_flags.3c \ + rctlblk_get_privilege.3c \ + rctlblk_get_recipient_pid.3c \ + rctlblk_get_value.3c \ + rctlblk_set_local_action.3c \ + rctlblk_set_local_flags.3c \ + rctlblk_set_privilege.3c \ + rctlblk_set_recipient_pid.3c \ + rctlblk_size.3c \ + re_exec.3c \ + readdir_r.3c \ + realloc.3c \ + reallocarray.3c \ + regerror.3c \ + regex.3c \ + regexec.3c \ + regfree.3c \ + remque.3c \ + resetmnttab.3c \ + rindex.3c \ + rw_rdlock.3c \ + rw_tryrdlock.3c \ + rw_trywrlock.3c \ + rw_unlock.3c \ + rw_wrlock.3c \ + rwlock_destroy.3c \ + rwlock_init.3c \ + sched_get_priority_min.3c \ + schedctl_exit.3c \ + schedctl_lookup.3c \ + schedctl_start.3c \ + schedctl_stop.3c \ + seconvert.3c \ + seed48.3c \ + sem_reltimedwait_np.3c \ + sem_trywait.3c \ + sema_destroy.3c \ + sema_init.3c \ + sema_post.3c \ + sema_trywait.3c \ + sema_wait.3c \ + setattrat.3c \ + setgrent.3c \ + sethostname.3c \ + setlinebuf.3c \ + setlogmask.3c \ + setnetgrent.3c \ + setpriority.3c \ setprogname.3c \ - setpwent.3c \ - setspent.3c \ - setstate.3c \ - settimeofday.3c \ - setusershell.3c \ - setutent.3c \ - setutxent.3c \ - setvbuf.3c \ - sfconvert.3c \ - sgconvert.3c \ - sig2str.3c \ - sigaddset.3c \ - sigdelset.3c \ - sigemptyset.3c \ - sigfillset.3c \ - sighold.3c \ - sigignore.3c \ - sigismember.3c \ - siglongjmp.3c \ - sigpause.3c \ - sigrelse.3c \ - sigset.3c \ - sigsetjmp.3c \ - sigtimedwait.3c \ - single_to_decimal.3c \ - snprintf.3c \ - sprintf.3c \ - srand.3c \ - srand48.3c \ - srandom.3c \ - sscanf.3c \ + setpwent.3c \ + setspent.3c \ + setstate.3c \ + settimeofday.3c \ + setusershell.3c \ + setutent.3c \ + setutxent.3c \ + setvbuf.3c \ + sfconvert.3c \ + sgconvert.3c \ + sig2str.3c \ + sigaddset.3c \ + sigdelset.3c \ + sigemptyset.3c \ + sigfillset.3c \ + sighold.3c \ + sigignore.3c \ + sigismember.3c \ + siglongjmp.3c \ + sigpause.3c \ + sigrelse.3c \ + sigset.3c \ + sigsetjmp.3c \ + sigtimedwait.3c \ + single_to_decimal.3c \ + snprintf.3c \ + sprintf.3c \ + srand.3c \ + srand48.3c \ + srandom.3c \ + sscanf.3c \ stderr.3c \ stdin.3c \ stdout.3c \ stpcpy.3c \ stpncpy.3c \ - strcasecmp.3c \ - strcasecmp_l.3c \ + strcasecmp.3c \ + strcasecmp_l.3c \ strcasestr.3c \ strcasestr_l.3c \ - strcat.3c \ - strchr.3c \ + strcat.3c \ + strchr.3c \ strchrnul.3c \ - strcmp.3c \ - strcoll_l.3c \ - strcpy.3c \ - strcspn.3c \ - strdup.3c \ - strdupa.3c \ - strerror_l.3c \ - strerror_r.3c \ - strfmon_l.3c \ - strftime_l.3c \ - strlcat.3c \ - strlcpy.3c \ - strlen.3c \ - strncasecmp.3c \ - strncasecmp_l.3c \ - strncat.3c \ - strncmp.3c \ - strncpy.3c \ + strcmp.3c \ + strcoll_l.3c \ + strcpy.3c \ + strcspn.3c \ + strdup.3c \ + strdupa.3c \ + strerror_l.3c \ + strerror_r.3c \ + strfmon_l.3c \ + strftime_l.3c \ + strlcat.3c \ + strlcpy.3c \ + strlen.3c \ + strncasecmp.3c \ + strncasecmp_l.3c \ + strncat.3c \ + strncmp.3c \ + strncpy.3c \ strndup.3c \ strndupa.3c \ - strnlen.3c \ + strnlen.3c \ strnstr.3c \ - strpbrk.3c \ - strptime_l.3c \ - strrchr.3c \ - strsep.3c \ - strspn.3c \ - strstr.3c \ - strtof.3c \ - strtok.3c \ - strtok_r.3c \ - strtold.3c \ - strtoll.3c \ - strtoull.3c \ - strtoumax.3c \ - strxfrm_l.3c \ - swapcontext.3c \ - swprintf.3c \ - swscanf.3c \ - tdelete.3c \ - tempnam.3c \ - textdomain.3c \ - tfind.3c \ - thr_continue.3c \ - thr_getspecific.3c \ - thr_keycreate_once.3c \ - thr_setconcurrency.3c \ - thr_setprio.3c \ - thr_setspecific.3c \ + strpbrk.3c \ + strptime_l.3c \ + strrchr.3c \ + strsep.3c \ + strspn.3c \ + strstr.3c \ + strtof.3c \ + strtok.3c \ + strtok_r.3c \ + strtold.3c \ + strtoll.3c \ + strtoull.3c \ + strtoumax.3c \ + strxfrm_l.3c \ + swapcontext.3c \ + swprintf.3c \ + swscanf.3c \ + tdelete.3c \ + tempnam.3c \ + textdomain.3c \ + tfind.3c \ + thr_continue.3c \ + thr_getspecific.3c \ + thr_keycreate_once.3c \ + thr_setconcurrency.3c \ + thr_setprio.3c \ + thr_setspecific.3c \ thrd_sleep.3c \ timegm.3c \ - timer_getoverrun.3c \ - timer_gettime.3c \ - timerclear.3c \ - timercmp.3c \ + timer_getoverrun.3c \ + timer_gettime.3c \ + timerclear.3c \ + timercmp.3c \ timerfd_gettime.3c \ timerfd_settime.3c \ - timerisset.3c \ - timersub.3c \ - tmpnam_r.3c \ - tolower_l.3c \ - toupper_l.3c \ - towctrans.3c \ - towctrans_l.3c \ - towlower_l.3c \ - towupper_l.3c \ + timerisset.3c \ + timersub.3c \ + tmpnam_r.3c \ + tolower_l.3c \ + toupper_l.3c \ + towctrans.3c \ + towctrans_l.3c \ + towlower_l.3c \ + towupper_l.3c \ tss_create.3c \ tss_delete.3c \ tss_get.3c \ tss_set.3c \ - ttyname_r.3c \ - twalk.3c \ - tzset.3c \ - uconv_u16tou8.3c \ - uconv_u32tou16.3c \ - uconv_u32tou8.3c \ - uconv_u8tou16.3c \ - uconv_u8tou32.3c \ - ucred_free.3c \ - ucred_get.3c \ - ucred_getegid.3c \ - ucred_geteuid.3c \ - ucred_getgroups.3c \ - ucred_getlabel.3c \ - ucred_getpflags.3c \ - ucred_getpid.3c \ - ucred_getprivset.3c \ - ucred_getprojid.3c \ - ucred_getrgid.3c \ - ucred_getruid.3c \ - ucred_getsgid.3c \ - ucred_getsuid.3c \ - ucred_getzoneid.3c \ - ucred_size.3c \ - ulckpwdf.3c \ - ulltostr.3c \ - unordered.3c \ - updwtmp.3c \ - updwtmpx.3c \ - utmpname.3c \ - utmpxname.3c \ - valloc.3c \ - vasprintf.3c \ - verr.3c \ - verrx.3c \ - vfprintf.3c \ - vfscanf.3c \ - vfwscanf.3c \ - vscanf.3c \ - vsnprintf.3c \ - vsprintf.3c \ - vsscanf.3c \ - vswprintf.3c \ - vswscanf.3c \ - vwarn.3c \ - vwarnx.3c \ - vwprintf.3c \ - vwscanf.3c \ - wait4.3c \ - warn.3c \ - warnx.3c \ - watof.3c \ - watoi.3c \ - watol.3c \ - watoll.3c \ + ttyname_r.3c \ + twalk.3c \ + tzset.3c \ + uconv_u16tou8.3c \ + uconv_u32tou16.3c \ + uconv_u32tou8.3c \ + uconv_u8tou16.3c \ + uconv_u8tou32.3c \ + ucred_free.3c \ + ucred_get.3c \ + ucred_getegid.3c \ + ucred_geteuid.3c \ + ucred_getgroups.3c \ + ucred_getlabel.3c \ + ucred_getpflags.3c \ + ucred_getpid.3c \ + ucred_getprivset.3c \ + ucred_getprojid.3c \ + ucred_getrgid.3c \ + ucred_getruid.3c \ + ucred_getsgid.3c \ + ucred_getsuid.3c \ + ucred_getzoneid.3c \ + ucred_size.3c \ + ulckpwdf.3c \ + ulltostr.3c \ + unordered.3c \ + updwtmp.3c \ + updwtmpx.3c \ + utmpname.3c \ + utmpxname.3c \ + valloc.3c \ + vasprintf.3c \ + verr.3c \ + verrx.3c \ + vfprintf.3c \ + vfscanf.3c \ + vfwscanf.3c \ + vscanf.3c \ + vsnprintf.3c \ + vsprintf.3c \ + vsscanf.3c \ + vswprintf.3c \ + vswscanf.3c \ + vwarn.3c \ + vwarnx.3c \ + vwprintf.3c \ + vwscanf.3c \ + wait4.3c \ + warn.3c \ + warnx.3c \ + watof.3c \ + watoi.3c \ + watol.3c \ + watoll.3c \ wcpncpy.3c \ - wcrtomb_l.3c \ + wcrtomb_l.3c \ wcscasecmp_l.3c \ - wcscat.3c \ - wcschr.3c \ - wcscmp.3c \ - wcscoll_l.3c \ - wcscpy.3c \ - wcscspn.3c \ - wcsetno.3c \ + wcscat.3c \ + wcschr.3c \ + wcscmp.3c \ + wcscoll_l.3c \ + wcscpy.3c \ + wcscspn.3c \ + wcsetno.3c \ wcsncasecmp.3c \ wcsncasecmp_l.3c \ - wcsncat.3c \ - wcsncmp.3c \ - wcsncpy.3c \ - wcsnlen.3c \ + wcsncat.3c \ + wcsncmp.3c \ + wcsncpy.3c \ + wcsnlen.3c \ wcsnrtombs.3c \ wcsnrtombs_l.3c \ - wcspbrk.3c \ - wcsrchr.3c \ + wcspbrk.3c \ + wcsrchr.3c \ wcsrtombs_l.3c \ - wcsspn.3c \ - wcstof.3c \ - wcstok.3c \ - wcstold.3c \ - wcstoll.3c \ + wcsspn.3c \ + wcstof.3c \ + wcstok.3c \ + wcstold.3c \ + wcstoll.3c \ wcstombs_l.3c \ - wcstoull.3c \ - wcstoumax.3c \ - wcswcs.3c \ - wcswidth_l.3c \ - wctob_l.3c \ - wctomb_l.3c \ - wctrans_l.3c \ - wctype_l.3c \ - wcwidth_l.3c \ - windex.3c \ - wordfree.3c \ - wprintf.3c \ - wrindex.3c \ - wscanf.3c \ - wscasecmp.3c \ - wscat.3c \ - wschr.3c \ - wscmp.3c \ - wscol.3c \ - wscoll.3c \ - wscpy.3c \ - wscspn.3c \ - wsdup.3c \ - wslen.3c \ - wsncasecmp.3c \ - wsncat.3c \ - wsncmp.3c \ - wsncpy.3c \ - wspbrk.3c \ - wsrchr.3c \ - wsspn.3c \ - wstod.3c \ - wstok.3c \ - wstol.3c \ - wstostr.3c \ - wsxfrm.3c + wcstoull.3c \ + wcstoumax.3c \ + wcswcs.3c \ + wcswidth_l.3c \ + wctob_l.3c \ + wctomb_l.3c \ + wctrans_l.3c \ + wctype_l.3c \ + wcwidth_l.3c \ + windex.3c \ + wordfree.3c \ + wprintf.3c \ + wrindex.3c \ + wscanf.3c \ + wscasecmp.3c \ + wscat.3c \ + wschr.3c \ + wscmp.3c \ + wscol.3c \ + wscoll.3c \ + wscpy.3c \ + wscspn.3c \ + wsdup.3c \ + wslen.3c \ + wsncasecmp.3c \ + wsncat.3c \ + wsncmp.3c \ + wsncpy.3c \ + wspbrk.3c \ + wsrchr.3c \ + wsspn.3c \ + wstod.3c \ + wstok.3c \ + wstol.3c \ + wstostr.3c \ + wsxfrm.3c __flbf.3c := LINKSRC = __fbufsize.3c __fpending.3c := LINKSRC = __fbufsize.3c @@ -1740,6 +1748,12 @@ fseeko.3c := LINKSRC = fseek.3c ftello.3c := LINKSRC = ftell.3c +fts_children.3c := LINKSRC = fts.3c +fts_close.3c := LINKSRC = fts.3c +fts_open.3c := LINKSRC = fts.3c +fts_read.3c := LINKSRC = fts.3c +fts_set.3c := LINKSRC = fts.3c + nftw.3c := LINKSRC = ftw.3c swprintf.3c := LINKSRC = fwprintf.3c @@ -1925,6 +1939,7 @@ calloc.3c := LINKSRC = malloc.3c free.3c := LINKSRC = malloc.3c memalign.3c := LINKSRC = malloc.3c realloc.3c := LINKSRC = malloc.3c +reallocarray.3c := LINKSRC = malloc.3c valloc.3c := LINKSRC = malloc.3c mblen_l.3c := LINKSRC = mblen.3c @@ -2349,8 +2364,8 @@ timercmp.3c := LINKSRC = timeradd.3c timerisset.3c := LINKSRC = timeradd.3c timersub.3c := LINKSRC = timeradd.3c -timerfd_gettime.3c := LINKSRC = timerfd_create.3c -timerfd_settime.3c := LINKSRC = timerfd_create.3c +timerfd_gettime.3c := LINKSRC = timerfd_create.3c +timerfd_settime.3c := LINKSRC = timerfd_create.3c tempnam.3c := LINKSRC = tmpnam.3c tmpnam_r.3c := LINKSRC = tmpnam.3c diff --git a/usr/src/man/man3c/fts.3c b/usr/src/man/man3c/fts.3c new file mode 100644 index 0000000000..974c79552d --- /dev/null +++ b/usr/src/man/man3c/fts.3c @@ -0,0 +1,825 @@ +.\" +.\" Copyright (c) 1989, 1991, 1993C, 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. +.\" 3C. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" +.Dd March 28, 2017 +.Dt FTS 3C +.Os +.Sh NAME +.Nm fts_open , +.Nm fts_read , +.Nm fts_children , +.Nm fts_set , +.Nm fts_close +.Nd traverse a file hierarchy +.Sh SYNOPSIS +.In sys/types.h +.In sys/stat.h +.In fts.h +.Ft FTS * +.Fo fts_open +.Fa "char * const *path_argv" +.Fa "int options" +.Fa "int (*compar)(const FTSENT **, const FTSENT **)" +.Fc +.Ft FTSENT * +.Fn fts_read "FTS *ftsp" +.Ft FTSENT * +.Fn fts_children "FTS *ftsp" "int options" +.Ft int +.Fn fts_set "FTS *ftsp" "FTSENT *f" "int option" +.Ft int +.Fn fts_close "FTS *ftsp" +.Sh DESCRIPTION +The +.Nm fts +functions are provided for traversing +.Ux +file hierarchies. +The +.Fn fts_open +function returns a +.Dq handle +on a file hierarchy, which is then supplied to +the other +.Nm fts +functions. +The function +.Fn fts_read +returns a pointer to a structure describing one of the files in the file +hierarchy. +The function +.Fn fts_children +returns a pointer to a linked list of structures, each of which describes +one of the files contained in a directory within the hierarchy. +.Pp +In general, directories are visited two distinguishable times; in pre-order +.Pq before any of their descendants are visited +and in post-order +.Pq after all of their descendants have been visited . +Files are visited once. +It is possible to walk the hierarchy +.Dq logically +.Pq following symbolic links +or +.Dq physically +.Pq not following symbolic links , +order the walk of the hierarchy, or +prune and/or re-visit portions of the hierarchy. +.Pp +Two structures are defined +.Pq and typedef'd +in the include file +.In fts.h . +The first is +.Dv FTS , +the structure that represents the file hierarchy itself. +The second is +.Li FTSENT , +the structure that represents a file in the file +hierarchy. +Normally, an +.Li FTSENT +structure is returned for every file in the file +hierarchy. +In this manual page, +.Dq file +and +.Dq Li FTSENT No structure +are generally +interchangeable. +.Pp +The +.Li FTSENT +structure contains at least the following fields, which are +described in greater detail below: +.Bd -literal +typedef struct _ftsent { + unsigned short fts_info; /* flags for FTSENT structure */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + size_t fts_pathlen; /* strlen(fts_path) */ + char *fts_name; /* file name */ + size_t fts_namelen; /* strlen(fts_name) */ + int fts_level; /* depth (-1 to N) */ + int fts_errno; /* file errno */ + long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file structure */ + struct _ftsent *fts_cycle; /* cycle structure */ + struct stat *fts_statp; /* stat(2) information */ +} FTSENT; +.Ed +.Pp +These fields are defined as follows: +.Bl -tag -width "fts_namelen" +.It Fa fts_info +One of the following flags describing the returned +.Li FTSENT +structure and +the file it represents. +With the exception of directories without errors +.Pq Dv FTS_D , +all of these +entries are terminal, that is, they will not be revisited, nor will any +of their descendants be visited. +.Bl -tag -width FTS_DEFAULT +.It Dv FTS_D +A directory being visited in pre-order. +.It Dv FTS_DC +A directory that causes a cycle in the tree. +.Po The +.Fa fts_cycle +field of the +.Li FTSENT +structure will be filled in as well. +.Pc +.It Dv FTS_DEFAULT +Any +.Li FTSENT +structure that represents a file type not explicitly described +by one of the other +.Fa fts_info +values. +.It Dv FTS_DNR +A directory which cannot be read. +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_DOT +A file named +.Dq \&. +or +.Dq .. +which was not specified as a file name to +.Fn fts_open +.Pq see Dv FTS_SEEDOT . +.It Dv FTS_DP +A directory being visited in post-order. +The contents of the +.Li FTSENT +structure will be unchanged from when +it was returned in pre-order, i.e., with the +.Fa fts_info +field set to +.Dv FTS_D . +.It Dv FTS_ERR +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_F +A regular file. +.It Dv FTS_NS +A file for which no +.Xr stat 2 +information was available. +The contents of the +.Fa fts_statp +field are undefined. +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_NSOK +A file for which no +.Xr stat 2 +information was requested. +The contents of the +.Fa fts_statp +field are undefined. +.It Dv FTS_SL +A symbolic link. +.It Dv FTS_SLNONE +A symbolic link with a non-existent target. +The contents of the +.Fa fts_statp +field reference the file characteristic information for the symbolic link +itself. +.El +.It Fa fts_accpath +A path for accessing the file from the current directory. +.It Fa fts_path +The path for the file relative to the root of the traversal. +This path contains the path specified to +.Fn fts_open +as a prefix. +.It Fa fts_pathlen +The length of the string referenced by +.Fa fts_path . +.It Fa fts_name +The name of the file. +.It Fa fts_namelen +The length of the string referenced by +.Fa fts_name . +.It Fa fts_level +The depth of the traversal, numbered from \-1 to N, where this file +was found. +The +.Li FTSENT +structure representing the parent of the starting point +.Pq or root +of the traversal is numbered +.Dv FTS_ROOTPARENTLEVEL +.Pq \-1 , +and the +.Li FTSENT +structure for the root +itself is numbered +.Dv FTS_ROOTLEVEL +.Pq 0 . +Note that while +.Fa fts_level +cannot hold a number of levels greater than +.Dv FTS_MAXLEVEL , +the +.Nm fts +functions themselves are not limited to a fixed number +of levels. +Application code that inspects +.Fa fts_level +should be written with this in mind. +.It Fa fts_errno +Upon return of an +.Li FTSENT +structure from the +.Fn fts_children +or +.Fn fts_read +functions, with its +.Fa fts_info +field set to +.Dv FTS_DNR , +.Dv FTS_ERR +or +.Dv FTS_NS , +the +.Fa fts_errno +field contains the value of the external variable +.Va errno +specifying the cause of the error. +Otherwise, the contents of the +.Fa fts_errno +field are undefined. +.It Fa fts_number +This field is provided for the use of the application program and is +not modified by the +.Nm fts +functions. +It is initialized to 0. +.It Fa fts_pointer +This field is provided for the use of the application program and is +not modified by the +.Nm fts +functions. +It is initialized to +.Dv NULL . +.It Fa fts_parent +A pointer to the +.Li FTSENT +structure referencing the file in the hierarchy +immediately above the current file, i.e., the directory of which this +file is a member. +A parent structure for the initial entry point is provided as well, +however, only the +.Fa fts_level , +.Fa fts_number +and +.Fa fts_pointer +fields are guaranteed to be initialized. +.It Fa fts_link +Upon return from the +.Fn fts_children +function, the +.Fa fts_link +field points to the next structure in the null-terminated +linked list of directory members. +Otherwise, the contents of the +.Fa fts_link +field are undefined. +.It Fa fts_cycle +If a directory causes a cycle in the hierarchy +.Pq see Dv FTS_DC , +either because of a hard link between two directories, or a symbolic link +pointing to a directory, the +.Fa fts_cycle +field of the structure will point to the +.Li FTSENT +structure in the hierarchy that references the same file as the current +.Li FTSENT +structure. +Otherwise, the contents of the +.Fa fts_cycle +field are undefined. +.It Fa fts_statp +A pointer to +.Xr stat 2 +information for the file. +.El +.Pp +A single buffer is used for all of the paths of all of the files in the +file hierarchy. +Therefore, the +.Fa fts_path +and +.Fa fts_accpath +fields are guaranteed to be NUL terminated +.Em only +for the file most recently returned by +.Fn fts_read . +To use these fields to reference any files represented by other +.Li FTSENT +structures will require that the path buffer be modified using the +information contained in that +.Li FTSENT +structure's +.Fa fts_pathlen +field. +Any such modifications should be undone before further calls to +.Fn fts_read +are attempted. +The +.Fa fts_name +field is always NUL terminated. +.Ss FTS_OPEN +The +.Fn fts_open +function takes a pointer to an array of character pointers naming one +or more paths which make up a logical file hierarchy to be traversed. +The array must be terminated by a null pointer. +.Pp +There are +a number of options, at least one of which +.Po either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL +.Pc +must be specified. +The +.Fa options +are selected by +.Tn OR Ns 'ing +the following values: +.Bl -tag -width "FTS_COMFOLLOW" +.It Dv FTS_COMFOLLOW +This option causes any symbolic link specified as a root path to be +followed immediately whether or not +.Dv FTS_LOGICAL +is also specified. +.It Dv FTS_LOGICAL +This option causes the +.Nm fts +routines to return +.Li FTSENT +structures for the targets of symbolic links +instead of the symbolic links themselves. +If this option is set, the only symbolic links for which +.Li FTSENT +structures +are returned to the application are those referencing non-existent files. +Either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL +.Em must +be provided to the +.Fn fts_open +function. +.It Dv FTS_NOCHDIR +As a performance optimization, the +.Nm fts +functions change directories as they walk the file hierarchy. +This has the side-effect that an application cannot rely on being +in any particular directory during the traversal. +The +.Dv FTS_NOCHDIR +option turns off this optimization, and the +.Nm fts +functions will not change the current directory. +Note that applications should not themselves change their current directory +and try to access files unless +.Dv FTS_NOCHDIR +is specified and absolute +pathnames were provided as arguments to +.Fn fts_open . +.It Dv FTS_NOSTAT +By default, returned +.Li FTSENT +structures reference file characteristic information +.Po the +.Fa statp +field +.Pc +for each file visited. +This option relaxes that requirement as a performance optimization, +allowing the +.Nm fts +functions to set the +.Fa fts_info +field to +.Dv FTS_NSOK +and leave the contents of the +.Fa statp +field undefined. +.It Dv FTS_PHYSICAL +This option causes the +.Nm fts +routines to return +.Li FTSENT +structures for symbolic links themselves instead +of the target files they point to. +If this option is set, +.Li FTSENT +structures for all symbolic links in the +hierarchy are returned to the application. +Either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL +.Em must +be provided to the +.Fn fts_open +function. +.It Dv FTS_SEEDOT +By default, unless they are specified as path arguments to +.Fn fts_open , +any files named +.Dq \&. +or +.Dq .. +encountered in the file hierarchy are ignored. +This option causes the +.Nm fts +routines to return +.Li FTSENT +structures for them. +.It Dv FTS_XDEV +This option prevents +.Nm fts +from descending into directories that have a different device number +than the file from which the descent began. +.El +.Pp +The +.Fa compar +argument +specifies a user-defined function which may be used to order the traversal +of the hierarchy. +It +takes two pointers to pointers to +.Li FTSENT +structures as arguments and +should return a negative value, zero, or a positive value to indicate +if the file referenced by its first argument comes before, in any order +with respect to, or after, the file referenced by its second argument. +The +.Fa fts_accpath , +.Fa fts_path +and +.Fa fts_pathlen +fields of the +.Li FTSENT +structures may +.Em never +be used in this comparison. +If the +.Fa fts_info +field is set to +.Dv FTS_NS +or +.Dv FTS_NSOK , +the +.Fa fts_statp +field may not either. +If the +.Fa compar +argument is +.Dv NULL , +the directory traversal order is in the order listed in +.Fa path_argv +for the root paths, and in the order listed in the directory for +everything else. +.Pp +If an error occurs, +.Fn fts_open +returns +.Dv NULL +and sets +.Va errno +appropriately. +.Ss FTS_READ +The +.Fn fts_read +function returns a pointer to an +.Li FTSENT +structure describing a file in +the hierarchy. +Directories +.Pq that are readable and do not cause cycles +are visited at least twice, once in pre-order and once in post-order. +All other files are visited at least once. +.Po Hard links between directories that do not cause cycles or symbolic +links to symbolic links may cause files to be visited more than once, +or directories more than twice. +.Pc +.Pp +If all the members of the hierarchy have been returned, +.Fn fts_read +returns +.Dv NULL +and sets the external variable +.Va errno +to 0. +If an error unrelated to a file in the hierarchy occurs, +.Fn fts_read +returns +.Dv NULL +and sets +.Va errno +appropriately. +If an error related to a returned file occurs, a pointer to an +.Li FTSENT +structure is returned, and +.Va errno +may or may not have been set +.Pq see Fa fts_info . +.Pp +The +.Li FTSENT +structures returned by +.Fn fts_read +may be overwritten after a call to +.Fn fts_close +on the same file hierarchy stream or, after a call to +.Fn fts_read , +on the same file hierarchy stream unless they represent a file of type +directory, in which case they will not be overwritten until after a call to +.Fn fts_read +after the +.Li FTSENT +structure has been returned by the function +.Fn fts_read +in post-order. +.Ss FTS_CHILDREN +The +.Fn fts_children +function returns a pointer to an +.Li FTSENT +structure describing the first entry in a null-terminated +linked list of +the files in the directory represented by the +.Li FTSENT +structure most recently returned by +.Fn fts_read . +The list is linked through the +.Fa fts_link +field of the +.Li FTSENT +structure, and is ordered by the user-specified comparison function, if any. +Repeated calls to +.Fn fts_children +will recreate this linked list. +.Pp +As a special case, if +.Fn fts_read +has not yet been called for a hierarchy, +.Fn fts_children +will return a pointer to the files in the logical directory specified to +.Fn fts_open , +i.e., the arguments specified to +.Fn fts_open . +Otherwise, if the +.Li FTSENT +structure most recently returned by +.Fn fts_read +is not a directory being visited in pre-order, +or the directory does not contain any files, +.Fn fts_children +returns +.Dv NULL +and sets +.Va errno +to 0. +If an error occurs, +.Fn fts_children +returns +.Dv NULL +and sets +.Va errno +appropriately. +.Pp +The +.Li FTSENT +structures returned by +.Fn fts_children +may be overwritten after a call to +.Fn fts_children , +.Fn fts_close +or +.Fn fts_read +on the same file hierarchy stream. +.Pp +.Fa options +may be set to the following value: +.Bl -tag -width FTS_NAMEONLY +.It Dv FTS_NAMEONLY +Only the names of the files are needed. +The contents of all the fields in the returned linked list of structures +are undefined with the exception of the +.Fa fts_name +and +.Fa fts_namelen +fields. +.El +.Ss FTS_SET +The function +.Fn fts_set +allows the user application to determine further processing for the file +.Fa f +of the stream +.Fa ftsp . +The +.Fn fts_set +function returns 0 on success or \-1 if an error occurred. +.Fa option +must be set to one of the following values: +.Bl -tag -width FTS_PHYSICAL +.It Dv FTS_AGAIN +Re-visit the file; any file type may be re-visited. +The next call to +.Fn fts_read +will return the referenced file. +The +.Fa fts_stat +and +.Fa fts_info +fields of the structure will be reinitialized at that time, +but no other fields will have been changed. +This option is meaningful only for the most recently returned +file from +.Fn fts_read . +Normal use is for post-order directory visits, where it causes the +directory to be re-visited +.Pq in both pre and post-order +as well as all of its descendants. +.It Dv FTS_FOLLOW +The referenced file must be a symbolic link. +If the referenced file is the one most recently returned by +.Fn fts_read , +the next call to +.Fn fts_read +returns the file with the +.Fa fts_info +and +.Fa fts_statp +fields reinitialized to reflect the target of the symbolic link instead +of the symbolic link itself. +If the file is one of those most recently returned by +.Fn fts_children , +the +.Fa fts_info +and +.Fa fts_statp +fields of the structure, when returned by +.Fn fts_read , +will reflect the target of the symbolic link instead of the symbolic link +itself. +In either case if the target of the symbolic link does not exist, the +fields of the returned structure will be unchanged and the +.Fa fts_info +field will be set to +.Dv FTS_SLNONE . +.Pp +If the target of the link is a directory, the pre-order return, followed +by the return of all of its descendants, followed by a post-order return, +is done. +.It Dv FTS_SKIP +No descendants of this file are visited. +The file may be one of those most recently returned by either +.Fn fts_children +or +.Fn fts_read . +.El +.Ss FTS_CLOSE +The +.Fn fts_close +function closes a file hierarchy stream +.Fa ftsp +and restores the current directory to the directory from which +.Fn fts_open +was called to open +.Fa ftsp . +.Rv -std fts_close +.Ss Locking +The fts routines provide no locking. +While the +.Fn fts_open +function is +.Sy Safe +and can be called from multiple threads simultaneously, the individual +handles returned from the +.Fn fts_open +function are not thread-safe. +If callers need to operate on a single +.Vt FTS +structure, then it is their responsibility to ensure that none of the +other functions are called from multiple threads simultaneously. +This implies that the +.Fn fts_read , +.Fn fts_children , +.Fn fts_set , +and +.Fn fts_close +functions are +.Sy Unsafe . +.Pp +These routines are not +.Sy Async-Signal-Safe +and callers should not assume that the implementation of these functions +will be +.Sy Fork-Safe . +If callers implement their own locking structures around the use of +these routines, they must ensure that those locks are accounted for when +forking by the use of routines such as +.Xr pthread_atfork 3C . +.Sh ERRORS +The function +.Fn fts_open +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr open 2 +and +.Xr malloc 3C . +.Pp +The function +.Fn fts_close +may fail and set +.Va errno +for any of the errors specified for the library function +.Xr fchdir 2 . +.Pp +The functions +.Fn fts_read +and +.Fn fts_children +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr chdir 2 , +.Xr malloc 3C , +.Xr opendir 3C , +.Xr readdir 3C +and +.Xr stat 2 . +.Pp +In addition, +.Fn fts_children , +.Fn fts_open +and +.Fn fts_set +may fail and set +.Va errno +as follows: +.Bl -tag -width Er +.It Er EINVAL +A specified option is invalid or +.Fa path_argv +is empty. +.El +.Sh INTERFACE STABILITY +.Sy Committed . +.Sh MT-LEVEL +See +.Sx Locking . +.Sh SEE ALSO +.Xr find 1 , +.Xr chdir 2 , +.Xr stat 2 , +.Xr qsort 3C , +.Xr attributes 5 diff --git a/usr/src/man/man3c/malloc.3c b/usr/src/man/man3c/malloc.3c index 9286b20784..f0c69f02f5 100644 --- a/usr/src/man/man3c/malloc.3c +++ b/usr/src/man/man3c/malloc.3c @@ -1,203 +1,332 @@ -'\" te -.\" Copyright 1989 AT&T. Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved. -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH MALLOC 3C "Mar 21, 2005" -.SH NAME -malloc, calloc, free, memalign, realloc, valloc, alloca \- memory allocator -.SH SYNOPSIS -.LP -.nf -#include - -\fBvoid *\fR\fBmalloc\fR(\fBsize_t\fR \fIsize\fR); -.fi - -.LP -.nf -\fBvoid *\fR\fBcalloc\fR(\fBsize_t\fR \fInelem\fR, \fBsize_t\fR \fIelsize\fR); -.fi - -.LP -.nf -\fBvoid\fR \fBfree\fR(\fBvoid *\fR\fIptr\fR); -.fi - -.LP -.nf -\fBvoid *\fR\fBmemalign\fR(\fBsize_t\fR \fIalignment\fR, \fBsize_t\fR \fIsize\fR); -.fi - -.LP -.nf -\fBvoid *\fR\fBrealloc\fR(\fBvoid *\fR\fIptr\fR, \fBsize_t\fR \fIsize\fR); -.fi - -.LP -.nf -\fBvoid *\fR\fBvalloc\fR(\fBsize_t\fR \fIsize\fR); -.fi - -.LP -.nf -#include - -\fBvoid *\fR\fBalloca\fR(\fBsize_t\fR \fIsize\fR); -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBmalloc()\fR and \fBfree()\fR functions provide a simple, general-purpose -memory allocation package. The \fBmalloc()\fR function returns a pointer to a -block of at least \fIsize\fR bytes suitably aligned for any use. If the space -assigned by \fBmalloc()\fR is overrun, the results are undefined. -.sp -.LP -The argument to \fBfree()\fR is a pointer to a block previously allocated by -\fBmalloc()\fR, \fBcalloc()\fR, or \fBrealloc()\fR. After \fBfree()\fR is -executed, this space is made available for further allocation by the -application, though not returned to the system. Memory is returned to the -system only upon termination of the application. If \fIptr\fR is a null -pointer, no action occurs. If a random number is passed to \fBfree()\fR, the -results are undefined. -.sp -.LP -The \fBcalloc()\fR function allocates space for an array of \fInelem\fR -elements of size \fIelsize\fR. The space is initialized to zeros. -.sp -.LP -The \fBmemalign()\fR function allocates \fIsize\fR bytes on a specified -alignment boundary and returns a pointer to the allocated block. The value of -the returned address is guaranteed to be an even multiple of \fIalignment\fR. -The value of \fIalignment\fR must be a power of two and must be greater than or -equal to the size of a word. -.sp -.LP -The \fBrealloc()\fR function changes the size of the block pointed to by -\fIptr\fR to \fIsize\fR bytes and returns a pointer to the (possibly moved) -block. The contents will be unchanged up to the lesser of the new and old -sizes. If the new size of the block requires movement of the block, the space -for the previous instantiation of the block is freed. If the new size is -larger, the contents of the newly allocated portion of the block are -unspecified. If \fIptr\fR is \fINULL\fR, \fBrealloc()\fR behaves like -\fBmalloc()\fR for the specified size. If \fIsize\fR is 0 and \fIptr\fR is not -a null pointer, the space pointed to is freed. -.sp -.LP -The \fBvalloc()\fR function has the same effect as \fBmalloc()\fR, except that -the allocated memory will be aligned to a multiple of the value returned by -\fBsysconf\fR(\fB_SC_PAGESIZE\fR). -.sp -.LP -The \fBalloca()\fR function allocates \fIsize\fR bytes of space in the stack -frame of the caller, and returns a pointer to the allocated block. This -temporary space is automatically freed when the caller returns. If the -allocated block is beyond the current stack limit, the resulting behavior is -undefined. -.SH RETURN VALUES -.sp -.LP +.\" +.\" The contents of this file are subject to the terms of the +.\" Common Development and Distribution License (the "License"). +.\" You may not use this file except in compliance with the License. +.\" +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" or http://www.opensolaris.org/os/licensing. +.\" See the License for the specific language governing permissions +.\" and limitations under the License. +.\" +.\" When distributing Covered Code, include this CDDL HEADER in each +.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" If applicable, add the following below this CDDL HEADER, with the +.\" fields enclosed by brackets "[]" replaced with your own identifying +.\" information: Portions Copyright [yyyy] [name of copyright owner] +.\" +.\" +.\" Copyright 1989 AT&T +.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved. +.\" +.Dd March 10, 2017 +.Dt MALLOC 3C +.Os +.Sh NAME +.Nm malloc , +.Nm calloc , +.Nm free , +.Nm memalign , +.Nm realloc , +.Nm reallocarray , +.Nm valloc , +.Nm alloca +.Nd memory allocator +.Sh SYNOPSIS +.In stdlib.h +.Ft void * +.Fo malloc +.Fa "size_t size" +.Fc +.Ft void * +.Fo calloc +.Fa "size_t nelem" +.Fa "size_t elsize" +.Fc +.Ft void +.Fo free +.Fa "void *ptr" +.Fc +.Ft void * +.Fo memalign +.Fa "size_t alignment" +.Fa "size_t size" +.Fc +.Ft void * +.Fo realloc +.Fa "void *ptr" +.Fa "size_t size" +.Fc +.Ft void * +.Fo reallocarray +.Fa "void *ptr" +.Fa "size_t nelem" +.Fa "size_t elsize" +.Fc +.Ft void * +.Fo valloc +.Fa "size_t size" +.Fc +.In alloca.h +.Ft void * +.Fo alloca +.Fa "size_t size" +.Fc +.Sh DESCRIPTION +The +.Fn malloc +and +.Fn free +functions provide a simple, general-purpose memory allocation package. +The +.Fn malloc +function returns a pointer to a block of at least +.Fa size +bytes suitably aligned for any use. +If the space assigned by +.Fn malloc +is overrun, the results are undefined. +.Pp +The argument to +.Fn free +is a pointer to a block previously allocated by +.Fn malloc , +.Fn calloc , +.Fn realloc , +or +.Fn reallocarray . +After +.Fn free +is executed, this space is made available for further allocation by the +application, though not returned to the system. +Memory is returned to the system only upon termination of the application. +If +.Fa ptr +is a null pointer, no action occurs. +If a random number is passed to +.Fn free , +the results are undefined. +.Pp +The +.Fn calloc +function allocates space for an array of +.Fa nelem +elements of size +.Fa elsize . +The space is initialized to zeros. +.Pp +The +.Fn memalign +function allocates +.Fa size +bytes on a specified alignment boundary and returns a pointer to the allocated +block. +The value of the returned address is guaranteed to be an even multiple of +.Fa alignment . +The value of +.Fa alignment +must be a power of two and must be greater than or equal to the size of a word. +.Pp +The +.Fn realloc +function changes the size of the block pointed to by +.Fa ptr +to +.Fa size +bytes and returns a pointer to the +.Pq possibly moved +block. +The contents will be unchanged up to the lesser of the new and old sizes. +If the new size of the block requires movement of the block, the space for the +previous instantiation of the block is freed. +If the new size is larger, the contents of the newly allocated portion of the +block are unspecified. +If +.Fa ptr +is +.Dv NULL , +.Fn realloc +behaves like +.Fn malloc +for the specified size. +If +.Fa size +is 0 and +.Fa ptr +is not a null pointer, the space pointed to is freed. +.Pp +The +.Fn reallocarray +function is similar to +.Fn realloc , +but operates on +.Fa nelem +elements of size +.Fa elsize +and checks for overflow in +.Fa nelem Ns * Ns Fa elsize +calculation. +.Pp +The +.Fn valloc +function has the same effect as +.Fn malloc , +except that the allocated memory will be aligned to a multiple of the value +returned by +.Nm sysconf Ns Pq Dv _SC_PAGESIZE . +.Pp +The +.Fn alloca +function allocates +.Fa size +bytes of space in the stack frame of the caller, and returns a pointer to the +allocated block. +This temporary space is automatically freed when the caller returns. +If the allocated block is beyond the current stack limit, the resulting behavior +is undefined. +.Sh RETURN VALUES Upon successful completion, each of the allocation functions returns a pointer -to space suitably aligned (after possible pointer coercion) for storage of any -type of object. -.sp -.LP -If there is no available memory, \fBmalloc()\fR, \fBrealloc()\fR, -\fBmemalign()\fR, \fBvalloc()\fR, and \fBcalloc()\fR return a null pointer. -When \fBrealloc()\fR is called with \fIsize\fR > 0 and returns \fINULL\fR, the -block pointed to by \fIptr\fR is left intact. If \fIsize\fR, \fInelem\fR, or -\fIelsize\fR is 0, either a null pointer or a unique pointer that can be passed -to \fBfree()\fR is returned. -.sp -.LP -If \fBmalloc()\fR, \fBcalloc()\fR, or \fBrealloc()\fR returns unsuccessfully, -\fBerrno\fR will be set to indicate the error. The \fBfree()\fR function does -not set \fBerrno\fR. -.SH ERRORS -.sp -.LP -The \fBmalloc()\fR, \fBcalloc()\fR, and \fBrealloc()\fR functions will fail if: -.sp -.ne 2 -.na -\fB\fBENOMEM\fR\fR -.ad -.RS 10n -The physical limits of the system are exceeded by \fIsize\fR bytes of memory -which cannot be allocated. -.RE - -.sp -.ne 2 -.na -\fB\fBEAGAIN\fR\fR -.ad -.RS 10n -There is not enough memory available to allocate \fIsize\fR bytes of memory; -but the application could try again later. -.RE - -.SH USAGE -.sp -.LP -Portable applications should avoid using \fBvalloc()\fR but should instead use -\fBmalloc()\fR or \fBmmap\fR(2). On systems with a large page size, the number -of successful \fBvalloc()\fR operations might be 0. -.sp -.LP +to space suitably aligned +.Pq after possible pointer coercion +for storage of any type of object. +.Pp +If there is no available memory, +.Fn malloc , +.Fn realloc , +.Fn reallocarray , +.Fn memalign , +.Fn valloc , +and +.Fn calloc +return a null pointer. +.Pp +When +.Fn realloc +or +.Fn reallocarray +is called with +.Fa size +> 0 and returns +.Dv NULL , +the block pointed to by +.Fa ptr +is left intact. +If +.Fa size , +.Fa nelem , +or +.Fa elsize +is 0, either a null pointer or a unique pointer that can be passed to +.Fn free +is returned. +.Pp +If +.Fn malloc , +.Fn calloc , +.Fn realloc , +or +.Fn reallocarray +returns unsuccessfully, +.Va errno +will be set to indicate the error. +The +.Fn free +function does not set +.Va errno . +.Sh ERRORS +The +.Fn malloc , +.Fn calloc , +.Fn realloc , +and +.Fn reallocarray +functions will fail if: +.Bl -tag -width "ENOMEM" +.It Er ENOMEM +The physical limits of the system are exceeded by +.Fa size +bytes of memory which cannot be allocated, or there's integer overflow in +.Fn reallocarray . +.It Er EAGAIN +There is not enough memory available to allocate +.Fa size +bytes of memory; but the application could try again later. +.El +.Sh USAGE +Portable applications should avoid using +.Fn valloc +but should instead use +.Fn malloc +or +.Xr mmap 2 . +On systems with a large page size, the number of successful +.Fn valloc +operations might be 0. +.Pp These default memory allocation routines are safe for use in multithreaded -applications but are not scalable. Concurrent accesses by multiple threads are -single-threaded through the use of a single lock. Multithreaded applications -that make heavy use of dynamic memory allocation should be linked with -allocation libraries designed for concurrent access, such as -\fBlibumem\fR(3LIB) or \fBlibmtmalloc\fR(3LIB). Applications that want to avoid -using heap allocations (with \fBbrk\fR(2)) can do so by using either -\fBlibumem\fR or \fBlibmapmalloc\fR(3LIB). The allocation libraries -\fBlibmalloc\fR(3LIB) and \fBlibbsdmalloc\fR(3LIB) are available for special -needs. -.sp -.LP +applications but are not scalable. +Concurrent accesses by multiple threads are single-threaded through the use of a +single lock. +Multithreaded applications that make heavy use of dynamic memory allocation +should be linked with allocation libraries designed for concurrent access, such +as +.Xr libumem 3LIB +or +.Xr libmtmalloc 3LIB . +Applications that want to avoid using heap allocations +.Pq with Xr brk 2 +can do so by using either +.Xr libumem 3LIB +or +.Xr libmapmalloc 3LIB . +The allocation libraries +.Xr libmalloc 3LIB +and +.Xr libbsdmalloc 3LIB +are available for special needs. +.Pp Comparative features of the various allocation libraries can be found in the -\fBumem_alloc\fR(3MALLOC) manual page. -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability See below. -_ -MT-Level Safe -.TE - -.sp -.LP -The \fBmalloc()\fR, \fBcalloc()\fR, \fBfree()\fR, \fBrealloc()\fR, -\fBvalloc()\fR functions are Standard. The \fBmemalign()\fR and \fBalloca()\fR -functions are Stable. -.SH SEE ALSO -.sp -.LP -\fBbrk\fR(2), \fBgetrlimit\fR(2), \fBlibbsdmalloc\fR(3LIB), -\fBlibmalloc\fR(3LIB), \fBlibmapmalloc\fR(3LIB), \fBlibmtmalloc\fR(3LIB), -\fBlibumem\fR(3LIB), \fBumem_alloc\fR(3MALLOC), \fBwatchmalloc\fR(3MALLOC), -\fBattributes\fR(5) -.SH WARNINGS -.sp -.LP +.Xr umem_alloc 3MALLOC +manual page. +.Sh INTERFACE STABILITY +The +.Fn malloc , +.Fn calloc , +.Fn free , +.Fn realloc , +.Fn valloc +functions are +.Sy Standard. +.Pp +The +.Fn reallocarray +function is +.Sy Committed . +.Pp +The +.Fn memalign +and +.Fn alloca +functions are +.Sy Stable . +.Sh MT-LEVEL +.Sy Safe. +.Sh SEE ALSO +.Xr brk 2 , +.Xr getrlimit 2 , +.Xr libbsdmalloc 3LIB , +.Xr libmalloc 3LIB , +.Xr libmapmalloc 3LIB , +.Xr libmtmalloc 3LIB , +.Xr libumem 3LIB , +.Xr umem_alloc 3MALLOC , +.Xr watchmalloc 3MALLOC , +.Xr attributes 5 +.Sh WARNINGS Undefined results will occur if the size requested for a block of memory exceeds the maximum size of a process's heap, which can be obtained with -\fBgetrlimit\fR(2) -.sp -.LP -The \fBalloca()\fR function is machine-, compiler-, and most of all, -system-dependent. Its use is strongly discouraged. +.Xr getrlimit 2 . +.Pp +The +.Fn alloca +function is machine-, compiler-, and most of all, system-dependent. +Its use is strongly discouraged. diff --git a/usr/src/man/man3c/strtonum.3c b/usr/src/man/man3c/strtonum.3c new file mode 100644 index 0000000000..a0e6412d66 --- /dev/null +++ b/usr/src/man/man3c/strtonum.3c @@ -0,0 +1,151 @@ +.\" +.\" Copyright (c) 2004 Ted Unangst +.\" +.\" 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. +.\" +.Dd $Mdocdate: February 7 2016 $ +.Dt STRTONUM 3C +.Os +.Sh NAME +.Nm strtonum +.Nd reliably convert string value to an integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft long long +.Fo strtonum +.Fa "const char *nptr" +.Fa "long long minval" +.Fa "long long maxval" +.Fa "const char **errstr" +.Fc +.Sh DESCRIPTION +The +.Fn strtonum +function converts the string in +.Fa nptr +to a +.Li long long +value. +The +.Fn strtonum +function was designed to facilitate safe, robust programming +and overcome the shortcomings of the +.Xr atoi 3C +and +.Xr strtol 3C +family of interfaces. +.Pp +The string may begin with an arbitrary amount of whitespace +.Pq as determined by Xr isspace 3C +followed by a single optional +.Ql + +or +.Ql - +sign. +.Pp +The remainder of the string is converted to a +.Li long long +value according to base 10. +.Pp +The value obtained is then checked against the provided +.Fa minval +and +.Fa maxval +bounds. +If +.Fa errstr +is non-null, +.Fn strtonum +stores an error string in +.Fa errstr +indicating the failure. +.Sh RETURN VALUES +The +.Fn strtonum +function returns the result of the conversion, +unless the value would exceed the provided bounds or is invalid. +On error, 0 is returned, +.Va errno +is set, and +.Fa errstr +will point to an error message. +.Fa errstr +will be set to +.Dv NULL +on success; this fact can be used to differentiate a successful return of 0 from +an error. +.Sh EXAMPLES +Using +.Fn strtonum +correctly is meant to be simpler than the alternative functions. +.Bd -literal -offset indent +int iterations; +const char *errstr; + +iterations = strtonum(optarg, 1, 64, &errstr); +if (errstr != NULL) + errx(1, "number of iterations is %s: %s", errstr, optarg); +.Ed +.Pp +The above example will guarantee that the value of iterations is between +1 and 64 +.Pq inclusive . +.Sh ERRORS +.Bl -tag -width Er +.It Er ERANGE +The given string was out of range. +.It Er EINVAL +The given string did not consist solely of digit characters. +.It Er EINVAL +.Ar minval +was larger than +.Ar maxval . +.El +.Pp +If an error occurs, +.Fa errstr +will be set to one of the following strings: +.Pp +.Bl -tag -width "too largeXX" -compact +.It Qq too large +The result was larger than the provided maximum value. +.It Qq too small +The result was smaller than the provided minimum value. +.It Qq invalid +The string did not consist solely of digit characters. +.El +.Sh INTERFACE STABILITY +.Sy Committed . +.Sh MT-LEVEL +.Sy Safe . +.Sh SEE ALSO +.Xr atof 3C , +.Xr atoi 3C , +.Xr atol 3C , +.Xr atoll 3C , +.Xr sscanf 3C , +.Xr strtod 3C , +.Xr strtol 3C , +.Xr strtoul 3C +.Sh STANDARDS +.Fn strtonum +is an +.Ox +extension. +The existing alternatives, such as +.Xr atoi 3C +and +.Xr strtol 3C , +are either impossible or difficult to use safely. diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 9082061fd1..71d3683ffb 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -24,7 +24,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2013 Saso Kiselkov. All rights reserved. # Copyright 2014 Garrett D'Amore -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2017 Nexenta Systems, Inc. # Copyright 2016 Hans Rosenfeld # @@ -379,6 +379,7 @@ file path=usr/include/float.h file path=usr/include/fmtmsg.h file path=usr/include/fnmatch.h file path=usr/include/form.h +file path=usr/include/fts.h file path=usr/include/ftw.h file path=usr/include/gelf.h file path=usr/include/getopt.h diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc index f913eecea4..0a07bd5222 100644 --- a/usr/src/pkg/manifests/system-library.man3c.inc +++ b/usr/src/pkg/manifests/system-library.man3c.inc @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright 2013 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. # Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore # @@ -147,6 +147,7 @@ file path=usr/share/man/man3c/fsync.3c file path=usr/share/man/man3c/ftell.3c file path=usr/share/man/man3c/ftime.3c file path=usr/share/man/man3c/ftok.3c +file path=usr/share/man/man3c/fts.3c file path=usr/share/man/man3c/ftw.3c file path=usr/share/man/man3c/fwide.3c file path=usr/share/man/man3c/fwprintf.3c @@ -440,6 +441,7 @@ file path=usr/share/man/man3c/strsignal.3c file path=usr/share/man/man3c/strtod.3c file path=usr/share/man/man3c/strtoimax.3c file path=usr/share/man/man3c/strtol.3c +file path=usr/share/man/man3c/strtonum.3c file path=usr/share/man/man3c/strtoul.3c file path=usr/share/man/man3c/strtows.3c file path=usr/share/man/man3c/strxfrm.3c @@ -818,6 +820,11 @@ link path=usr/share/man/man3c/fsetattr.3c target=fgetattr.3c link path=usr/share/man/man3c/ftello.3c target=ftell.3c link path=usr/share/man/man3c/ftruncate.3c target=truncate.3c link path=usr/share/man/man3c/ftrylockfile.3c target=flockfile.3c +link path=usr/share/man/man3c/fts_children.3c target=fts.3c +link path=usr/share/man/man3c/fts_close.3c target=fts.3c +link path=usr/share/man/man3c/fts_open.3c target=fts.3c +link path=usr/share/man/man3c/fts_read.3c target=fts.3c +link path=usr/share/man/man3c/fts_set.3c target=fts.3c link path=usr/share/man/man3c/func_to_decimal.3c target=string_to_decimal.3c link path=usr/share/man/man3c/funlockfile.3c target=flockfile.3c link path=usr/share/man/man3c/gconvert.3c target=econvert.3c @@ -1197,6 +1204,7 @@ link path=usr/share/man/man3c/rctlblk_size.3c target=rctlblk_set_value.3c link path=usr/share/man/man3c/re_exec.3c target=re_comp.3c link path=usr/share/man/man3c/readdir_r.3c target=readdir.3c link path=usr/share/man/man3c/realloc.3c target=malloc.3c +link path=usr/share/man/man3c/reallocarray.3c target=malloc.3c link path=usr/share/man/man3c/regerror.3c target=regcomp.3c link path=usr/share/man/man3c/regex.3c target=regcmp.3c link path=usr/share/man/man3c/regexec.3c target=regcomp.3c diff --git a/usr/src/tools/mandoc/Makefile b/usr/src/tools/mandoc/Makefile index 6e254601a2..7f8b3b8f2a 100644 --- a/usr/src/tools/mandoc/Makefile +++ b/usr/src/tools/mandoc/Makefile @@ -10,14 +10,18 @@ # # -# Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. # CMDDIR= $(SRC)/cmd/mandoc +LCDIR= $(SRC)/lib/libc/port include $(SRC)/tools/Makefile.tools include $(CMDDIR)/Makefile.common +OBJS += reallocarray.o \ + strtonum.o + .KEEP_STATE: all: $(PROG) @@ -34,4 +38,7 @@ $(PROG): $(OBJS) %.o: $(CMDDIR)/%.c $(COMPILE.c) -o $@ $< +%.o: $(LCDIR)/gen/%.c + $(COMPILE.c) -o $@ $< + include $(SRC)/tools/Makefile.targ diff --git a/usr/src/uts/common/fs/zfs/dsl_deadlist.c b/usr/src/uts/common/fs/zfs/dsl_deadlist.c index 203815a750..ff06c9e93c 100644 --- a/usr/src/uts/common/fs/zfs/dsl_deadlist.c +++ b/usr/src/uts/common/fs/zfs/dsl_deadlist.c @@ -85,7 +85,7 @@ dsl_deadlist_load_tree(dsl_deadlist_t *dl) zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) { dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP); - dle->dle_mintxg = strtonum(za.za_name, NULL); + dle->dle_mintxg = zfs_strtonum(za.za_name, NULL); VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, za.za_first_integer)); avl_add(&dl->dl_tree, dle); @@ -490,7 +490,7 @@ dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx) for (zap_cursor_init(&zc, dl->dl_os, obj); zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) { - uint64_t mintxg = strtonum(za.za_name, NULL); + uint64_t mintxg = zfs_strtonum(za.za_name, NULL); dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx); VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx)); } diff --git a/usr/src/uts/common/fs/zfs/dsl_scan.c b/usr/src/uts/common/fs/zfs/dsl_scan.c index e476689e40..ccd9eb4c39 100644 --- a/usr/src/uts/common/fs/zfs/dsl_scan.c +++ b/usr/src/uts/common/fs/zfs/dsl_scan.c @@ -1365,7 +1365,7 @@ dsl_scan_visit(dsl_scan_t *scn, dmu_tx_t *tx) dsl_dataset_t *ds; uint64_t dsobj; - dsobj = strtonum(za.za_name, NULL); + dsobj = zfs_strtonum(za.za_name, NULL); VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset, scn->scn_phys.scn_queue_obj, dsobj, tx)); diff --git a/usr/src/uts/common/fs/zfs/dsl_userhold.c b/usr/src/uts/common/fs/zfs/dsl_userhold.c index 54a15e1669..a0484a0cd9 100644 --- a/usr/src/uts/common/fs/zfs/dsl_userhold.c +++ b/usr/src/uts/common/fs/zfs/dsl_userhold.c @@ -340,7 +340,7 @@ static int dsl_dataset_hold_obj_string(dsl_pool_t *dp, const char *dsobj, void *tag, dsl_dataset_t **dsp) { - return (dsl_dataset_hold_obj(dp, strtonum(dsobj, NULL), tag, dsp)); + return (dsl_dataset_hold_obj(dp, zfs_strtonum(dsobj, NULL), tag, dsp)); } static int diff --git a/usr/src/uts/common/fs/zfs/spa_errlog.c b/usr/src/uts/common/fs/zfs/spa_errlog.c index 168f3acc2e..8ce780537a 100644 --- a/usr/src/uts/common/fs/zfs/spa_errlog.c +++ b/usr/src/uts/common/fs/zfs/spa_errlog.c @@ -73,13 +73,13 @@ bookmark_to_name(zbookmark_phys_t *zb, char *buf, size_t len) static void name_to_bookmark(char *buf, zbookmark_phys_t *zb) { - zb->zb_objset = strtonum(buf, &buf); + zb->zb_objset = zfs_strtonum(buf, &buf); ASSERT(*buf == ':'); - zb->zb_object = strtonum(buf + 1, &buf); + zb->zb_object = zfs_strtonum(buf + 1, &buf); ASSERT(*buf == ':'); - zb->zb_level = (int)strtonum(buf + 1, &buf); + zb->zb_level = (int)zfs_strtonum(buf + 1, &buf); ASSERT(*buf == ':'); - zb->zb_blkid = strtonum(buf + 1, &buf); + zb->zb_blkid = zfs_strtonum(buf + 1, &buf); ASSERT(*buf == '\0'); } #endif diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c index 1aebbca741..6555d4eee5 100644 --- a/usr/src/uts/common/fs/zfs/spa_misc.c +++ b/usr/src/uts/common/fs/zfs/spa_misc.c @@ -1481,7 +1481,7 @@ zfs_panic_recover(const char *fmt, ...) * lowercase hexadecimal numbers that don't overflow. */ uint64_t -strtonum(const char *str, char **nptr) +zfs_strtonum(const char *str, char **nptr) { uint64_t val = 0; char c; diff --git a/usr/src/uts/common/fs/zfs/sys/spa.h b/usr/src/uts/common/fs/zfs/sys/spa.h index c96c001da5..0243c3effd 100644 --- a/usr/src/uts/common/fs/zfs/sys/spa.h +++ b/usr/src/uts/common/fs/zfs/sys/spa.h @@ -829,7 +829,7 @@ extern int spa_maxblocksize(spa_t *spa); extern void zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp); extern int spa_mode(spa_t *spa); -extern uint64_t strtonum(const char *str, char **nptr); +extern uint64_t zfs_strtonum(const char *str, char **nptr); extern char *spa_his_ievent_table[]; diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c index 213a30b6e6..5fefc541a6 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c @@ -632,7 +632,7 @@ fuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr, uint64_t fuid; const char *domain; - fuid = strtonum(fuidstr, NULL); + fuid = zfs_strtonum(fuidstr, NULL); domain = zfs_fuid_find_by_idx(zfsvfs, FUID_INDEX(fuid)); if (domain) -- cgit v1.2.3