From owner-freebsd-standards Wed Mar 27 1:20:17 2002 Delivered-To: freebsd-standards@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 1FEB637B405 for ; Wed, 27 Mar 2002 01:20:02 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g2R9K2K53874; Wed, 27 Mar 2002 01:20:02 -0800 (PST) (envelope-from gnats) Date: Wed, 27 Mar 2002 01:20:02 -0800 (PST) Message-Id: <200203270920.g2R9K2K53874@freefall.freebsd.org> To: freebsd-standards@FreeBSD.org Cc: From: "Tim J. Robbins" Subject: Re: standards/36191: P1003.1-2001 csplit utility Reply-To: "Tim J. Robbins" Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The following reply was made to PR standards/36191; it has been noted by GNATS. From: "Tim J. Robbins" To: Stefan Farfeleder Cc: freebsd-gnats-submit@FreeBSD.ORG Subject: Re: standards/36191: P1003.1-2001 csplit utility Date: Wed, 27 Mar 2002 20:06:41 +1100 On Tue, Mar 26, 2002 at 08:07:20PM +0100, Stefan Farfeleder wrote: > According to P1003.1-2001 '+' is optional. > Why is a negative offset a 'bad offset'? Thanks for pointing these out. > > X if (sufflen + strlen(prefix) >= PATH_MAX) > > X errx(1, "name too long"); > > It might be better to check this for each file. I've decided to do what GNU csplit does, and stop making output files once the maximum number is reached. The standard isn't clear about this. > The improvement posted by Brian F. Feldman (and reposted by you as a > patch) has a bug: > > >+ snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, sufflen, > >+ nfiles); > > >+ snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix, sufflen, i); > > sufflen has type long, but '*' wants an int. Fixed. Here is a new patch incorporating fixes for the problems you found. --- csplit.c 2002/03/23 03:36:26 1.18 +++ csplit.c 2002/03/27 09:01:24 1.21 @@ -44,7 +44,7 @@ #include __FBSDID("$FreeBSD$"); -__RCSID("$Id: csplit.c,v 1.18 2002/03/23 03:36:26 tim Exp $"); +__RCSID("$Id: csplit.c,v 1.21 2002/03/27 09:01:24 tim Exp $"); #include @@ -80,6 +80,7 @@ long lineno; /* Current line number in input file */ long reps; /* Number of repetitions for this pattern */ long nfiles; /* Number of files output so far */ +long maxfiles; /* Maximum number of files we can create */ char currfile[PATH_MAX]; /* Current output file */ const char *infn; /* Name of the input file */ FILE *infile; /* Input file handle */ @@ -93,7 +94,7 @@ { FILE *fp; - snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, sufflen, + snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, (int)sufflen, nfiles); if ((fp = fopen(currfile, "w+")) == NULL) err(1, "%s", currfile); @@ -113,7 +114,8 @@ return; for (i = 0; i < nfiles; i++) { - snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix, sufflen, i); + snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix, + (int)sufflen, i); unlink(fnbuf); } } @@ -186,7 +188,7 @@ errx(1, "can't read overflowed output"); if (fseek(ofp, -(long)nread, SEEK_CUR) != 0) err(1, "%s", currfile); - for (i = 0; i < nread; i++) + for (i = 1; i <= nread; i++) if (buf[nread - i] == '\n' && n-- == 0) break; } while (n > 0); @@ -221,11 +223,9 @@ *pofs++ = '\0'; /* point to offset from regexp, zap trailing char */ if (*pofs != '\0') { - if (*pofs != '+' && *pofs != '-') - errx(1, "%s: bad offset", pofs); errno = 0; ofs = strtol(pofs, &ep, 10); - if (ofs < 0 || *ep != '\0' || errno != 0) + if (*ep != '\0' || errno != 0) errx(1, "%s: bad offset", pofs); } else ofs = 0; @@ -296,7 +296,7 @@ if (lastline <= lineno) errx(1, "%s: can't go backwards", expr); - for (;;) { + while (nfiles < maxfiles - 1) { ofp = newfile(); while (lineno + 1 != lastline) if ((p = getline()) == NULL || fputs(p, ofp) != 0) @@ -318,6 +318,7 @@ char *ep, *p; FILE *ofp; int ch; + long i, n; kflag = sflag = 0; prefix = "xx"; @@ -369,7 +370,15 @@ truncofs = 0; overfile = NULL; - while ((expr = *argv++) != NULL) { + for (maxfiles = 1, i = 0; i < sufflen; i++) { + n = maxfiles; + maxfiles *= 10; + if (maxfiles / 10 != n) + errx(1, "%ld: suffix too long (limit %ld)", + sufflen, i); + } + + while (nfiles < maxfiles - 1 && (expr = *argv++) != NULL) { /* Look ahead & see if this pattern has any repetitions */ if (*argv != NULL && **argv == '{') { errno = 0; @@ -384,7 +393,7 @@ /* Regular expression copy or ignore */ do do_rexp(expr); - while (reps-- != 0); + while (reps-- != 0 && nfiles < maxfiles - 1); } else if (isdigit(*expr)) do_lineno(expr); else To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message