From owner-freebsd-bugs Sun Nov 19 16: 0: 7 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 6D72B37B4CF for ; Sun, 19 Nov 2000 16:00:01 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id QAA25441; Sun, 19 Nov 2000 16:00:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefour.acs.rpi.edu (freefour.acs.rpi.edu [128.113.24.91]) by hub.freebsd.org (Postfix) with ESMTP id A1C4737B479; Sun, 19 Nov 2000 15:51:31 -0800 (PST) Received: (from gad@localhost) by freefour.acs.rpi.edu (8.9.3/8.9.3) id SAA30775; Sun, 19 Nov 2000 18:51:26 -0500 (EST) (envelope-from gad) Message-Id: <200011192351.SAA30775@freefour.acs.rpi.edu> Date: Sun, 19 Nov 2000 18:51:26 -0500 (EST) From: Garance A Drosehn Reply-To: gad@eclipse.acs.rpi.edu To: FreeBSD-gnats-submit@freebsd.org Cc: gad@eclipse.acs.rpi.edu, gad@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/22965: [PATCH] fix for minor bug in libc/gen/getcap.c Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 22965 >Category: bin >Synopsis: [PATCH] fix for minor bug in libc/gen/getcap.c >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Nov 19 16:00:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Garance A Drosehn >Release: FreeBSD 3.2-RELEASE i386 >Organization: RPI ; Troy NY >Environment: While compiling FreeBSD's lpr/lpd for use on some other platforms, I ran into a fairly nasty bug on redhat linux. As near as I can tell, the bug has existed in FreeBSD's 'getcap' for several years without it causing any known problems, but I do believe the code is wrong and should be fixed anyway. (while this send-pr is coming from a 3.2 system, the patch is for the source in freebsd-current, ie, 5.x as of Nov 2000) >Description: You probably don't want to know what the problem is under linux... However, the problem comes down to code which does: (void)fclose(pfp); if (ferror(pfp)) { ...do stuff... } According to the "single unix spec", the behavior of calling ANY "f-routine" on a closed stream is undefined. I take it to mean that's a bad idea. Certainly on linux it can trigger some major headaches. Also, I don't see what is to be gained by calling ferror in the above case. My change is just to USE the return code from fclose, instead of throwing it away, and have error-processing key off that instead of ferror. >How-To-Repeat: .na. >Fix: Here is the patch I propose. If no one objects to this, I can commit this patch sometime after thanksgiving. Or I would be more than happy if someone else wants to claim ownership of getcap, and they generate their own patch for it... :-) This also initializes global (static) variables to appropriate values, although that probably doesn't effect anything. Index: getcap.c =================================================================== RCS file: /home/ncvs/src/lib/libc/gen/getcap.c,v retrieving revision 1.12 diff -u -r1.12 getcap.c --- getcap.c 2000/05/21 02:55:09 1.12 +++ getcap.c 2000/11/19 23:09:15 @@ -62,9 +62,9 @@ #define TCERR (char)1 #define SHADOW (char)2 -static size_t topreclen; /* toprec length */ -static char *toprec; /* Additional record specified by cgetset() */ -static int gottoprec; /* Flag indicating retrieval of toprecord */ +static size_t topreclen = 0; /* toprec length */ +static char *toprec = NULL; /* Additional record specified by cgetset() */ +static int gottoprec = 0; /* Flag indicating retrieval of toprecord */ static int cdbget __P((DB *, char **, char *)); static int getent __P((char **, u_int *, char **, int, char *, int, char *)); @@ -619,9 +619,9 @@ return (cgetnext(buf, db_array)); } -static FILE *pfp; -static int slash; -static char **dbp; +static FILE *pfp = NULL; +static int slash = 0; /* on if last line read-in ended with a '/' */ +static char **dbp = NULL; int cgetclose() @@ -647,7 +647,7 @@ char **db_array; { size_t len; - int status, i, done; + int done, fcloseres, i, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; @@ -665,8 +665,9 @@ } else { line = fgetln(pfp, &len); if (line == NULL && pfp) { - (void)fclose(pfp); - if (ferror(pfp)) { + fcloseres = fclose(pfp); + pfp = NULL; + if (fcloseres != 0) { (void)cgetclose(); return (-1); } else { @@ -724,8 +725,9 @@ } else { /* name field extends beyond the line */ line = fgetln(pfp, &len); if (line == NULL && pfp) { - (void)fclose(pfp); - if (ferror(pfp)) { + fcloseres = fclose(pfp); + pfp = NULL; + if (fcloseres != 0) { (void)cgetclose(); return (-1); } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message