From owner-freebsd-audit Tue May 21 11:51:27 2002 Delivered-To: freebsd-audit@freebsd.org Received: from chiark.greenend.org.uk (chiark.greenend.org.uk [212.135.138.206]) by hub.freebsd.org (Postfix) with ESMTP id A922E37B41C for ; Tue, 21 May 2002 11:51:08 -0700 (PDT) Received: from fanf by chiark.greenend.org.uk with local (Exim 3.12 #1) id 17AEix-0001Jl-00 (Debian); Tue, 21 May 2002 19:51:07 +0100 Date: Tue, 21 May 2002 19:51:07 +0100 From: Tony Finch To: freebsd-audit@freebsd.org Subject: strptime %z support Message-ID: <20020521195107.A4260@chiark.greenend.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG This is a work-in-progress patch against -STABLE. The reason I'm posting here is because I have a feeling I'm barking up the wrong tree -- I'm not sure how to get it to return a struct tm with the right timezone filled in so it currently falls back to GMT. It also replaces a pthreads lock with re-entrant code. Any comments would be welcome. Tony. -- f.a.n.finch http://dotat.at/ SOUTHEAST ICELAND: SOUTHEASTERLY 6 TO GALE 8, BACKING EAST OR NORTHEAST 4 OR 5. SHOWERS. MODERATE. Index: strptime.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdtime/strptime.c,v retrieving revision 1.17.2.3 diff -u -r1.17.2.3 strptime.c --- strptime.c 12 Mar 2002 17:24:54 -0000 1.17.2.3 +++ strptime.c 21 May 2002 18:39:23 -0000 @@ -75,18 +75,17 @@ #endif #include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *); +static char * _strptime(const char *, const char *, struct tm *, int *); -#ifdef _THREAD_SAFE -static struct pthread_mutex _gotgmt_mutexd = PTHREAD_MUTEX_STATIC_INITIALIZER; -static pthread_mutex_t gotgmt_mutex = &_gotgmt_mutexd; -#endif -static int got_GMT; +enum { + NORMALIZE_GMT = 1, + NORMALIZE_LOCAL = 2 +}; #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) static char * -_strptime(const char *buf, const char *fmt, struct tm *tm) +_strptime(const char *buf, const char *fmt, struct tm *tm, int *flagp) { char c; const char *ptr; @@ -123,7 +122,7 @@ break; case '+': - buf = _strptime(buf, tptr->date_fmt, tm); + buf = _strptime(buf, tptr->date_fmt, tm, flagp); if (buf == 0) return 0; break; @@ -146,13 +145,13 @@ break; case 'c': - buf = _strptime(buf, tptr->c_fmt, tm); + buf = _strptime(buf, tptr->c_fmt, tm, flagp); if (buf == 0) return 0; break; case 'D': - buf = _strptime(buf, "%m/%d/%y", tm); + buf = _strptime(buf, "%m/%d/%y", tm, flagp); if (buf == 0) return 0; break; @@ -170,37 +169,37 @@ goto label; case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm); + buf = _strptime(buf, "%Y-%m-%d", tm, flagp); if (buf == 0) return 0; break; case 'R': - buf = _strptime(buf, "%H:%M", tm); + buf = _strptime(buf, "%H:%M", tm, flagp); if (buf == 0) return 0; break; case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm); + buf = _strptime(buf, tptr->ampm_fmt, tm, flagp); if (buf == 0) return 0; break; case 'T': - buf = _strptime(buf, "%H:%M:%S", tm); + buf = _strptime(buf, "%H:%M:%S", tm, flagp); if (buf == 0) return 0; break; case 'X': - buf = _strptime(buf, tptr->X_fmt, tm); + buf = _strptime(buf, tptr->X_fmt, tm, flagp); if (buf == 0) return 0; break; case 'x': - buf = _strptime(buf, tptr->x_fmt, tm); + buf = _strptime(buf, tptr->x_fmt, tm, flagp); if (buf == 0) return 0; break; @@ -460,7 +459,7 @@ return 0; buf = cp; gmtime_r(&t, tm); - got_GMT = 1; + *flagp |= NORMALIZE_GMT; } break; @@ -504,7 +503,7 @@ zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT")) { - got_GMT = 1; + *flagp |= NORMALIZE_GMT; } else if (0 == strcmp(zonestr, tzname[0])) { tm->tm_isdst = 0; } else if (0 == strcmp(zonestr, tzname[1])) { @@ -516,6 +515,31 @@ } } break; + case 'z': + { + long off; + char *end; + + off = strtol(buf + 1, &end, 10); + if (end != buf + 5) + return 0; + if (off % 100 > 59) + return 0; + /* convert from 4 decimal digits to hours + minutes */ + off = (off / 100) * 60 + off % 100; + if (*buf == '-') + off = -off; + else if (*buf == '+') + off = +off; + else + return 0; + tm->tm_gmtoff = off * 60; + tm->tm_isdst = -1; + tm->tm_zone = NULL; + *flagp |= NORMALIZE_LOCAL; + buf = end; + } + break; } } return (char *)buf; @@ -526,22 +550,20 @@ strptime(const char *buf, const char *fmt, struct tm *tm) { char *ret; + int flags; -#ifdef _THREAD_SAFE - pthread_mutex_lock(&gotgmt_mutex); -#endif - - got_GMT = 0; - ret = _strptime(buf, fmt, tm); - if (ret && got_GMT) { + ret = _strptime(buf, fmt, tm, &flags); + if (ret == NULL) + return NULL; + if (flags & NORMALIZE_LOCAL) { + tm->tm_hour -= tm->tm_gmtoff / 3600; + tm->tm_min -= (tm->tm_min / 60) % 60; + flags |= NORMALIZE_GMT; + } + if (flags & NORMALIZE_GMT) { time_t t = timegm(tm); - localtime_r(&t, tm); - got_GMT = 0; + localtime_r(&t, tm); } - -#ifdef _THREAD_SAFE - pthread_mutex_unlock(&gotgmt_mutex); -#endif return ret; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 22 8:18:32 2002 Delivered-To: freebsd-audit@freebsd.org Received: from leviathan.inethouston.net (leviathan.inethouston.net [66.64.12.249]) by hub.freebsd.org (Postfix) with ESMTP id E8A8037B419 for ; Wed, 22 May 2002 08:18:29 -0700 (PDT) Received: by leviathan.inethouston.net (Postfix, from userid 1001) id C7FEE3198CC; Wed, 22 May 2002 10:18:31 -0500 (CDT) Date: Wed, 22 May 2002 10:18:31 -0500 From: "David W. Chapman Jr." To: audit@freebsd.org Subject: src/sys/i386/conf/Makefile minor adjustment Message-ID: <20020522151831.GA88258@leviathan.inethouston.net> Reply-To: "David W. Chapman Jr." Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="d6Gm4EdcadzBjdND" Content-Disposition: inline User-Agent: Mutt/1.3.99i X-Operating-System: FreeBSD 4.5-STABLE i386 Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --d6Gm4EdcadzBjdND Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here's a minor adjustment that I saw might be needed. If you do a make clean when LINT doesn't exist you get an error, this fixes that. -- David W. Chapman Jr. dwcjr@inethouston.net Raintree Network Services, Inc. dwcjr@freebsd.org FreeBSD Committer --d6Gm4EdcadzBjdND Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="conf.patch" Index: Makefile =================================================================== RCS file: /home/ncvs/src/sys/i386/conf/Makefile,v retrieving revision 1.5 diff -u -r1.5 Makefile --- Makefile 2 May 2002 16:34:47 -0000 1.5 +++ Makefile 22 May 2002 15:08:00 -0000 @@ -4,7 +4,7 @@ @echo "make LINT only" clean: - rm LINT + rm -f LINT LINT: ../../conf/NOTES NOTES makeLINT.sed cat ../../conf/NOTES NOTES | sed -E -n -f makeLINT.sed > LINT --d6Gm4EdcadzBjdND-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 22 21:59:12 2002 Delivered-To: freebsd-audit@freebsd.org Received: from treetop.robbins.dropbear.id.au (199.b.004.mel.iprimus.net.au [210.50.37.199]) by hub.freebsd.org (Postfix) with ESMTP id 16F0637B416 for ; Wed, 22 May 2002 21:59:07 -0700 (PDT) Received: from treetop.robbins.dropbear.id.au (localhost [127.0.0.1]) by treetop.robbins.dropbear.id.au (8.12.2/8.12.2) with ESMTP id g4N4r6YG053653 for ; Thu, 23 May 2002 14:53:06 +1000 (EST) (envelope-from tim@treetop.robbins.dropbear.id.au) Received: (from tim@localhost) by treetop.robbins.dropbear.id.au (8.12.2/8.12.2/Submit) id g4N4r5Va053652 for freebsd-audit@FreeBSD.ORG; Thu, 23 May 2002 14:53:05 +1000 (EST) Date: Thu, 23 May 2002 14:53:05 +1000 From: "Tim J. Robbins" To: freebsd-audit@FreeBSD.ORG Subject: newgrp implementation for review Message-ID: <20020523145305.A53637@treetop.robbins.dropbear.id.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG I'd appreciate it if people could review my implementation of newgrp(1), which runs suid root, for possible security flaws: http://people.freebsd.org/~tjr/newgrp.shar It will only get installed suid root if ENABLE_NEWGRP=true is specified in /etc/make.conf because most people won't need it. newgrp is required by POSIX.2 Amd. 1 (User Portability Extension). Thanks, Tim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Wed May 22 22: 1: 8 2002 Delivered-To: freebsd-audit@freebsd.org Received: from turbine.trit.org (turbine.trit.org [63.198.170.141]) by hub.freebsd.org (Postfix) with ESMTP id F0D6037B415 for ; Wed, 22 May 2002 22:00:18 -0700 (PDT) Received: from turbine.trit.org (localhost [127.0.0.1]) by turbine.trit.org (Postfix) with ESMTP id E3A2A3E22 for ; Thu, 23 May 2002 05:00:16 +0000 (UTC) To: audit@freebsd.org Subject: %j for printf(9) Date: Thu, 23 May 2002 05:00:15 +0000 From: Dima Dorfman Message-Id: <20020523050017.E3A2A3E22@turbine.trit.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Attached is a patch that implements the %j length modifier in printf(9). I would appreciate it if someone could test it on one (or more) of the 64-bit architectures (applying and checking if ddb ps output looks sensible should be sufficient); I have no reason to think it will break there, but breaking printf for !i386 would be a Bad Thing(tm). I would also appreciate it if someone could review this, particularly looking for anywhere I assume signed or unsigned where I shouldn't (I'm concerned with mis-{sign,zero}-extension). See message-id <20020405080000.754FB3E31@bazooka.trit.org> for the discussion on -standards. The patch has not changed since then. I would also like to solicit comments on what to do with %z; C99 says this is the length modifier for size_t, but the kernel treats it as signed hex. This patch implements the C99 length modifier as %Z, but that probably shouldn't stay. IIRC, I couldn't find any place in the kernel that we actually use %z; can it perhaps be removed? I'd like to get this into the tree pretty soon, since someone already used %j in the kernel. Thanks. Index: subr_prf.c =================================================================== RCS file: /ref/cvsf/src/sys/kern/subr_prf.c,v retrieving revision 1.80 diff -u -r1.80 subr_prf.c --- subr_prf.c 1 Apr 2002 21:30:49 -0000 1.80 +++ subr_prf.c 4 Apr 2002 02:33:56 -0000 @@ -40,6 +40,7 @@ */ #include +#include #include #include #include @@ -78,6 +79,12 @@ size_t remain; }; +/* Length modifier. */ +enum lenmod { + LM_POINTER, LM_QUAD, LM_UQUAD, LM_LONG, LM_ULONG, + LM_INT, LM_UINT, LM_INTMAX, LM_UINTMAX, LM_SIZET +}; + extern int log_open; struct tty *constty; /* pointer to console "window" tty */ @@ -86,8 +93,9 @@ static void msglogchar(int c, int pri); static void msgaddchar(int c, void *dummy); static void putchar(int ch, void *arg); -static char *ksprintn(char *nbuf, u_long num, int base, int *len); -static char *ksprintqn(char *nbuf, u_quad_t num, int base, int *len); +static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len); +static uintmax_t lm_arg(va_list *app, enum lenmod lm); +static enum lenmod lm_unsigned(enum lenmod in); static void snprintf_func(int ch, void *arg); static int consintr = 1; /* Ok to handle console interrupts? */ @@ -419,9 +427,9 @@ * The buffer pointed to by `nbuf' must have length >= MAXNBUF. */ static char * -ksprintn(nbuf, ul, base, lenp) +ksprintn(nbuf, um, base, lenp) char *nbuf; - u_long ul; + uintmax_t um; int base, *lenp; { char *p; @@ -429,29 +437,92 @@ p = nbuf; *p = '\0'; do { - *++p = hex2ascii(ul % base); - } while (ul /= base); + *++p = hex2ascii(um % base); + } while (um /= base); if (lenp) *lenp = p - nbuf; return (p); } -/* ksprintn, but for a quad_t. */ -static char * -ksprintqn(nbuf, uq, base, lenp) - char *nbuf; - u_quad_t uq; - int base, *lenp; + +/* + * Retrieve the next argument in `app' according to `lm'. + */ +static uintmax_t +lm_arg(va_list *app, enum lenmod lm) { - char *p; + uintmax_t um; - p = nbuf; - *p = '\0'; - do { - *++p = hex2ascii(uq % base); - } while (uq /= base); - if (lenp) - *lenp = p - nbuf; - return (p); + switch (lm) { + case LM_POINTER: + um = (uintptr_t)va_arg(*app, void *); + break; + case LM_QUAD: + um = (quad_t)va_arg(*app, quad_t); + break; + case LM_UQUAD: + um = (u_quad_t)va_arg(*app, u_quad_t); + break; + case LM_LONG: + um = (long)va_arg(*app, long); + break; + case LM_ULONG: + um = (u_long)va_arg(*app, u_long); + break; + case LM_INT: + um = (int)va_arg(*app, int); + break; + case LM_UINT: + um = (u_int)va_arg(*app, u_int); + break; + case LM_INTMAX: + um = (intmax_t)va_arg(*app, intmax_t); + break; + case LM_UINTMAX: + um = (uintmax_t)va_arg(*app, uintmax_t); + break; + case LM_SIZET: + um = (size_t)va_arg(*app, size_t); + break; + default: + panic("lm_arg: unknown lm=%d", lm); + } + return (um); +} + +/* + * Return the unsigned counerpart of the length modifier passed in. + */ +static enum lenmod +lm_unsigned(enum lenmod in) +{ + enum lenmod out; + + switch (in) { + case LM_QUAD: + out = LM_UQUAD; + break; + case LM_LONG: + out = LM_ULONG; + break; + case LM_INT: + out = LM_UINT; + break; + case LM_INTMAX: + out = LM_UINTMAX; + break; + case LM_UQUAD: + case LM_ULONG: + case LM_UINT: + case LM_UINTMAX: + case LM_POINTER: + case LM_SIZET: /* Should we do something special with this? */ + /* These are already unsigned, so just return the input. */ + out = in; + break; + default: + panic("lm_unsigned: unknown lm=%d", in); + } + return (out); } /* @@ -488,15 +559,14 @@ char *p, *q, *d; u_char *up; int ch, n; - u_long ul; - u_quad_t uq; - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + uintmax_t um; + enum lenmod lm; + int base, tmp, width, ladjust, sharpflag, neg, sign, dot; int dwidth; char padc; int retval = 0; - ul = 0; - uq = 0; + um = 0; if (!func) d = (char *) arg; else @@ -516,7 +586,8 @@ return (retval); PCHAR(ch); } - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + lm = LM_INT; + ladjust = 0; sharpflag = 0; neg = 0; sign = 0; dot = 0; dwidth = 0; reswitch: switch (ch = (u_char)*fmt++) { case '.': @@ -564,17 +635,17 @@ width = n; goto reswitch; case 'b': - ul = va_arg(ap, int); + um = va_arg(ap, int); p = va_arg(ap, char *); - for (q = ksprintn(nbuf, ul, *p++, NULL); *q;) + for (q = ksprintn(nbuf, um, *p++, NULL); *q;) PCHAR(*q--); - if (!ul) + if (!um) break; for (tmp = 0; *p;) { n = *p++; - if (ul & (1 << (n - 1))) { + if (um & (1 << (n - 1))) { PCHAR(tmp ? ',' : '<'); for (; (n = *p) > ' '; ++p) PCHAR(n); @@ -604,48 +675,34 @@ } break; case 'd': - if (qflag) - uq = va_arg(ap, quad_t); - else if (lflag) - ul = va_arg(ap, long); - else - ul = va_arg(ap, int); + um = lm_arg(&ap, lm); sign = 1; base = 10; goto number; + case 'j': + lm = LM_INTMAX; + goto reswitch; case 'l': - if (lflag) { - lflag = 0; - qflag = 1; - } else - lflag = 1; + if (lm == LM_LONG) + lm = LM_QUAD; + else + lm = LM_LONG; goto reswitch; case 'o': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); + um = lm_arg(&ap, lm_unsigned(lm)); base = 8; goto nosign; case 'p': - ul = (uintptr_t)va_arg(ap, void *); + um = lm_arg(&ap, LM_POINTER); base = 16; sharpflag = (width == 0); goto nosign; case 'q': - qflag = 1; + lm = LM_QUAD; goto reswitch; case 'n': case 'r': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); + um = lm_arg(&ap, sign ? lm : lm_unsigned(lm)); base = radix; goto number; case 's': @@ -670,50 +727,29 @@ PCHAR(padc); break; case 'u': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); + um = lm_arg(&ap, lm_unsigned(lm)); base = 10; goto nosign; case 'x': case 'X': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); + um = lm_arg(&ap, lm_unsigned(lm)); base = 16; goto nosign; + case 'Z': /* XXX: This should be 'z'. */ + lm = LM_SIZET; + goto reswitch; case 'z': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); + um = lm_arg(&ap, sign ? lm : lm_unsigned(lm)); base = 16; goto number; nosign: sign = 0; number: - if (qflag) { - if (sign && (quad_t)uq < 0) { - neg = 1; - uq = -(quad_t)uq; - } - p = ksprintqn(nbuf, uq, base, &tmp); - } else { - if (sign && (long)ul < 0) { - neg = 1; - ul = -(long)ul; - } - p = ksprintn(nbuf, ul, base, &tmp); + if (sign && (intmax_t)um < 0) { + neg = 1; + um = -(intmax_t)um; } - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + p = ksprintn(nbuf, um, base, &tmp); + if (sharpflag && um != 0) { if (base == 8) tmp++; else if (base == 16) @@ -727,7 +763,7 @@ PCHAR(padc); if (neg) PCHAR('-'); - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + if (sharpflag && um != 0) { if (base == 8) { PCHAR('0'); } else if (base == 16) { @@ -746,7 +782,17 @@ break; default: PCHAR('%'); - if (lflag) + /* + * XXX: This is bogus. We can have more flags + * than just `l', and we can even have `l' + * more than once. The old test was + * + * if (lflag) + * + * and we're just imitating that for now. + */ + if (lm == LM_LONG || lm == LM_ULONG || + lm == LM_QUAD || lm == LM_UQUAD) PCHAR('l'); PCHAR(ch); break; @@ -776,7 +822,7 @@ dangling = 0; } msgaddchar('<', NULL); - for (p = ksprintn(nbuf, (u_long)pri, 10, NULL); *p;) + for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL); *p;) msgaddchar(*p--, NULL); msgaddchar('>', NULL); lastpri = pri; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 23 2:21:36 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 1A2AC37B40D for ; Thu, 23 May 2002 02:21:33 -0700 (PDT) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id TAA06447; Thu, 23 May 2002 19:21:26 +1000 Date: Thu, 23 May 2002 19:24:17 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Dima Dorfman Cc: audit@FreeBSD.ORG Subject: Re: %j for printf(9) In-Reply-To: <20020523050017.E3A2A3E22@turbine.trit.org> Message-ID: <20020523185629.L12973-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Thu, 23 May 2002, Dima Dorfman wrote: > Attached is a patch that implements the %j length modifier in > printf(9). I would appreciate it if someone could test it on one (or > ... > I would also appreciate it if someone could review this, particularly > looking for anywhere I assume signed or unsigned where I shouldn't > (I'm concerned with mis-{sign,zero}-extension). > ... > See message-id <20020405080000.754FB3E31@bazooka.trit.org> for the > discussion on -standards. The patch has not changed since then. I'm still not keen on the lm changes. Printf is used more than it used to be for formatting sysctl strings, (e.g. in for malloc statistics), so its efficiency may actually be important and the change to doing everything related to integers in uintmax_t precision might be too inefficient. Some of my debugging sysctls take a second or so to format large trace buffers. I think the error is mainly in the sysctls though. Production-quality sysctls shouldn't take longer than a few microseconds. > I would also like to solicit comments on what to do with %z; C99 says > this is the length modifier for size_t, but the kernel treats it as > signed hex. This patch implements the C99 length modifier as %Z, but > that probably shouldn't stay. Just change %z globally in the kernel. > IIRC, I couldn't find any place in the > kernel that we actually use %z; can it perhaps be removed? It is used only in a couple of places, mainly in ddb. Grep for '".*%.*z' in sys/ddb to see some of them. Hack gcc to warn about %z to find all of them except possibly non-literal ones. %n should be changed similary. I think %n was changed globally to %r long ago to fix an old conflict, but it was not removed from printf(9), so correct use of %n would pass gcc's format checker but printf(9) would do the wrong thing. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Thu May 23 4:17: 2 2002 Delivered-To: freebsd-audit@freebsd.org Received: from flood.ping.uio.no (flood.ping.uio.no [129.240.78.31]) by hub.freebsd.org (Postfix) with ESMTP id 90C0B37B407 for ; Thu, 23 May 2002 04:17:00 -0700 (PDT) Received: by flood.ping.uio.no (Postfix, from userid 2602) id B41155307; Thu, 23 May 2002 13:16:58 +0200 (CEST) X-URL: http://www.ofug.org/~des/ X-Disclaimer: The views expressed in this message do not necessarily coincide with those of any organisation or company with which I am or have been affiliated. To: Dima Dorfman Cc: audit@freebsd.org Subject: Re: %j for printf(9) References: <20020523050017.E3A2A3E22@turbine.trit.org> From: Dag-Erling Smorgrav Date: 23 May 2002 13:16:58 +0200 In-Reply-To: <20020523050017.E3A2A3E22@turbine.trit.org> Message-ID: Lines: 14 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Dima Dorfman writes: > I would also like to solicit comments on what to do with %z; C99 says > this is the length modifier for size_t, but the kernel treats it as > signed hex. This patch implements the C99 length modifier as %Z, but > that probably shouldn't stay. IIRC, I couldn't find any place in the > kernel that we actually use %z; can it perhaps be removed? des@des ~% egrep -r '%[^\" dious]+z' /sec/freebsd/current/src/sys /sec/freebsd/current/src/sys/ddb/db_examine.c: db_printf("%-*lz", width, (long)value); /sec/freebsd/current/src/sys/ddb/db_examine.c: db_printf("%8lz", (long)addr); DES -- Dag-Erling Smorgrav - des@ofug.org To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message From owner-freebsd-audit Sat May 25 6:29:29 2002 Delivered-To: freebsd-audit@freebsd.org Received: from flood.ping.uio.no (flood.ping.uio.no [129.240.78.31]) by hub.freebsd.org (Postfix) with ESMTP id ABD8A37B407 for ; Sat, 25 May 2002 06:29:17 -0700 (PDT) Received: by flood.ping.uio.no (Postfix, from userid 2602) id 55FFE5307; Sat, 25 May 2002 15:29:12 +0200 (CEST) X-URL: http://www.ofug.org/~des/ X-Disclaimer: The views expressed in this message do not necessarily coincide with those of any organisation or company with which I am or have been affiliated. To: Dima Dorfman Cc: audit@freebsd.org Subject: Re: %j for printf(9) References: <20020523050017.E3A2A3E22@turbine.trit.org> From: Dag-Erling Smorgrav Date: 25 May 2002 15:29:11 +0200 In-Reply-To: <20020523050017.E3A2A3E22@turbine.trit.org> Message-ID: Lines: 13 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --=-=-= Dima Dorfman writes: > Attached is a patch that implements the %j length modifier in > printf(9). Here's an alternative (IMHO less disruptive) patch, which also fixes the default case. DES -- Dag-Erling Smorgrav - des@ofug.org --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=kvprintf.diff Index: subr_prf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_prf.c,v retrieving revision 1.81 diff -u -r1.81 subr_prf.c --- subr_prf.c 29 Apr 2002 09:15:38 -0000 1.81 +++ subr_prf.c 25 May 2002 13:25:11 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ #define TOLOG 0x04 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ -#define MAXNBUF (sizeof(quad_t) * NBBY + 1) +#define MAXNBUF (sizeof(intmax_t) * NBBY + 1) struct putchar_arg { int flags; @@ -86,8 +87,7 @@ static void msglogchar(int c, int pri); static void msgaddchar(int c, void *dummy); static void putchar(int ch, void *arg); -static char *ksprintn(char *nbuf, u_long num, int base, int *len); -static char *ksprintqn(char *nbuf, u_quad_t num, int base, int *len); +static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len); static void snprintf_func(int ch, void *arg); static int consintr = 1; /* Ok to handle console interrupts? */ @@ -426,9 +426,9 @@ * The buffer pointed to by `nbuf' must have length >= MAXNBUF. */ static char * -ksprintn(nbuf, ul, base, lenp) +ksprintn(nbuf, num, base, lenp) char *nbuf; - u_long ul; + uintmax_t num; int base, *lenp; { char *p; @@ -436,26 +436,8 @@ p = nbuf; *p = '\0'; do { - *++p = hex2ascii(ul % base); - } while (ul /= base); - if (lenp) - *lenp = p - nbuf; - return (p); -} -/* ksprintn, but for a quad_t. */ -static char * -ksprintqn(nbuf, uq, base, lenp) - char *nbuf; - u_quad_t uq; - int base, *lenp; -{ - char *p; - - p = nbuf; - *p = '\0'; - do { - *++p = hex2ascii(uq % base); - } while (uq /= base); + *++p = hex2ascii(num % base); + } while (num /= base); if (lenp) *lenp = p - nbuf; return (p); @@ -491,19 +473,19 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) { #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } + const char *percent; char nbuf[MAXNBUF]; char *p, *q, *d; u_char *up; int ch, n; - u_long ul; - u_quad_t uq; - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + uintmax_t num; + int base, lflag, jflag, qflag, tmp, width; + int ladjust, sharpflag, neg, sign, dot; int dwidth; char padc; int retval = 0; - ul = 0; - uq = 0; + num = 0; if (!func) d = (char *) arg; else @@ -523,9 +505,11 @@ return (retval); PCHAR(ch); } - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; - sign = 0; dot = 0; dwidth = 0; -reswitch: switch (ch = (u_char)*fmt++) { + percent = fmt - 1; + qflag = jflag = lflag = ladjust = sharpflag = + neg = sign = dot = dwidth = 0; +reswitch: + switch (ch = (u_char)*fmt++) { case '.': dot = 1; goto reswitch; @@ -571,17 +555,17 @@ width = n; goto reswitch; case 'b': - ul = va_arg(ap, int); + num = va_arg(ap, int); p = va_arg(ap, char *); - for (q = ksprintn(nbuf, ul, *p++, NULL); *q;) + for (q = ksprintn(nbuf, num, *p++, NULL); *q;) PCHAR(*q--); - if (!ul) + if (num == 0) break; for (tmp = 0; *p;) { n = *p++; - if (ul & (1 << (n - 1))) { + if (num & (1 << (n - 1))) { PCHAR(tmp ? ',' : '<'); for (; (n = *p) > ' '; ++p) PCHAR(n); @@ -611,15 +595,12 @@ } break; case 'd': - if (qflag) - uq = va_arg(ap, quad_t); - else if (lflag) - ul = va_arg(ap, long); - else - ul = va_arg(ap, int); sign = 1; base = 10; - goto number; + goto fetch_number; + case 'j': + jflag = 1; + goto reswitch; case 'l': if (lflag) { lflag = 0; @@ -628,16 +609,10 @@ lflag = 1; goto reswitch; case 'o': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); base = 8; - goto nosign; + goto fetch_nosign; case 'p': - ul = (uintptr_t)va_arg(ap, void *); + num = (uintptr_t)va_arg(ap, void *); base = 16; sharpflag = (width == 0); goto nosign; @@ -646,15 +621,8 @@ goto reswitch; case 'n': case 'r': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); base = radix; - goto number; + goto fetch_number; case 's': p = va_arg(ap, char *); if (p == NULL) @@ -677,50 +645,45 @@ PCHAR(padc); break; case 'u': - if (qflag) - uq = va_arg(ap, u_quad_t); - else if (lflag) - ul = va_arg(ap, u_long); - else - ul = va_arg(ap, u_int); base = 10; - goto nosign; + goto fetch_nosign; case 'x': case 'X': - if (qflag) - uq = va_arg(ap, u_quad_t); + base = 16; + goto fetch_nosign; + case 'z': + base = 16; + goto fetch_number; +fetch_nosign: + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); else if (lflag) - ul = va_arg(ap, u_long); + num = va_arg(ap, u_long); else - ul = va_arg(ap, u_int); - base = 16; + num = va_arg(ap, u_int); goto nosign; - case 'z': - if (qflag) - uq = va_arg(ap, u_quad_t); +fetch_number: + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); else if (lflag) - ul = va_arg(ap, u_long); + num = va_arg(ap, u_long); else - ul = sign ? - (u_long)va_arg(ap, int) : va_arg(ap, u_int); - base = 16; + num = sign ? (uintmax_t)va_arg(ap, int) : + va_arg(ap, u_int); goto number; -nosign: sign = 0; -number: - if (qflag) { - if (sign && (quad_t)uq < 0) { - neg = 1; - uq = -(quad_t)uq; - } - p = ksprintqn(nbuf, uq, base, &tmp); - } else { - if (sign && (long)ul < 0) { - neg = 1; - ul = -(long)ul; - } - p = ksprintn(nbuf, ul, base, &tmp); +nosign: + sign = 0; +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; } - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + p = ksprintn(nbuf, num, base, &tmp); + if (sharpflag && num != 0) { if (base == 8) tmp++; else if (base == 16) @@ -734,7 +697,7 @@ PCHAR(padc); if (neg) PCHAR('-'); - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { + if (sharpflag && num != 0) { if (base == 8) { PCHAR('0'); } else if (base == 16) { @@ -752,10 +715,8 @@ break; default: - PCHAR('%'); - if (lflag) - PCHAR('l'); - PCHAR(ch); + while (percent < fmt) + PCHAR(*percent++); break; } } @@ -783,7 +744,7 @@ dangling = 0; } msgaddchar('<', NULL); - for (p = ksprintn(nbuf, (u_long)pri, 10, NULL); *p;) + for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL); *p;) msgaddchar(*p--, NULL); msgaddchar('>', NULL); lastpri = pri; --=-=-=-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message