Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Nov 2000 18:51:26 -0500 (EST)
From:      Garance A Drosehn <gad@freefour.acs.rpi.edu>
To:        FreeBSD-gnats-submit@freebsd.org
Cc:        gad@eclipse.acs.rpi.edu, gad@freebsd.org
Subject:   bin/22965: [PATCH] fix for minor bug in libc/gen/getcap.c
Message-ID:  <200011192351.SAA30775@freefour.acs.rpi.edu>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011192351.SAA30775>