Skip to content

Commit

Permalink
AC_SYS_LARGEFILE: Don’t enlarge time_t by default
Browse files Browse the repository at this point in the history
Having AC_SYS_LARGEFILE enlarge time_t means that any program that has
already requested large file support will be abruptly migrated to
64-bit time_t (on 32-bit systems) as soon as its configure script is
regenerated with a sufficiently new Autoconf.  We’ve received reports
of several widely used programs and libraries that are not prepared
for this migration, with breakage ranging from annoying (garbage
timestamps in messages) through serious (binary compatibility break
in security-critical shared library) to catastrophic (on-disk data
corruption).

Partially revert f665725: in the
absence of AC_SYS_YEAR2038, AC_SYS_LARGEFILE will now only add an
--enable-year2038 command line option to configure.  If this option is
used, time_t will be enlarged, allowing people to experiment with the
migration without needing to *edit* the configure script in question,
only regenerate it.

In the process, AC_SYS_LARGEFILE and AC_SYS_YEAR2038 were drastically
overhauled for modularity; it should now be much easier to add support
for platforms that offer large off_t / time_t but not with the standard
feature selection macros.  Also, new macros AC_SYS_LARGEFILE_REQUIRED and
AC_SYS_YEAR2038_REQUIRED can be used by programs for which large off_t /
time_t are essential.

The implementation is a little messy because it needs to gracefully
handle the case where AC_SYS_LARGEFILE and AC_SYS_LARGEFILE_REQUIRED
are both used in the same configure script — or, probably more common,
AC_SYS_LARGEFILE (which invokes _AC_SYS_YEAR2038_OPT_IN) followed by
AC_SYS_YEAR2038 — but if macro B is invoked after macro A, there’s no
way for B to change *what macro A expanded to*.  The best kludge I
managed to find is to AC_CONFIG_COMMANDS_PRE as a m4-level hook that
sets shell variables in an early diversion.

* lib/autoconf/functions.m4 (AC_FUNC_FSEEKO): Rewrite to avoid dependency
  on internal subroutines of AC_SYS_LARGEFILE.

* lib/autoconf/specific.m4 (_AC_SYS_YEAR2038_TEST_INCLUDES): Renamed to
  _AC_SYS_YEAR2038_TEST_CODE.
  (_AC_SYS_YEAR2038): Refactor into subroutines: _AC_SYS_YEAR2038_OPTIONS,
  _AC_SYS_YEAR2038_PROBE, _AC_SYS_YEAR2038_ENABLE.
  (AC_SYS_YEAR2038): Update for refactoring.
  (_AC_SYS_YEAR2038_OPT_IN): New sorta-top-level macro, for use by
  AC_SYS_LARGEFILE, that probes for large time_t only if the
  --enable-year2038 option is given.
  (AC_SYS_YEAR2038_REQUIRED): New top-level macro that insists on
  support for large time_t.

  (_AC_SYS_LARGEFILE_TEST_INCLUDES): Renamed to _AC_SYS_LARGEFILE_TEST_CODE.
  (_AC_SYS_LARGEFILE_MACRO_VALUE, AC_SYS_LARGEFILE): Refactor along same
  lines as above: _AC_SYS_LARGEFILE_OPTIONS, _AC_SYS_LARGEFILE_PROBE,
  _AC_SYS_LARGEFILE_ENABLE.  Invoke _AC_SYS_YEAR2038_OPT_IN at end of
  _AC_SYS_LARGEFILE_PROBE.  MinGW-specific logic moved to YEAR2038
  macros as it has nothing to do with large file support.
  (AC_SYS_LARGEFILE_REQUIRED): New top-level macro that insists on
  support for large off_t.

* tests/local.at (_AT_CHECK_ENV): Also allow changes in CPPFLAGS,
  enableval, enable_*, withval, with_*.

* doc/autoconf.texi, NEWS: Update documentation to match above changes.
  Fix typo in definition of @dvarv.
  • Loading branch information
zackw authored and eggert committed Dec 25, 2022
1 parent bb7c8cb commit cf09f48
Show file tree
Hide file tree
Showing 5 changed files with 463 additions and 244 deletions.
34 changes: 31 additions & 3 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,43 @@ GNU Autoconf NEWS - User visible changes.
that you will get a confusing error message if you run autoconf on
a configure.ac that neglects to use AC_INIT or AC_OUTPUT.

