From owner-freebsd-audit Sun Jun 3 16: 7:38 2001 Delivered-To: freebsd-audit@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 5360637B401 for ; Sun, 3 Jun 2001 16:07:35 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id JAA30589; Mon, 4 Jun 2001 09:07:19 +1000 Date: Mon, 4 Jun 2001 09:05:42 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Garance A Drosihn Cc: Dima Dorfman , audit@FreeBSD.ORG Subject: Re: last(1) WARNS patch for review In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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