]> code.delx.au - gnu-emacs/blobdiff - src/dired.c
Merge from emacs--rel--22
[gnu-emacs] / src / dired.c
index 31b7e19ddae9a80efede43cad4fa0333c0634b02..3efc87ac84423294317a3607c2c07bc9e1acb122 100644 (file)
@@ -96,6 +96,7 @@ extern struct direct *readdir ();
 #include "systime.h"
 #include "buffer.h"
 #include "commands.h"
+#include "character.h"
 #include "charset.h"
 #include "coding.h"
 #include "regex.h"
@@ -918,8 +919,10 @@ Elements of the attribute list are:
  8. File modes, as a string of ten letters or dashes as in ls -l.
  9. t if file's gid would change if file were deleted and recreated.
 10. inode number.  If inode number is larger than the Emacs integer,
-  this is a cons cell containing two integers: first the high part,
-  then the low 16 bits.
+  but still fits into a 32-bit number, this is a cons cell containing two
+  integers: first the high part, then the low 16 bits.  If the inode number
+  is wider than 32 bits, this is a cons cell containing three integers:
+  first the high 24 bits, then middle 24 bits, and finally the low 16 bits.
 11. Device number.  If it is larger than the Emacs integer, this is
   a cons cell, similar to the inode number.  */)
      (filename, id_format)
@@ -1028,25 +1031,32 @@ Elements of the attribute list are:
   values[9] = (gid != getegid ()) ? Qt : Qnil;
 #endif /* BSD4_2 (or BSD4_3) */
   /* Shut up GCC warnings in FIXNUM_OVERFLOW_P below.  */
-#ifdef WINDOWSNT
-  {
-    /* The bit-shuffling we do in w32.c:stat can turn on the MSB, which
-       will produce negative inode numbers.  People don't like that, so
-       force a positive inode instead.  */
-    unsigned short tem = s.st_ino;
-    ino = tem;
-  }
-#else
-  ino = s.st_ino;
-#endif
-  if (FIXNUM_OVERFLOW_P (ino))
+  if (sizeof (s.st_ino) > sizeof (ino))
+    ino = (EMACS_INT)(s.st_ino & 0xffffffff);
+  else
+    ino = s.st_ino;
+  if (!FIXNUM_OVERFLOW_P (ino)
+      && (sizeof (s.st_ino) <= sizeof (ino) || (s.st_ino & ~INTMASK) == 0))
+    /* Keep the most common cases as integers.  */
+    values[10] = make_number (ino);
+  else if (sizeof (s.st_ino) <= sizeof (ino)
+          || ((s.st_ino >> 16) & ~INTMASK) == 0)
     /* To allow inode numbers larger than VALBITS, separate the bottom
        16 bits.  */
-    values[10] = Fcons (make_number (ino >> 16),
-                       make_number (ino & 0xffff));
+    values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)),
+                       make_number ((EMACS_INT)(s.st_ino & 0xffff)));
   else
-    /* But keep the most common cases as integers.  */
-    values[10] = make_number (ino);
+    {
+      /* To allow inode numbers beyond 32 bits, separate into 2 24-bit
+        high parts and a 16-bit bottom part.  */
+      EMACS_INT high_ino = s.st_ino >> 32;
+      EMACS_INT low_ino  = s.st_ino & 0xffffffff;
+
+      values[10] = Fcons (make_number (high_ino >> 8),
+                         Fcons (make_number (((high_ino & 0xff) << 16)
+                                             + (low_ino >> 16)),
+                                make_number (low_ino & 0xffff)));
+    }
 
   /* Likewise for device.  */
   if (FIXNUM_OVERFLOW_P (s.st_dev))