bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Fix diff build on arm


From: Paul Eggert
Subject: Re: [PATCH] Fix diff build on arm
Date: Mon, 18 Jun 2007 15:44:54 -0700
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

Xin LI <address@hidden> writes:

> I have just committed a changeset which will hopefully fix diffutils
> build on FreeBSD/arm.  The problem is that time_t on FreeBSD/arm is 64
> bits while long int is 32 bits, therefore:

That's going to break many programs other than diffutils, I'm afraid.

>       verify (info_preserved, sizeof inf->stat.st_mtime <= sizeof sec);
>
> would fail because sec is defined as long int.

You're noticing this problem with diffutils because diffutils takes
the trouble to catch it at compile-time.  Most other apps don't do
that.  Instead, they'll silently do the wrong thing for time stamps
that don't fit in 'long int'.  So you'll have several latent bugs in
your applications.

> -       sprintf (buf, "%ld.%.9d", sec, nsec);
> +       sprintf (buf, "%jd.%.9d", (intmax_t)sec, nsec);

This patch is not portable to pre-C99 hosts.  There are still a lot of
hosts out there that are pre-C99.

Is there any possibility that FreeBSD/arm can be fixed to have 64-bit
long int?  This is what nearly every other platform does.

Anyway, I installed the following patch, which should fix the problem
for diffutils though not other apps.  Doing this portably is a bit
painful (even the patch below isn't 100% portable to all C99 hosts);
this may help to explain why a lot of software assumes that time_t
fits in long int.

2007-06-18  Paul Eggert  <address@hidden>

        * src/context.c (print_context_label): Don't assume that time_t
        fits in long int, since it doesn't in FreeBSD/arm.  Problem
        reported by Xin Li in
        <http://lists.gnu.org/archive/html/bug-gnu-utils/2007-06/msg00091.html>.

--- src/context.c       5 Sep 2006 22:57:09 -0000       1.20
+++ src/context.c       18 Jun 2007 22:23:16 -0000
@@ -54,9 +54,23 @@ print_context_label (char const *mark,
       int nsec = get_stat_mtime_ns (&inf->stat);
       if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec)))
        {
-         long int sec = inf->stat.st_mtime;
-         verify (sizeof inf->stat.st_mtime <= sizeof sec);
-         sprintf (buf, "%ld.%.9d", sec, nsec);
+         verify ((time_t) 1.5 == 1);
+         if (LONG_MIN <= TYPE_MINIMUM (time_t)
+             && TYPE_MAXIMUM (time_t) <= LONG_MAX)
+           {
+             long int sec = inf->stat.st_mtime;
+             sprintf (buf, "%ld.%.9d", sec, nsec);
+           }
+         else if (TYPE_MAXIMUM (time_t) <= INTMAX_MAX)
+           {
+             intmax_t sec = inf->stat.st_mtime;
+             sprintf (buf, "%"PRIdMAX".%.9d", sec, nsec);
+           }
+         else
+           {
+             uintmax_t sec = inf->stat.st_mtime;
+             sprintf (buf, "%"PRIuMAX".%.9d", sec, nsec);
+           }
        }
       fprintf (outfile, "%s %s\t%s\n", mark, inf->name, buf);
     }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]