Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-04 Thread Paul Eggert

On 10/3/22 12:56, Paul Eggert wrote:
In looking through old dev histories it appears Paul pushes changes 
every now and then, so I'll wait until he's pushed his next batch of 
changes, which will presumably include some timestamp-related fixes, 
before looking into this again.


Thanks, that merge looks good to me.

I might also suggest installing the attached, which contains code that 
won't be executed on any platform that I know about, but which is needed 
to avoid undefined behavior on platforms where INT_MAX == INTMAX_MAX 
(maybe a signal-processing CPU? :-). This is to document the assumption 
that INT_MAX < INTMAX_MAX, not to fix any real bug on any platform I 
know about. Of course this is low priority.
From 81c5f5de755911f3a24900886d57a7b0dbd0178b Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 4 Oct 2022 15:38:14 -0700
Subject: [PATCH] Fix theoretical bug when int == intmax_t
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/file.c (file_timestamp_sprintf):
Port to platforms where int == intmax_t.  I don’t know of any such
platforms, so to some extent this patch merely documents the
assumption that INT_MAX < INTMAX_MAX.
---
 src/file.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/file.c b/src/file.c
index 62b8dd00..b0b24cc9 100644
--- a/src/file.c
+++ b/src/file.c
@@ -1019,10 +1019,15 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
 
   if (tm)
 {
+#if defined INTMAX_MAX && INTMAX_MAX - 1900 < INT_MAX
+  /* A theoretical host where (intmax_t) INT_MAX + 1900 overflows.  */
+  strftime (p, FILE_TIMESTAMP_PRINT_LEN_BOUND + 1, "%Y-%m-%d %H:%M:%S", tm);
+#else
   intmax_t year = tm->tm_year;
   sprintf (p, "%04" PRIdMAX "-%02d-%02d %02d:%02d:%02d",
year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
+#endif
 }
   else if (t < 0)
 sprintf (p, "%" PRIdMAX, (intmax_t) t);
-- 
2.37.3



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-04 Thread Paul Smith
On Tue, 2022-10-04 at 09:06 +0300, Eli Zaretskii wrote:
> > From: Paul Smith 
> > Cc: bug-make@gnu.org
> > Date: Mon, 03 Oct 2022 16:14:01 -0400
> > 
> > I needed another set of changes, since intmax_t is a new type and
> > is not available on Windows so we needed to add it to configure.ac
> > etc.
> 
> By "not available on Windows" you mean in MSVC, right?  Because MinGW
> (both flavors of it) does provide it (in stdint.h).

Yes, sorry.  I think this is covered because we have:

  /* Define to 1 if you have the  header file. */
  #ifdef __MINGW32__
  #define HAVE_STDINT_H 1
  #endif
   ...

  /* Define {u,}intmax_t if not defined in  or . */
  #if !HAVE_STDINT_H && !HAVE_INTTYPES_H
  #define intmax_t long long
  #define uintmax_t unsigned long long
  #endif

Thx.



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-04 Thread Eli Zaretskii
> From: Paul Smith 
> Cc: bug-make@gnu.org
> Date: Mon, 03 Oct 2022 16:14:01 -0400
> 
> I needed another set of changes, since intmax_t is a new type and is
> not available on Windows so we needed to add it to configure.ac etc.

By "not available on Windows" you mean in MSVC, right?  Because MinGW
(both flavors of it) does provide it (in stdint.h).



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread Paul Smith
On Sun, 2022-10-02 at 17:06 -0700, Paul Eggert wrote:
> On 10/2/22 14:09, Paul Smith wrote:
> 
> > I applied these changes but made a few mods:
> 
> Thanks. I assume you'll push this to savannah at some point?

Pushed now.

I needed another set of changes, since intmax_t is a new type and is
not available on Windows so we needed to add it to configure.ac etc.

I did some other cleanups which might or might not be helpful, getting
rid of most warnings on Windows (with Visual Studio: I don't have MinGW
compilers).  The ones that are left are either in "external code"
(glob/fnmatch) or are annoying to deal with (read(2) and write(2) don't
use size_t for their length arguments on Windows for example).



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread Paul Eggert

On 10/3/22 09:12, rsbec...@nexbridge.com wrote:

This happens in AR and TAR also, which appear to be limited to 32-bit time_t on 
some platforms. It's a struggle but we have some time to deal with it.


Yes, I've been part of an ongoing effort to make GNU apps Y2038-safe, 
even on 32-bit platforms. This is why I've been submitting patches to 
GNU Make. Many other GNU apps are also affected; core apps are mostly 
fixed already.


It's not just the year 2038, though that's the most pressing. 
Traditional tar format uses an unsigned 33-bit timestamp and stops 
working after 2242-03-16 12:56:31 UTC. ar format uses a 12-digit 
timestamp and stops working after 318857-05-20 17:46:39 UTC. Of course 
these are far-future problems - except that people or programs might use 
'touch' to create far-future problems today. GNU tar has long had format 
fixes (gnu and pax formats) for this. GNU ar doesn't have a fix but 
that's less important. Etc.


In looking through old dev histories it appears Paul pushes changes 
every now and then, so I'll wait until he's pushed his next batch of 
changes, which will presumably include some timestamp-related fixes, 
before looking into this again.




RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread rsbecker
On October 3, 2022 3:56 PM, Paul Eggert wrote:
>On 10/3/22 09:12, rsbec...@nexbridge.com wrote:
>> This happens in AR and TAR also, which appear to be limited to 32-bit time_t 
>> on
>some platforms. It's a struggle but we have some time to deal with it.
>
>Yes, I've been part of an ongoing effort to make GNU apps Y2038-safe, even on
>32-bit platforms. This is why I've been submitting patches to GNU Make. Many
>other GNU apps are also affected; core apps are mostly fixed already.
>
>It's not just the year 2038, though that's the most pressing.
>Traditional tar format uses an unsigned 33-bit timestamp and stops working 
>after
>2242-03-16 12:56:31 UTC. ar format uses a 12-digit timestamp and stops working
>after 318857-05-20 17:46:39 UTC. Of course these are far-future problems - 
>except
>that people or programs might use 'touch' to create far-future problems today.
>GNU tar has long had format fixes (gnu and pax formats) for this. GNU ar 
>doesn't
>have a fix but that's less important. Etc.
>
>In looking through old dev histories it appears Paul pushes changes every now 
>and
>then, so I'll wait until he's pushed his next batch of changes, which will 
>presumably
>include some timestamp-related fixes, before looking into this again.

Thanks. I'll be keeping an eye out for those.




Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread Paul Eggert

On 10/2/22 14:23, Paul Smith wrote:

I would be happy to use it, if using it didn't import a ton of other
things that require POSIX tools AND an already-working make program.


Oh, right, sorry, I was confusing inttypes.h (which takes some 
configuring) with intprops.h (which doesn't).



On 10/2/22 14:48, rsbec...@nexbridge.com wrote:


Gnulib is not available on the platform I maintain


It doesn't have to be available. Unlike most libraries, Gnulib is a 
source-code library so it doesn't matter whether it's available or 
installed as a library on your platform in the usual sense. GNU 'make' 
is already Gnulib and works fine on HPE NonStop.




RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread rsbecker
On October 2, 2022 8:07 PM Paul Eggert wrote:
>On 10/2/22 14:09, Paul Smith wrote:
>
>> I applied these changes but made a few mods:
>
>Thanks. I assume you'll push this to savannah at some point? I had been working
>on merging with your more-recent changes to GNU Make, and it wouldn't hurt to
>have another pair of eyes look at this finicky business once you've published 
>your
>mods.
>
>
>> Is there ever a system anywhere that can't represent any remotely
>> useful year value using an int (even if you add
>> 1900 to it :) )?
>
>My use case was if someone sets a file timestamp to something oddball and then
>'make' mishandles the result. This sort of thing happens more often than one
>would like.
>
>As it happens today I fixed a glitch in an oddball part of the GNU Emacs build
>process that uses "TZ=UTC0 touch -t 19700101" to set file timestamps to 0 
>and
>thus fool 'make'. (This was not my idea! and doesn't GNU 'make' treat a zero 
>file
>timestamp specially? but I digress.) It's not a stretch to think of someone 
>using
>'touch' to set file timestamps in the far future, for a similar reason.
>
>For example, here's what happens on a filesystem that supports 64-bit
>timestamps:
>
>   $ TZ=UTC0 touch -d @67767976233532800 foo
>   $ TZ=UTC0 ls -l foo
>   -rw-rw-r-- 1 eggert faculty 0 Jan  1  2147483648 foo
>
>Here the year is 2**31, which works because tm_year is 2**31 - 1900 which fits 
>in
>32-bit int even though 2**31 does not fit. This works with GNU ls, which uses
>strftime which does things correctly. It won't work with GNU Make's C code that
>simply adds 1900 to tm_year.
>
>Come to think of it, if file_timestamp_sprintf simply used strftime instead of
>sprintf that would be more-straightforward fix (this is part of the "finicky 
>business"
>I was talking about earlier...).

At least you get bigger numbers with an unsigned time_t. On my platform, I get 
stuff like May 1954. This happens in AR and TAR also, which appear to be 
limited to 32-bit time_t on some platforms. It's a struggle but we have some 
time to deal with it.

-Randall




Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-03 Thread Eli Zaretskii
> From: Paul Smith 
> Cc: bug-make@gnu.org
> Date: Sun, 02 Oct 2022 17:23:46 -0400
> 
> On Thu, 2022-09-22 at 11:00 -0700, Paul Eggert wrote:
> > (This would not be needed if 'make' used Gnulib's inttypes module.)
> 
> I would be happy to use it, if using it didn't import a ton of other
> things that require POSIX tools AND an already-working make program.
> 
> I understand that this type of reuse makes things easier for the gnulib
> folks, but for GNU make I'm not ready to drop support for platforms
> that are not POSIX enough to run configure, and that don't already have
> "make" available.

It's not just that: some of those platforms aren't even supported by
Gnulib.  For example, DJGPP (a.k.a. "MSDOS") support was AFAIK
dropped, and MinGW (a.k.a. "native MS-Windows") is not supported on
systems older than Windows 7 or 8.1.



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread Paul Eggert

On 10/2/22 14:09, Paul Smith wrote:


I applied these changes but made a few mods:


Thanks. I assume you'll push this to savannah at some point? I had been 
working on merging with your more-recent changes to GNU Make, and it 
wouldn't hurt to have another pair of eyes look at this finicky business 
once you've published your mods.




Is there ever a system anywhere that can't
represent any remotely useful year value using an int (even if you add
1900 to it :) )?


My use case was if someone sets a file timestamp to something oddball 
and then 'make' mishandles the result. This sort of thing happens more 
often than one would like.


As it happens today I fixed a glitch in an oddball part of the GNU Emacs 
build process that uses "TZ=UTC0 touch -t 19700101" to set file 
timestamps to 0 and thus fool 'make'. (This was not my idea! and doesn't 
GNU 'make' treat a zero file timestamp specially? but I digress.) It's 
not a stretch to think of someone using 'touch' to set file timestamps 
in the far future, for a similar reason.


For example, here's what happens on a filesystem that supports 64-bit 
timestamps:


  $ TZ=UTC0 touch -d @67767976233532800 foo
  $ TZ=UTC0 ls -l foo
  -rw-rw-r-- 1 eggert faculty 0 Jan  1  2147483648 foo

Here the year is 2**31, which works because tm_year is 2**31 - 1900 
which fits in 32-bit int even though 2**31 does not fit. This works with 
GNU ls, which uses strftime which does things correctly. It won't work 
with GNU Make's C code that simply adds 1900 to tm_year.


Come to think of it, if file_timestamp_sprintf simply used strftime 
instead of sprintf that would be more-straightforward fix (this is part 
of the "finicky business" I was talking about earlier...).




RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread rsbecker
On October 2, 2022 6:13 PM, Paul Smith wrote:
>On Sun, 2022-10-02 at 17:48 -0400, rsbec...@nexbridge.com wrote:
>> > I understand that this type of reuse makes things easier for the
>> > gnulib folks, but for GNU make I'm not ready to drop support for
>> > platforms that are not POSIX enough to run configure, and that don't
>> > already have "make" available.  So gnulib modules that require them
>> > aren't available to GNU make (at least, not without modifications).
>>
>> Thank you for this comment. Gnulib is not available on the platform I
>> maintain because of its high number of dependencies (including gcc
>> itself, which cannot build on HPE NonStop). Keeping dependencies down
>> is helpful for those outside of the explicit gcc support base.
>
>Really?  I'd be pretty surprised if gnulib modules require GCC.  In my 
>experience
>gnulib-enabled software can be used with lots of compilers include MSVC and
>Clang, plus others that are less well-known of course.
>One of the main points of gnulib is to hide compiler differences (the other 
>being to
>hide OS system differences).
>
>Gnulib does require a C compiler which is at least notionally C99 conforming,
>though.

I was thinking of glibc, not gnulib. My bad. Still, recent version of gnulib 
have been problematic because of configure.




Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread Paul Smith
On Sun, 2022-10-02 at 17:48 -0400, rsbec...@nexbridge.com wrote:
> > I understand that this type of reuse makes things easier for the
> > gnulib folks, but for GNU make I'm not ready to drop support for
> > platforms that are not POSIX enough to run configure, and that
> > don't already have "make" available.  So gnulib modules that
> > require them aren't available to GNU make (at least, not without
> > modifications).
> 
> Thank you for this comment. Gnulib is not available on the platform I
> maintain because of its high number of dependencies (including gcc
> itself, which cannot build on HPE NonStop). Keeping dependencies down
> is helpful for those outside of the explicit gcc support base.

