Date: Sun, 18 Dec 2011 20:08:16 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Dimitry Andric <dim@freebsd.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r228678 - head/usr.sbin/rpc.ypupdated Message-ID: <20111218194714.W1622@besplex.bde.org> In-Reply-To: <201112180040.pBI0eVKi084246@svn.freebsd.org> References: <201112180040.pBI0eVKi084246@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 18 Dec 2011, Dimitry Andric wrote: > Log: > In usr.sbin/rpc.ypupdated/yp_dbupdate.c, use the appropriate printf > length modifier for time_t (after casting it to intmax_t). > > MFC after: 1 week > > Modified: > head/usr.sbin/rpc.ypupdated/yp_dbupdate.c > > Modified: head/usr.sbin/rpc.ypupdated/yp_dbupdate.c > ============================================================================== > --- head/usr.sbin/rpc.ypupdated/yp_dbupdate.c Sun Dec 18 00:34:42 2011 (r228677) > +++ head/usr.sbin/rpc.ypupdated/yp_dbupdate.c Sun Dec 18 00:40:30 2011 (r228678) > @@ -130,7 +130,7 @@ ypmap_update(char *netname, char *map, u > return(rval); > } > > - snprintf(yplastbuf, sizeof(yplastbuf), "%lu", time(NULL)); > + snprintf(yplastbuf, sizeof(yplastbuf), "%ju", (intmax_t)time(NULL)); > key.data = yp_last; > key.size = strlen(yp_last); > data.data = (char *)&yplastbuf; It still has a sign mismatch. time_t can be unsigned, but in practice isn't. Now a sign mismatch is certain, since intmax_t is signed but the format is still unsigned. If time() somehow failed, it would return -1 and this is printed as an inscrutable huge number (1844mumble with 64-bit intmax_t). If time_t were unsigned, then there would be another sign error converting it to intmax_t. Casting to intmax_t is silly for time_t, at least for current times. Many places cast to long. This is guaranteed to work until 2038 even on i386. It will keep working past then provided long is enlarged before then. I think long is already 64 bits on all arches that have 64-bit time_t. Determining the appropriate printf modifier for time_t is especially difficult, even in POSIX, since POSIX still allows it to be a floating point type (it now says "integer or real floating type" where it used to say "arithmetic type". C still says "arithmetic type", and that now seems to allow it to be a complex floating point type too). In C, there might be no appropriate modifier, since the encoding is unspecified but code like the above wants seconds [since the Epoch]. Apart from that, determination of the appropriate modifier requires either: A. first determine if it is floating point. If so, cast to long double, etc. else determine if it is signed. If so, cast to intmax_t, etc. else cast to uintmax_t. B. just assume that it is signed integer and cast to the simplest type that works. I prefer plain long. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111218194714.W1622>