*** AC_SYS_LARGEFILE now arranges for 64-bit time_t if possible.

*** m4sh diversions like BINSH have been renumbered.
This matters only for uses that, contrary to the documentation
and despite warnings, use m4_divert with numbered diversions.

** New features

*** New macro AC_SYS_YEAR2038 for 64-bit time_t.
*** New macros AC_SYS_YEAR2038 and AC_SYS_YEAR2038_REQUIRED.
These macros attempt to enlarge time_t to 64 bits, on systems where
it has historically been only 32 bits wide, and therefore (assuming
the usual Unix epoch) cannot represent dates after mid-January of
2038 (hence the names). The difference between the two is that
AC_SYS_YEAR2038_REQUIRED unconditionally causes 'configure' to error
out if 64-bit time_t is not available.

AC_SYS_YEAR2038 will also error out if the host system shows signs of
supporting dates after Jan 2038 (e.g. in file timestamps) but it can’t
figure out how to get a wider time_t; this failure can be overridden
with the --disable-year2038 option.

Library authors should be cautious about adding these macros to
their configure scripts; they can break binary backward compatibility.

*** New macro AC_SYS_LARGEFILE_REQUIRED.
This macro is the same as the existing AC_SYS_LARGEFILE except that
it will cause 'configure' to error out if 64-bit off_t is not available,
and it does not provide a --disable-largefile option.

*** AC_SYS_LARGEFILE now optionally arranges to enlarge time_t.
As an experimental measure to make it easier to rebuild old programs
with support for dates after Jan 2038, if you regenerate any configure
script that uses AC_SYS_LARGEFILE (but not AC_SYS_YEAR2038) using
Autoconf 2.72, it will gain an --enable-year2038 option. When the
program is configured with this option, time_t will be enlarged if
possible, as if AC_SYS_YEAR2038 had been used.

Using this option in a library build also potentially breaks binary
backward compatibility.

*** AC_USE_SYSTEM_EXTENSIONS now enables C23 Annex F extensions
by defining __STDC_WANT_IEC_60559_EXT__.
Expand Down
165 changes: 112 additions & 53 deletions doc/autoconf.texi
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
@c Same as @dvar{ARG, DEFAULT-VAR}, but with @var instead of @samp
@c around DEFAULT-VAR.
@macro dvarv{varname, default}
@r{[}@var{\varname\} = @var{\default\}@r{]}@c
@r{[}@var{\varname\} = @var{\default\}@r{]}
@end macro

@c Handling the indexes with Texinfo yields several different problems.
Expand Down Expand Up @@ -5229,6 +5229,7 @@ test, you also need to set the @code{ac_cv_func_fork} and
@code{ac_cv_func_vfork} variables.
@end defmac

@anchor{AC_FUNC_FSEEKO}
@defmac AC_FUNC_FSEEKO
@acindex{FUNC_FSEEKO}
@cvindex _LARGEFILE_SOURCE
Expand All @@ -5238,12 +5239,13 @@ test, you also need to set the @code{ac_cv_func_fork} and
@c @fuindex ftello
@prindex @code{ftello}
@c @caindex sys_largefile_source
If the @code{fseeko} function is available, define @code{HAVE_FSEEKO}.
Define @code{_LARGEFILE_SOURCE} if necessary to make the prototype
visible on some systems (e.g., glibc 2.2). Otherwise linkage problems
may occur when compiling with @code{AC_SYS_LARGEFILE} on
largefile-sensitive systems where @code{off_t} does not default to a
64bit entity. All systems with @code{fseeko} also supply @code{ftello}.
If the @code{fseeko} and @code{ftello} functions are available, define
@code{HAVE_FSEEKO}. Define @code{_LARGEFILE_SOURCE} if necessary to
make the prototype visible.

Configure scripts that use @code{AC_FUNC_FSEEKO} should normally also
use @code{AC_SYS_LARGEFILE} to ensure that @code{off_t} can represent
all supported file sizes. @xref{AC_SYS_LARGEFILE}.

