Mercurial > hg > xemacs-beta
changeset 5727:86d33ddc7fd6
Avoid EOVERFLOW from stat() calls due to overflowing inode numbers.
The btrfs filesystem now uses 64-bit inode numbers even on 32-bit systems.
This can lead to spurious stat() failures, where EOVERFLOW is returned because
the inode number does not fit into the 32-bit stat structure, even when the
caller is not interested in the inode number. This patch builds with
_FILE_OFFSET_BITS == 64 when possible, and deals with integers that may be
too large to fit into a Lisp fixnum. For more information, see xemacs-patches
message <CAHCOHQk_mPM6WgFChBsGafqhuazep6VED7swFoqfFXOV1r8org@mail.gmail.com>.
author | Jerry James <james@xemacs.org> |
---|---|
date | Wed, 06 Mar 2013 08:32:17 -0700 |
parents | 179f4a9201b5 |
children | 0e2f2837c2bd |
files | ChangeLog configure configure.ac lib-src/ChangeLog lib-src/insert-data-in-exec.c src/ChangeLog src/config.h.in src/dired.c src/dumper.c |
diffstat | 9 files changed, 384 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Mar 05 08:55:56 2013 +0100 +++ b/ChangeLog Wed Mar 06 08:32:17 2013 -0700 @@ -1,3 +1,7 @@ +2013-03-04 Jerry James <james@xemacs.org> + + * configure.ac: Check for large file support. + 2013-03-04 Jerry James <james@xemacs.org> * configure.ac: Complete removal of need_modules_common, forgotten
--- a/configure Tue Mar 05 08:55:56 2013 +0100 +++ b/configure Wed Mar 06 08:32:17 2013 -0700 @@ -1049,6 +1049,7 @@ with_purify enable_valgrind with_valgrind +enable_largefile with_x ' ac_precious_vars='build_alias @@ -2030,6 +2031,12 @@ --with-purify Support memory debugging using Purify. --with-valgrind Support memory debugging using Valgrind. +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) @@ -11709,6 +11716,308 @@ fi +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 +$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } +if ${ac_cv_sys_largefile_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> /* for off_t */ + #include <stdio.h> +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=no; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGEFILE_SOURCE 1 +#include <sys/types.h> /* for off_t */ + #include <stdio.h> +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=1; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_cv_sys_largefile_source=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 +$as_echo "$ac_cv_sys_largefile_source" >&6; } +case $ac_cv_sys_largefile_source in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source +_ACEOF +;; +esac +rm -rf conftest* + +# 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 + +$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 +$as_echo_n "checking size of off_t... " >&6; } +if ${ac_cv_sizeof_off_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_off_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (off_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_off_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 +$as_echo "$ac_cv_sizeof_off_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_OFF_T $ac_cv_sizeof_off_t +_ACEOF + + + ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin" if test "x$ac_cv_func_sin" = xyes; then :
--- a/configure.ac Tue Mar 05 08:55:56 2013 +0100 +++ b/configure.ac Wed Mar 06 08:32:17 2013 -0700 @@ -2721,6 +2721,11 @@ dnl check for long file names AC_SYS_LONG_FILE_NAMES +dnl check for large file support +AC_SYS_LARGEFILE +AC_FUNC_FSEEKO +AC_CHECK_SIZEOF(off_t) + dnl -lm is required for floating point support, among other things AC_CHECK_FUNC(sin, ,AC_CHECK_LIB(m, sin))
--- a/lib-src/ChangeLog Tue Mar 05 08:55:56 2013 +0100 +++ b/lib-src/ChangeLog Wed Mar 06 08:32:17 2013 -0700 @@ -1,3 +1,9 @@ +2013-03-04 Jerry James <james@xemacs.org> + + * insert-data-in-exec.c (main): Use OFF_T, FSEEK, and FTELL macros, + and adjust variable types and printf specifiers for large file + support on supporting systems. + 2013-01-04 Stephen J. Turnbull <stephen@xemacs.org> * XEmacs 21.5.33 "horseradish" is released.
--- a/lib-src/insert-data-in-exec.c Tue Mar 05 08:55:56 2013 +0100 +++ b/lib-src/insert-data-in-exec.c Wed Mar 06 08:32:17 2013 -0700 @@ -32,6 +32,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <config.h> static const unsigned char key[] = { 255, @@ -55,8 +56,9 @@ { FILE *te, *xe, *dump; unsigned char *xed, *p; - long size, size_dump, size1, i; - long max_size, offset; + size_t size, size_dump, size1, i; + size_t max_size, offset; + OFF_T off; char msg[65536]; @@ -73,24 +75,25 @@ exit(1); } - if(fseek(dump, 0, SEEK_END)) { + if(FSEEK(dump, 0, SEEK_END)) { perror("fseek end dump"); exit(1); } - size = ftell(dump); - if(size == -1) { + off = FTELL(dump); + if(off == -1) { perror("ftell dump"); exit(1); } + size = (size_t)off; - printf("%ld\n", size); + printf("%zu\n", size); exit(0); } - max_size = strtol(argv[4], 0, 10); - offset = strtol(argv[5], 0, 10); + max_size = strtoul(argv[4], 0, 10); + offset = strtoul(argv[5], 0, 10); sprintf(msg, "Opening %s failed", argv[1]); te = fopen(argv[1], "rb"); @@ -99,18 +102,19 @@ exit(1); } - if(fseek(te, 0, SEEK_END)) { + if(FSEEK(te, 0, SEEK_END)) { perror("fseek end"); exit(1); } - size = ftell(te); - if(size == -1) { + off = FTELL(te); + if(off == -1) { perror("ftell"); exit(1); } + size = (size_t)off; - if(fseek(te, 0, SEEK_SET)) { + if(FSEEK(te, 0, SEEK_SET)) { perror("fseek beginning"); exit(1); } @@ -127,7 +131,7 @@ perror("fread temacs"); exit(1); } - fprintf(stderr, "Fread returned %ld, expected %ld ?\n", size1, size); + fprintf(stderr, "Fread returned %zu, expected %zu ?\n", size1, size); exit(1); } @@ -137,7 +141,7 @@ } p = xed; - for(i=0; i<size-(long)sizeof(key); i++) { + for(i=0; i<size-sizeof(key); i++) { if(!memcmp(p, key, sizeof(key))) goto found; p++; @@ -147,7 +151,7 @@ exit(1); found: - fprintf(stderr, "dumped_data found at offset 0x%lx, patching.\n", i); + fprintf(stderr, "dumped_data found at offset 0x%zx, patching.\n", i); sprintf(msg, "Opening %s failed", argv[2]); dump = fopen(argv[2], "rb"); @@ -156,23 +160,24 @@ exit(1); } - if(fseek(dump, 0, SEEK_END)) { + if(FSEEK(dump, 0, SEEK_END)) { perror("fseek end dump"); exit(1); } - size_dump = ftell(dump); - if(size_dump == -1) { + off = FTELL(dump); + if(off == -1) { perror("ftell dump"); exit(1); } + size_dump = (size_t)off; if(size_dump > max_size) { - fprintf(stderr, "Dump file too big for available space (max=%ld, dump=%ld)\n", max_size, size_dump); + fprintf(stderr, "Dump file too big for available space (max=%zu, dump=%zu)\n", max_size, size_dump); exit(2); } - if(fseek(dump, 0, SEEK_SET)) { + if(FSEEK(dump, 0, SEEK_SET)) { perror("fseek beginning dump"); exit(1); } @@ -183,7 +188,7 @@ perror("fread dump"); exit(1); } - fprintf(stderr, "Fread dump returned %ld, expected %ld ?\n", size1, size_dump); + fprintf(stderr, "Fread dump returned %zu, expected %zu ?\n", size1, size_dump); exit(1); } @@ -199,7 +204,7 @@ xed[i+2] = size_dump >> 16; xed[i+3] = size_dump >> 24; - fprintf(stderr, "dumped_data found at offset 0x%lx, patching.\n", i); + fprintf(stderr, "dumped_data found at offset 0x%zx, patching.\n", i); sprintf(msg, "Opening %s failed", argv[3]); xe = fopen(argv[3], "wb"); @@ -214,7 +219,7 @@ perror("fwrite xemacs"); exit(1); } - fprintf(stderr, "Fwrite xemacs returned %ld, expected %ld ?\n", size1, size); + fprintf(stderr, "Fwrite xemacs returned %zu, expected %zu ?\n", size1, size); exit(1); }
--- a/src/ChangeLog Tue Mar 05 08:55:56 2013 +0100 +++ b/src/ChangeLog Wed Mar 06 08:32:17 2013 -0700 @@ -1,3 +1,13 @@ +2013-03-04 Jerry James <james@xemacs.org> + + * config.h.in: Add placeholders and definitions needed for large + file support. + * dired.c (Ffile_attributes): Some elements of the stat structure + can overflow a fixnum. Allow them to be bignums, if possible. + * dumper.c (pdump_align_stream): Use OFF_T, FTELL, and FSEEK macros + to get large file support. + (pdump): Ditto. + 2013-03-02 Jerry James <james@xemacs.org> * Makefile.in.in: If modules are built into the executable, assume
--- a/src/config.h.in Tue Mar 05 08:55:56 2013 +0100 +++ b/src/config.h.in Wed Mar 06 08:32:17 2013 -0700 @@ -757,6 +757,19 @@ #undef SIZEOF_LONG_LONG #undef SIZEOF_VOID_P #undef SIZEOF_DOUBLE +#undef SIZEOF_OFF_T + +/* Large file support */ +#undef AC_FUNC_FSEEKO +#ifdef AC_FUNC_FSEEKO +# define OFF_T off_t +# define FSEEK(stream, offset, whence) fseeko (stream, offset, whence) +# define FTELL(stream) ftello (stream) +#else +# define OFF_T long +# define FSEEK(stream, offset, whence) fseek (stream, offset, whence) +# define FTELL(stream) ftell (stream) +#endif /* some systems (Cygwin) typedef u?intptr_t in <sys/types.h> but the standard is <inttypes.h>
--- a/src/dired.c Tue Mar 05 08:55:56 2013 +0100 +++ b/src/dired.c Wed Mar 06 08:32:17 2013 -0700 @@ -927,17 +927,17 @@ RETURN_UNGCPRO (listn (12, mode, - make_fixnum (s.st_nlink), - make_fixnum (s.st_uid), - make_fixnum (s.st_gid), + make_integer (s.st_nlink), + make_integer (s.st_uid), + make_integer (s.st_gid), make_time (s.st_atime), make_time (s.st_mtime), make_time (s.st_ctime), size, modestring, gid, - make_fixnum (s.st_ino), - make_fixnum (s.st_dev))); + make_integer (s.st_ino), + make_integer (s.st_dev))); }
--- a/src/dumper.c Tue Mar 05 08:55:56 2013 +0100 +++ b/src/dumper.c Wed Mar 06 08:32:17 2013 -0700 @@ -203,10 +203,10 @@ inline static void pdump_align_stream (FILE *stream, Bytecount alignment) { - long offset = ftell (stream); - long adjustment = ALIGN_SIZE (offset, alignment) - offset; + OFF_T offset = FTELL (stream); + OFF_T adjustment = ALIGN_SIZE (offset, alignment) - offset; if (adjustment) - fseek (stream, adjustment, SEEK_CUR); + FSEEK (stream, adjustment, SEEK_CUR); } #define PDUMP_ALIGN_OUTPUT(type) pdump_align_stream (pdump_out, ALIGNOF (type)) @@ -2168,7 +2168,7 @@ elt->fcts->convert_free(elt->object, elt->data, elt->size); } - fseek (pdump_out, header.stab_offset, SEEK_SET); + FSEEK (pdump_out, header.stab_offset, SEEK_SET); #ifdef NEW_GC {