Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jun 2001 09:05:42 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Garance A Drosihn <drosih@rpi.edu>
Cc:        Dima Dorfman <dima@unixfreak.org>, audit@FreeBSD.ORG
Subject:   Re: last(1) WARNS patch for review
Message-ID:  <Pine.BSF.4.21.0106040828500.52604-100000@besplex.bde.org>
In-Reply-To: <p05100e13b740290b2b97@[128.113.24.47]>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 3 Jun 2001, Garance A Drosihn wrote:

> At 8:23 PM -0700 5/29/01, Dima Dorfman wrote:
> >Please review the attached patch to last(1) which silences
> >most of the warnings.  I'm particuarly doubtful about the
> >printf formatting changes.  They seem to be correct, but
> >there might've been a reason why they were originally
> >written incorrectly (a reason other than not compiling
> >with the right -W flags).
> 
> There are a number of hairy issues when going to print out a
> time_t.  See my recent message to -arch, where I quoted most
> of Garrett Wollman's recent message to -stable.  In short:
> 
> A time_t can be integral, floating-point, or complex.  It can
> be signed or unsigned.  It can be "regular size" or "long".
> 
> When it comes to printing, Garrett mentioned:
>       There is a simple way around this, for POSIX systems
>       only: use strftime() with the %s format.
> 
> which I assume means that freebsd has %s in strftime.  If so,
> then maybe the wisest change for 'last' would be to call
> strftime() to get the right string.

Using strftime() would be especially silly in last(1), since the
value to be printed is the difference of two time_t's, and C90
provides a perfectly portable way of printing differences of
time_t's:

	/* The following only assumes that difftime() actually works. */
	printf("%g", difftime(time1, time0));

Dima didn't like my suggestion of using difftime() much, and neither
do I.  It is overkill for a POSIX environment, since a (not so) simple
subtraction can be used.  The time_t's whose difference is being taken
are the login and logout times.  These times can't possibly be more
than 68 years apart until about 2061, since FreeBSD didn't exist until
about 1993, and they are unlikely to be more than 68 years apart after
2061.  Therefore, the time difference is representable as a long, and on
POSIX systems the difference can be computed by simple subtraction
(assuming that the login time is not after the loguout time so that there
are no sign extension problems), and the above can be simplified to:

	/* The following assumes POSIX && time1 >= time0 && difference small. */
	printf("%ld", (long)(time1 - time0));

But using difftime() is much simpler than using strftime().  Half of the
above analysis must be repeated to ensure that (time_t)(time1 - time0)
works right.

It's interesting that difftime() can't fail in C90.  This implies that
doubles can exactly represent the difference between all times that
can be represented as time_t's or that the implementation is of low
quality.

Bruce


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




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