Commits

Anonymous committed 86d33dd

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>.

  • Participants
  • Parent commits 179f4a9

Comments (0)

Files changed (9)

+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
 with_purify
 enable_valgrind
 with_valgrind
+enable_largefile
 with_x
 '
       ac_precious_vars='build_alias
   --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)
 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 :
 
 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))
 

lib-src/ChangeLog

+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.

lib-src/insert-data-in-exec.c

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <config.h>
 
 static const unsigned char key[] = {
   255,
 {
   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];
 
       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");
     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);
   }
       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);
   }
 
   }
 
   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++;
   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");
     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);
   }
       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);
   }
 
   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");
       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);
   }
 
+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
 #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>
 
   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)));
 }
 
 
 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))
 	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
   {