Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Oct 2002 13:42:05 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Mark Murray <mark@grondar.za>
Cc:        cvs-committers@FreeBSD.org, <cvs-all@FreeBSD.org>
Subject:   Re: cvs commit: src/include stdlib.h src/lib/libc/gen getbsize.3 getbsize.c 
Message-ID:  <20021024132124.O25492-100000@gamplex.bde.org>
In-Reply-To: <200210231856.g9NIuIks095533@grimreaper.grondar.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 23 Oct 2002, Mark Murray wrote:

> > >   Make the first argument of getbsize a size_t* instead of an int*, as this is what the quantity actually is. Fix an easy const while I'm here.
> >
> > This breaks binary compatibility on 64-bit machines.
>
> So we perhaps need to bump ${MAJ}?

Of course not.  We need to back out this change.

Another reason to back it out is that it is just wrong.  The header length
is not a size but a field width that needs to be passed to printf via %*.
Field widths have type int.  Bogus conversions are needed to convert it
back to the correct type.  E.g., in the collaterally damaged df.c:

% Index: df.c
% ===================================================================
% RCS file: /home/ncvs/src/bin/df/df.c,v
% retrieving revision 1.43
% retrieving revision 1.44
% diff -u -2 -r1.43 -r1.44
% --- df.c	26 Aug 2002 04:56:23 -0000	1.43
% +++ df.c	23 Oct 2002 22:09:05 -0000	1.44
% @@ -382,5 +382,6 @@
%  {
%  	static long blocksize;
% -	static int headerlen, timesthrough;
% +	static int timesthrough;
% +	static size_t headerlen;

Convert to a wrong type.

%  	static const char *header;
%  	long used, availblks, inodes;
% @@ -393,5 +394,5 @@
%  		} else {
%  			header = getbsize(&headerlen, &blocksize);
% -			mwp->total = imax(mwp->total, headerlen);
% +			mwp->total = imax(mwp->total, (int)headerlen);

Explicitly cast the wrong type back to int.  If we didn't cast it
explicitly then imax()'s protootype would convert it.  imax() returns
the correct type (int) and mwp->total has the correct type, so there
are no further problems.  We use mwp->total for %*.

The conversion that inspire this breakage is also sort of backwards.
From getbsize.c:

%	(void)snprintf(header, sizeof(header), "%ld%s-blocks", n, form);
%	*headerlenp = strlen(header);
%	*blocksizep = blocksize;

Here snprintf() returns the correct length or an error, but we ignore
it and recover the length using strlen().  strlen() returns a size_t, so
lint may warn of possible truncation or sign mismatch errors for the
assignment to *headerlen which had type int.

> Consumers of this interface == { df, du, ls, pkg_install, stat, pstat }
>
> Of the N (<12) calls to the function, 6 of them (one of 2 in df, stat, 3
> in pstat) actually use the returned value. Easy fixes (warnings only).
>
> I don't believe this is a crisis. Make world has fixed worse problems.

There may be many more in ports and third party software.

Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




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