Really?  I'd be pretty surprised if gnulib modules require GCC.  In my
experience gnulib-enabled software can be used with lots of compilers
include MSVC and Clang, plus others that are less well-known of course.
One of the main points of gnulib is to hide compiler differences (the
other being to hide OS system differences).

Gnulib does require a C compiler which is at least notionally C99
conforming, though.



RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread rsbecker
On October 2, 2022 5:24 PM, Paul Smith wrote:
>On Thu, 2022-09-22 at 11:00 -0700, Paul Eggert wrote:
>> (This would not be needed if 'make' used Gnulib's inttypes module.)
>
>I would be happy to use it, if using it didn't import a ton of other things 
>that
>require POSIX tools AND an already-working make program.
>
>I understand that this type of reuse makes things easier for the gnulib folks, 
>but
>for GNU make I'm not ready to drop support for platforms that are not POSIX
>enough to run configure, and that don't already have "make" available.  So 
>gnulib
>modules that require them aren't available to GNU make (at least, not without
>modifications).

Thank you for this comment. Gnulib is not available on the platform I maintain 
because of its high number of dependencies (including gcc itself, which cannot 
build on HPE NonStop). Keeping dependencies down is helpful for those outside 
of the explicit gcc support base.

-Randall




Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread Paul Smith
On Thu, 2022-09-22 at 11:00 -0700, Paul Eggert wrote:
> (This would not be needed if 'make' used Gnulib's inttypes module.)

I would be happy to use it, if using it didn't import a ton of other
things that require POSIX tools AND an already-working make program.

I understand that this type of reuse makes things easier for the gnulib
folks, but for GNU make I'm not ready to drop support for platforms
that are not POSIX enough to run configure, and that don't already have
"make" available.  So gnulib modules that require them aren't available
to GNU make (at least, not without modifications).



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-10-02 Thread Paul Smith
On Thu, 2022-09-22 at 11:00 -0700, Paul Eggert wrote:
> On 9/21/22 23:49, Eli Zaretskii wrote:
> > This will cause problems in the native MS-Windows builds, where
> > printf in the system C runtime doesn't support %lld and %llu.
> 
> Thanks for the review. Revised patch attached. It also addresses your
> comment about the commit message, plus it fixes a couple of places
> where I mistakenly used PRI* macros instead of SCN* macros.

Are there really any AR format standards that use timestamps >32bits? 
Maybe so.  Note that for ar support (most of it anyway) we don't care
what the size of time_t is, we only care about how large the value that
could appear in an archive's modification time field is.

I applied these changes but made a few mods:

Instead of _PRI64_PREFIX I used MK_PRI64_PREFIX because the former is a
reserved preprocessor token for the system.

Wherever we used string concatenation I added a space between the
string and the token: I realize in C it doesn't matter but in C++ it
can matter and so I prefer to just use the same format everywhere.

I had a question about this change:

@@ -1018,13 +1018,16 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP
ts)
   struct tm *tm = localtime ();
 
   if (tm)
-sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
+{
+  intmax_t year = tm->tm_year;
+  sprintf (p, "%04" PRIdMAX "-%02d-%02d %02d:%02d:%02d",
+   year + 1900, tm->tm_mon + 1, tm->tm_mday,
+   tm->tm_hour, tm->tm_min, tm->tm_sec);
+}

Is this really needed?  Is there ever a system anywhere that can't
represent any remotely useful year value using an int (even if you add
1900 to it :) )?  The POSIX spec, for sure, defined the struct tm
tm_year data member to be of type int.



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-23 Thread Eli Zaretskii
> Date: Thu, 22 Sep 2022 11:00:52 -0700
> Cc: rsbec...@nexbridge.com, bug-make@gnu.org
> From: Paul Eggert 
> 
> On 9/21/22 23:49, Eli Zaretskii wrote:
> > This will cause problems in the native MS-Windows builds, where printf
> > in the system C runtime doesn't support %lld and %llu.
> 
> Thanks for the review. Revised patch attached. It also addresses your 
> comment about the commit message, plus it fixes a couple of places where 
> I mistakenly used PRI* macros instead of SCN* macros.

Thanks, this LGTM.



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-22 Thread Paul Eggert

On 9/21/22 23:49, Eli Zaretskii wrote:

This will cause problems in the native MS-Windows builds, where printf
in the system C runtime doesn't support %lld and %llu.