The Gnulib module @code{fseeko} invokes @code{AC_FUNC_FSEEKO}
and also contains workarounds for other portability problems of
Expand Down Expand Up @@ -8792,45 +8794,76 @@ the shell variable @code{interpval}; it is set to @samp{yes}
if the system supports @samp{#!}, @samp{no} if not.
@end defmac

@anchor{AC_SYS_LARGEFILE}
@defmac AC_SYS_LARGEFILE
@acindex{SYS_LARGEFILE}
@cvindex _FILE_OFFSET_BITS
@cvindex _LARGE_FILES
@cvindex _TIME_BITS
@ovindex CC
@cindex Large file support
@cindex LFS
Arrange for 64-bit file offsets, known as
@uref{http://@/www.unix.org/@/version2/@/whatsnew/@/lfs20mar.html,
large-file support}, along with other large attributes.
On some hosts, one must use special compiler options
to build programs that can access files with large sizes inode
numbers, timestamps, or other attributes. Append any such
options to the output variable @code{CC}. Define
@code{_FILE_OFFSET_BITS}, @code{_LARGE_FILES}, and @code{_TIME_BITS}
if necessary.
If the default @code{off_t} type is a 32-bit integer, and therefore
cannot be used to work with files larger than 4 gigabytes, arrange to
make a larger @code{off_t} available, if the system supports this.
Several other types related to the sizes of files and file systems will
also be enlarged: @code{ino_t}, @code{blkcnt_t}, @code{fsblkcnt_t},
@code{fsfilcnt_t}, and possibly @code{dev_t}.

If a large @code{off_t} is available (whether or not any arrangements
were necessary), the shell variable @code{ac_have_largefile} will be set
to @samp{yes}; if not, it will be set to @samp{no}.

Preprocessor macros will be defined if necessary to make a larger
@code{off_t} available. (For example, on many systems the macro
@code{_FILE_OFFSET_BITS} will be defined.) Some of these macros only
work if they are defined before the first system header is included;
therefore, when using this macro in concert with
@code{AC_CONFIG_HEADERS}, make sure that @file{config.h} is included
before any system headers.

On a few older systems, the output variable @code{CC} will also be
changed to add special compiler options that are needed to enable large
@code{off_t}.

Large-file support can be disabled by configuring with the
@option{--disable-largefile} option. If you disable large-file
support, your program may have trouble accessing arbitrary files, such
as files that might be found in an adversary's directory.

If you use this macro, check that your program works even when the types
@code{blkcnt_t}, @code{dev_t}, @code{ino_t}, @code{off_t}, and @code{time_t}
are wider than @code{long int}, since this is common when
large-file support is enabled. For example, it is not correct to print
an arbitrary @code{off_t} value @code{X} with @code{printf ("%ld",
(long int) X)}. Also, when using this macro in concert with
@code{AC_CONFIG_HEADERS}, be sure that @file{config.h} is included
before any system header.
@option{--disable-largefile} option. Note that this has no effect on
systems where @code{off_t} is 64 bits or larger by default. Disabling
large-file support can have surprising effects, such as causing
functions like @code{readdir} and @code{stat} to fail on small files
(because their @emph{inode numbers} are unrepresentable).

The LFS introduced the @code{fseeko} and @code{ftello} functions to
replace their C counterparts @code{fseek} and @code{ftell} that do not
use @code{off_t}. Take care to use @code{AC_FUNC_FSEEKO} to make their
prototypes available when using them and large-file support is
enabled.
Regardless of whether you use this macro, portable programs should not
assume that any of the types listed above fit into a @code{long int}.
For example, it is not correct to print an arbitrary @code{off_t} value
@code{X} with @code{printf ("%ld", (long int) X)}.

Note that the standard C library functions @code{fseek} and @code{ftell}
do not use @code{off_t}. If you need to use either of these functions,
you should use @code{AC_FUNC_FSEEKO} as well as @code{AC_SYS_LARGEFILE},
and then use their Posix replacements @code{fseeko} and @code{ftello},
which @emph{do} use @code{off_t}, when available. @xref{AC_FUNC_FSEEKO}.

As of Autoconf 2.72, @code{AC_SYS_LARGEFILE} also @emph{optionally}
arranges to enlarge @code{time_t}. This is to make it easier to build
programs that support timestamps after 2038; many configure scripts will
not need to be modified, only regenerated with newer Autoconf. When
@code{AC_SYS_LARGEFILE} is used, and @code{AC_SYS_YEAR2038} is
@emph{not} used, @code{time_t} will normally be left at the system's
default size, but you can request it be enlarged by configuring with the
@option{--enable-year2038} option. (When @code{AC_SYS_YEAR2038} is also
used, @code{time_t} is enlarged if possible. @xref{AC_SYS_YEAR2038}.)
@end defmac

@defmac AC_SYS_LARGEFILE_REQUIRED
@acindex{SYS_LARGEFILE_REQUIRED}
This macro has the same effect as @code{AC_SYS_LARGEFILE},
but also declares that the program being configured
@emph{requires} support for large files.
If a large @code{off_t} is unavailable,
@command{configure} will error out.
The @option{--disable-largefile} option will not be available.
@end defmac


@anchor{AC_SYS_LONG_FILE_NAMES}
@defmac AC_SYS_LONG_FILE_NAMES
@acindex{SYS_LONG_FILE_NAMES}
Expand All @@ -8849,32 +8882,58 @@ system. If so, set the shell variable @code{ac_cv_sys_posix_termios} to
@samp{yes}. If not, set the variable to @samp{no}.
@end defmac

@anchor{AC_SYS_YEAR2038}
@defmac AC_SYS_YEAR2038
@acindex{SYS_YEAR2038}
@cvindex _TIME_BITS
@ovindex CC
@cindex Year 2038
If the default @code{time_t} type is a signed 32-bit integer that stops
working in the year 2038, then arrange to use a wider @code{time_t} if
possible and report a fatal error otherwise. Define @code{_TIME_BITS}
if necessary.

Wider-time support can be disabled by configuring with the
@option{--disable-year2038} option.
If the default @code{time_t} type is a signed 32-bit integer,
and therefore (assuming the usual Unix epoch) cannot represent
timestamps after mid-January of 2038, arrange to make a larger
@code{time_t} available, if the system supports this.

If a large @code{time_t} is available (whether or not any arrangements
were necessary), the shell variable @code{ac_have_year2038} will be set
to @samp{yes}; if not, it will be set to @samp{no}.

Preprocessor macros will be defined if necessary to make a larger
@code{time_t} available. (For example, on some systems the macro
@code{_TIME_BITS} will be defined.) Some of these macros only work if
they are defined before the first system header is included; therefore,
when using this macro in concert with @code{AC_CONFIG_HEADERS}, make
sure that @file{config.h} is included before any system headers.

Support for timestamps after 2038 can be disabled by configuring with
the @option{--disable-year2038} option. Note that this has no effect on
systems where @code{time_t} is 64 bits or larger by default.
If this option is @emph{not} given, and @command{configure} fails to
find a way to enable a large @code{time_t}, but inspection of the
system suggests that this feature is available @emph{somehow}, it will
error out.

Regardless of whether you use this macro, portable programs should not
assume that @code{time_t} fits into @code{long int}. For example, it is
not correct to print an arbitrary @code{time_t} value @code{X} with
@code{printf ("%ld", (long int) X)}. Also, when using this macro in
concert with @code{AC_CONFIG_HEADERS}, be sure that @file{config.h} is
included before any system header.

@code{AC_SYS_LARGFILE} also widens @code{time_t} if possible,
as this is needed for programs that access files with large timestamps,
However, @code{AC_SYS_LARGEFILE} merely warns if @code{time_t} is too
narrow and cannot be widened, rather than reporting a fatal error as
@code{AC_SYS_YEAR2038} does. This is for portability to older
platforms that will become obsolete in the year 2038.
@code{printf ("%ld", (long int) X)}.

@strong{Caution:} If you are developing a shared library, and
@code{time_t} appears anywhere in your library's public interface, use
of this macro may break binary compatibility with older executables.
@end defmac

@defmac AC_SYS_YEAR2038_REQUIRED
@acindex{SYS_YEAR2038_REQUIRED}
This macro has the same effect as @code{AC_SYS_YEAR2038},
but also declares that the program being configured
@emph{requires} support for timestamps after mid-January of 2038.
If a large @code{time_t} is unavailable,
@command{configure} will @emph{unconditionally} error out
(unlike the behavior of @code{AC_SYS_YEAR2038}).
The @option{--disable-year2038} option will not be available.

@strong{Caution:} If you are developing a shared library, and
@code{time_t} appears anywhere in your library's public interface, use
of this macro may break binary compatibility with older executables.
@end defmac

@node C and Posix Variants
Expand Down
66 changes: 44 additions & 22 deletions lib/autoconf/functions.m4
Original file line number Diff line number Diff line change
Expand Up @@ -641,35 +641,57 @@ AU_ALIAS([AM_FUNC_FNMATCH], [AC_FUNC_FNMATCH])
AU_ALIAS([fp_FUNC_FNMATCH], [AC_FUNC_FNMATCH])
# _AC_FUNC_FSEEKO_TEST_PROGRAM
# ----------------------------
# Test code used by AC_FUNC_FSEEKO.
m4_define([_AC_FUNC_FSEEKO_TEST_PROGRAM],
[AC_LANG_PROGRAM([[
#if defined __hpux && !defined _LARGEFILE_SOURCE
# include <limits.h>
# if LONG_MAX >> 31 == 0
# error "32-bit HP-UX 11/ia64 needs _LARGEFILE_SOURCE for fseeko in C++"
# endif
#endif
#include <sys/types.h> /* for off_t */
#include <stdio.h>
]], [[
int (*fp1) (FILE *, off_t, int) = fseeko;
off_t (*fp2) (FILE *) = ftello;
return fseeko (stdin, 0, 0)
&& fp1 (stdin, 0, 0)
&& ftello (stdin) >= 0
&& fp2 (stdin) >= 0;
]])])
# AC_FUNC_FSEEKO
# --------------
# Check for correctly prototyped declarations of fseeko and ftello;
# define HAVE_FSEEKO if they are available. If it is necessary to
# define _LARGEFILE_SOURCE=1 to make these declarations available,
# do that (this is needed on 32-bit HP/UX). We used to try defining
# _XOPEN_SOURCE=500 too, to work around a bug in glibc 2.1.3, but that
# breaks too many other things. If you want fseeko and ftello with
# glibc, upgrade to a fixed glibc.
AN_FUNCTION([ftello], [AC_FUNC_FSEEKO])
AN_FUNCTION([fseeko], [AC_FUNC_FSEEKO])
AC_DEFUN([AC_FUNC_FSEEKO],
[_AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
[ac_cv_sys_largefile_source],
[Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2).],
[[#if defined __hpux && !defined _LARGEFILE_SOURCE
#include <limits.h>
#if LONG_MAX >> 31 == 0
#error "32-bit HP-UX 11/ia64 needs _LARGEFILE_SOURCE for fseeko in C++"
#endif
#endif
#include <sys/types.h> /* for off_t */
#include <stdio.h>]],
[[int (*fp) (FILE *, off_t, int) = fseeko;
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);]])
# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
# in glibc 2.1.3, but that breaks too many other things.
# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
if test $ac_cv_sys_largefile_source != unknown; then
AC_DEFINE(HAVE_FSEEKO, 1,
[Define to 1 if fseeko (and presumably ftello) exists and is declared.])
fi
[AC_CACHE_CHECK([for declarations of fseeko and ftello],
[ac_cv_func_fseeko_ftello],
[AC_COMPILE_IFELSE([_AC_FUNC_FSEEKO_TEST_PROGRAM],
[ac_cv_func_fseeko_ftello=yes],
[ac_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE=1"
AC_COMPILE_IFELSE([_AC_FUNC_FSEEKO_TEST_PROGRAM],
[ac_cv_func_fseeko_ftello="need _LARGEFILE_SOURCE"],
[ac_cv_func_fseeko_ftello=no])])])
AS_IF([test "$ac_cv_func_fseeko_ftello" != no],
[AC_DEFINE([HAVE_FSEEKO], [1],
[Define to 1 if fseeko (and ftello) are declared in stdio.h.])])
AS_IF([test "$ac_cv_func_fseeko_ftello" = "need _LARGEFILE_SOURCE"],
[AC_DEFINE([_LARGEFILE_SOURCE], [1],
[Define to 1 if necessary to make fseeko visible.])])
])# AC_FUNC_FSEEKO
# AC_FUNC_GETGROUPS
# -----------------
# Try to find 'getgroups', and check that it works.
Expand Down
Loading

0 comments on commit cf09f48

Please sign in to comment.