Thanks for the review. Revised patch attached. It also addresses your 
comment about the commit message, plus it fixes a couple of places where 
I mistakenly used PRI* macros instead of SCN* macros.


Oh, one more thing, I forgot, this patch also fixes an unlikely buffer 
write overrun in ar_member_touch with an outlandishly-large timestamp. I 
mentioned that in the commit message too, and changed "<=" to "<" to 
make sure the updated archive header would be readable.


There are still some potential buffer read overruns in the sscanf calls 
in arscan.c but these could be handled by a separate patch (and are less 
important).From d6b8ac5e3051f863463df5ff03c295df984245cc Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 20 Sep 2022 14:18:00 -0700
Subject: [PATCH] Port to 32-bit long + 64-bit time_t

Don't assume that time_t fits in long, as some hosts (e.g.,
glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t.
* bootstrap.conf (gnulib_modules): Add largefile, to support
files with timestamps after Y2038 on hosts with 32-bit long.
* configure.ac: Do not call AC_SYS_LARGEFILE,
as the largefile module does that for us.
* src/ar.c: Include intprops.h, for TYPE_MAXIMUM,
as INTEGER_TYPE_MAXIMUM does not work on time_t
without issuing a bunch of warnings.
(ar_member_date): Check that result is in time_t range.
* src/ar.c (ar_member_date, ar_glob_match):
* src/arscan.c (VMS_function, VMS_function_ret, ar_scan)
(parse_int, ar_scan, ar_member_pos, ar_member_touch)
(describe_member):
* src/file.c (file_timestamp_sprintf):
Use intmax_t/uintmax_t instead of long/unsigned long for values
that might be time_t.
* src/arscan.c (ar_member_touch): Fix buffer overrun if the
timestamp is too large.
* src/makeint.h (PRIdMAX, PRIuMAX, SCNdMAX): Define if not already
defined, via an intermediate _PRI64_PREFIX macro, taken from Gnulib.
(This would not be needed if 'make' used Gnulib's inttypes module.)
---
 bootstrap.conf |  1 +
 configure.ac   |  5 -
 src/ar.c   | 15 ---
 src/arscan.c   | 44 
 src/file.c | 13 -
 src/makeint.h  | 21 ++---
 6 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index b1ee947d..1dc096db 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -60,5 +60,6 @@ fdl
 findprog-in
 getloadavg
 host-cpu-c-abi
+largefile
 make-glob
 make-macros"
diff --git a/configure.ac b/configure.ac
index e08e75ad..11e9ed12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,11 +57,6 @@ AC_C_BIGENDIAN
 AM_GNU_GETTEXT_VERSION([0.19.4])
 AM_GNU_GETTEXT([external])
 
-# This test must come as early as possible after the compiler configuration
-# tests, because the choice of the file model can (in principle) affect
-# whether functions and headers are available, whether they work, etc.
-AC_SYS_LARGEFILE
-
 # Checks for libraries.
 AC_SEARCH_LIBS([strerror],[cposix])
 AC_SEARCH_LIBS([getpwnam], [sun])
diff --git a/src/ar.c b/src/ar.c
index 7a26662c..48ef5e44 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -22,6 +22,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "filedef.h"
 #include "dep.h"
 #include 
+#include 
 
 /* Return nonzero if NAME is an archive-member reference, zero if not.  An
archive-member reference is a name like 'lib(member)' where member is a
@@ -69,10 +70,10 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
 /* This function is called by 'ar_scan' to find which member to look at.  */
 
 /* ARGSUSED */
-static long int
+static intmax_t
 ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
   long int hdrpos UNUSED, long int datapos UNUSED,
-  long int size UNUSED, long int date,
+  long int size UNUSED, intmax_t date,
   int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
   const void *name)
 {
@@ -86,7 +87,7 @@ ar_member_date (const char *name)
 {
   char *arname;
   char *memname;
-  long int val;
+  intmax_t val;
 
   ar_parse_name (name, , );
 
@@ -111,7 +112,7 @@ ar_member_date (const char *name)
 
   free (arname);
 
-  return (val <= 0 ? (time_t) -1 : (time_t) val);
+  return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
 }
 
 /* Set the archive-member NAME's modtime to now.  */
@@ -194,10 +195,10 @@ struct ar_glob_state
 /* This function is called by 'ar_scan' to match one archive
element against the pattern in STATE.  */
 
-static long int
+static intmax_t
 ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
-   long int size UNUSED, long int date UNUSED, int uid U

Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-22 Thread Eli Zaretskii
> Date: Wed, 21 Sep 2022 17:58:20 -0700
> Cc: bug-make@gnu.org
> From: Paul Eggert 
> 
> On 9/20/22 18:48, rsbec...@nexbridge.com wrote:
> > I am sorry to say that the %j prefix is not safe or portable. There are
> > major production platforms where this is not supported. I work on one of
> > them.
> 
> Which platform and version? I'd like to document this in Gnulib. Some 
> other GNU programs are using %j now so it might make sense for you to 
> file an enhancement request at some point, assuming %j is not supported 
> even in the latest version of the platform.
> 
> Anyway, thanks, revised GNU Make patch attached; it does not assume %j.

The log message still says it does:

> Don't assume that time_t fits in long, as some hosts (e.g.,
> glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t.
> This fix uses C99 sprintf/scanf %jd and %ju, which is
> safe to assume nowadays.
> --- a/src/makeint.h
> +++ b/src/makeint.h
> @@ -294,6 +294,12 @@ char *strerror (int errnum);
>  #if HAVE_STDINT_H
>  # include 
>  #endif
> +#ifndef PRIdMAX
> +# define PRIdMAX "lld"
> +#endif
> +#ifndef PRIuMAX
> +# define PRIuMAX "llu"
> +#endif

This will cause problems in the native MS-Windows builds, where printf
in the system C runtime doesn't support %lld and %llu.  (Unless I'm
missing something: I didn't try to build Make with this patch.
Apologies if this is taken care of somewhere and I didn't see it.)

Thanks.



Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-21 Thread Eli Zaretskii
> From: 
> Cc: 
> Date: Wed, 21 Sep 2022 21:01:58 -0400
> 
> On September 21, 2022 8:58 PM, Paul Eggert wrote:
> >On 9/20/22 18:48, rsbec...@nexbridge.com wrote:
> >> I am sorry to say that the %j prefix is not safe or portable. There
> >> are major production platforms where this is not supported. I work on
> >> one of them.
> >
> >Which platform and version? I'd like to document this in Gnulib. Some other 
> >GNU
> >programs are using %j now so it might make sense for you to file an 
> >enhancement
> >request at some point, assuming %j is not supported even in the latest 
> >version of
> >the platform.
> >
> >Anyway, thanks, revised GNU Make patch attached; it does not assume %j.
> 
> I'm going to back away from complaining on this. The platform I thought did 
> not support it was HPE NonStop but it appears that I was looking at an old OS 
> version. The current set of supported operating system releases support %j.

MinGW on native MS-Windows definitely doesn't, unless we force linking
against the replacement stdio.  And I think we still support MSVC?

So I think it's best to stay away of %j.



RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-21 Thread rsbecker
On September 21, 2022 8:58 PM, Paul Eggert wrote:
>On 9/20/22 18:48, rsbec...@nexbridge.com wrote:
>> I am sorry to say that the %j prefix is not safe or portable. There
>> are major production platforms where this is not supported. I work on
>> one of them.
>
>Which platform and version? I'd like to document this in Gnulib. Some other GNU
>programs are using %j now so it might make sense for you to file an enhancement
>request at some point, assuming %j is not supported even in the latest version 
>of
>the platform.
>
>Anyway, thanks, revised GNU Make patch attached; it does not assume %j.

I'm going to back away from complaining on this. The platform I thought did not 
support it was HPE NonStop but it appears that I was looking at an old OS 
version. The current set of supported operating system releases support %j.

Sincerely,
Randall




Re: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-21 Thread Paul Eggert

On 9/20/22 18:48, rsbec...@nexbridge.com wrote:

I am sorry to say that the %j prefix is not safe or portable. There are
major production platforms where this is not supported. I work on one of
them.


Which platform and version? I'd like to document this in Gnulib. Some 
other GNU programs are using %j now so it might make sense for you to 
file an enhancement request at some point, assuming %j is not supported 
even in the latest version of the platform.


Anyway, thanks, revised GNU Make patch attached; it does not assume %j.

From 007094a8f912a405746e3496684fba75d8b89913 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 20 Sep 2022 14:18:00 -0700
Subject: [PATCH] Port to 32-bit long + 64-bit time_t

Don't assume that time_t fits in long, as some hosts (e.g.,
glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t.
This fix uses C99 sprintf/scanf %jd and %ju, which is
safe to assume nowadays.
* bootstrap.conf (gnulib_modules): Add largefile, to support
files with timestamps after Y2038 on hosts with 32-bit long.
* configure.ac: Do not call AC_SYS_LARGEFILE,
as the largefile module does that for us.
* src/ar.c: Include intprops.h, for TYPE_MAXIMUM,
as INTEGER_TYPE_MAXIMUM does not work on time_t
without issuing a bunch of warnings.
(ar_member_date): Check that result is in time_t range.
* src/ar.c (ar_member_date, ar_glob_match):
* src/arscan.c (VMS_function, VMS_function_ret, ar_scan)
(parse_int, ar_scan, ar_member_pos, ar_member_touch)
(describe_member):
* src/file.c (file_timestamp_sprintf):
Use intmax_t/uintmax_t instead of long/unsigned long for values
that might be time_t.
* src/makeint.h (PRIdMAX, PRIuMAX): Define if not already defined.
These days it should be safe to assume long long and %lld even on
pre-C99 platforms, as GNU Make is already using both features.
---
 bootstrap.conf |  1 +
 configure.ac   |  5 -
 src/ar.c   | 15 ---
 src/arscan.c   | 44 
 src/file.c | 13 -
 src/makeint.h  | 13 ++---
 6 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index b1ee947d..1dc096db 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -60,5 +60,6 @@ fdl
 findprog-in
 getloadavg
 host-cpu-c-abi
+largefile
 make-glob
 make-macros"
diff --git a/configure.ac b/configure.ac
index e08e75ad..11e9ed12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,11 +57,6 @@ AC_C_BIGENDIAN
 AM_GNU_GETTEXT_VERSION([0.19.4])
 AM_GNU_GETTEXT([external])
 
-# This test must come as early as possible after the compiler configuration
-# tests, because the choice of the file model can (in principle) affect
-# whether functions and headers are available, whether they work, etc.
-AC_SYS_LARGEFILE
-
 # Checks for libraries.
 AC_SEARCH_LIBS([strerror],[cposix])
 AC_SEARCH_LIBS([getpwnam], [sun])
diff --git a/src/ar.c b/src/ar.c
index 7a26662c..48ef5e44 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -22,6 +22,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "filedef.h"
 #include "dep.h"
 #include 
+#include 
 
 /* Return nonzero if NAME is an archive-member reference, zero if not.  An
archive-member reference is a name like 'lib(member)' where member is a
@@ -69,10 +70,10 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
 /* This function is called by 'ar_scan' to find which member to look at.  */
 
 /* ARGSUSED */
-static long int
+static intmax_t
 ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
   long int hdrpos UNUSED, long int datapos UNUSED,
-  long int size UNUSED, long int date,
+  long int size UNUSED, intmax_t date,
   int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
   const void *name)
 {
@@ -86,7 +87,7 @@ ar_member_date (const char *name)
 {
   char *arname;
   char *memname;
-  long int val;
+  intmax_t val;
 
   ar_parse_name (name, , );
 
@@ -111,7 +112,7 @@ ar_member_date (const char *name)
 
   free (arname);
 
-  return (val <= 0 ? (time_t) -1 : (time_t) val);
+  return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
 }
 
 /* Set the archive-member NAME's modtime to now.  */
@@ -194,10 +195,10 @@ struct ar_glob_state
 /* This function is called by 'ar_scan' to match one archive
element against the pattern in STATE.  */
 
-static long int
+static intmax_t
 ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
-   long int size UNUSED, long int date UNUSED, int uid UNUSED,
+   long int size UNUSED, intmax_t date UNUSED, int uid UNUSED,
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
 {
   struct ar_glob_state *state = (struct ar_glob_state *)arg;
@@ -218,7 +219,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated 

RE: [PATCH] Port to 32-bit long + 64-bit time_t

2022-09-20 Thread rsbecker
On September 20, 2022 5:22 PM Paul Eggert wrote:
>Don't assume that time_t fits in long, as some hosts (e.g., glibc x86 -
>D_TIME_BITS=64) have 32-bit long and 64-bit time_t.
>This fix uses C99 sprintf/scanf %jd and %ju, which is safe to assume
nowadays.

I am sorry to say that the %j prefix is not safe or portable. There are
major production platforms where this is not supported. I work on one of
them. %l and %ll are supportable and can be selected with a configuration
knob that would be safer.
-Randall




[PATCH] Port to 32-bit long + 64-bit time_t

2022-09-20 Thread Paul Eggert
Don't assume that time_t fits in long, as some hosts (e.g.,
glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t.
This fix uses C99 sprintf/scanf %jd and %ju, which is
safe to assume nowadays.
* bootstrap.conf (gnulib_modules): Add largefile, to support
files with timestamps after Y2038 on hosts with 32-bit long.
* configure.ac: Do not call AC_SYS_LARGEFILE,
as the largefile module does that for us.
* src/ar.c: Include intprops.h, for TYPE_MAXIMUM,
as INTEGER_TYPE_MAXIMUM does not work on time_t
without issuing a bunch of warnings.
(ar_member_date): Check that result is in time_t range.
* src/ar.c (ar_member_date, ar_glob_match):
* src/arscan.c (VMS_function, VMS_function_ret, ar_scan)
(parse_int, ar_scan, ar_member_pos, ar_member_touch)
(describe_member):
* src/file.c (file_timestamp_sprintf):
Use intmax_t/uintmax_t instead of long/unsigned long for values
that might be time_t.
---
 bootstrap.conf |  1 +
 configure.ac   |  5 -
 src/ar.c   | 15 ---
 src/arscan.c   | 44 
 src/file.c | 13 -
 src/makeint.h  |  7 ---
 6 files changed, 45 insertions(+), 40 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index b1ee947d..1dc096db 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -60,5 +60,6 @@ fdl
 findprog-in
 getloadavg
 host-cpu-c-abi
+largefile
 make-glob
 make-macros"
diff --git a/configure.ac b/configure.ac
index e08e75ad..11e9ed12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,11 +57,6 @@ AC_C_BIGENDIAN
 AM_GNU_GETTEXT_VERSION([0.19.4])
 AM_GNU_GETTEXT([external])
 
-# This test must come as early as possible after the compiler configuration
-# tests, because the choice of the file model can (in principle) affect
-# whether functions and headers are available, whether they work, etc.
-AC_SYS_LARGEFILE
-
 # Checks for libraries.
 AC_SEARCH_LIBS([strerror],[cposix])
 AC_SEARCH_LIBS([getpwnam], [sun])
diff --git a/src/ar.c b/src/ar.c
index 7a26662c..48ef5e44 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -22,6 +22,7 @@ this program.  If not, see .  */
 #include "filedef.h"
 #include "dep.h"
 #include 
+#include 
 
 /* Return nonzero if NAME is an archive-member reference, zero if not.  An
archive-member reference is a name like 'lib(member)' where member is a
@@ -69,10 +70,10 @@ ar_parse_name (const char *name, char **arname_p, char 
**memname_p)
 /* This function is called by 'ar_scan' to find which member to look at.  */
 
 /* ARGSUSED */
-static long int
+static intmax_t
 ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
   long int hdrpos UNUSED, long int datapos UNUSED,
-  long int size UNUSED, long int date,
+  long int size UNUSED, intmax_t date,
   int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
   const void *name)
 {
@@ -86,7 +87,7 @@ ar_member_date (const char *name)
 {
   char *arname;
   char *memname;
-  long int val;
+  intmax_t val;
 
   ar_parse_name (name, , );
 
@@ -111,7 +112,7 @@ ar_member_date (const char *name)
 
   free (arname);
 
-  return (val <= 0 ? (time_t) -1 : (time_t) val);
+  return 0 < val && val <= TYPE_MAXIMUM (time_t) ? val : -1;
 }
 
 /* Set the archive-member NAME's modtime to now.  */
@@ -194,10 +195,10 @@ struct ar_glob_state
 /* This function is called by 'ar_scan' to match one archive
element against the pattern in STATE.  */
 
-static long int
+static intmax_t
 ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
-   long int size UNUSED, long int date UNUSED, int uid UNUSED,
+   long int size UNUSED, intmax_t date UNUSED, int uid UNUSED,
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
 {
   struct ar_glob_state *state = (struct ar_glob_state *)arg;
@@ -218,7 +219,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int 
truncated UNUSED,
   ++state->n;
 }
 
-  return 0L;
+  return 0;
 }
 
 /* Return nonzero if PATTERN contains any metacharacters.
diff --git a/src/arscan.c b/src/arscan.c
index f22d21aa..78c6c06f 100644
--- a/src/arscan.c
+++ b/src/arscan.c
@@ -75,9 +75,9 @@ static void *VMS_lib_idx;
 
 static const void *VMS_saved_arg;
 
-static long int (*VMS_function) ();
+static intmax_t (*VMS_function) ();
 
-static long int VMS_function_ret;
+static intmax_t VMS_function_ret;
 
 
 /* This is a callback procedure for lib$get_index */
@@ -203,7 +203,7 @@ VMS_get_member_info(struct dsc$descriptor_s *module, 
unsigned long *rfa)
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully.  */
 
-long int
+intmax_t
 ar_scan (const char *archive, ar_member_func_t function, const void *varg)
 {
   char *vms_archive;
@@ -379,13 +379,13 @@ struct ar_hdr
 #include "output.h"
 
 
-static unsigned long int
+static uintmax_t
 parse_int (const char *ptr,