emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: file sizes shown incorrectly for large files under Windows


From: Chris Moore
Subject: Re: file sizes shown incorrectly for large files under Windows
Date: Fri, 14 Nov 2003 00:13:43 +0100

Jason Rumney writes:

 > "Eli Zaretskii" <address@hidden> writes:
 > 
 > > C9x does: it's called int64_t.  But I don't know whether MSVC has it.
 > 
 > It appears it does, at least since 6.0.

I'm using 'MinGW' to compile Emacs.  It's a free port of GCC.

I hope we don't move to requiring MSVC (non-free) to compile Emacs
under Windows.

In my stat.h I see the following:

        #if defined (__MSVCRT__)
        struct _stati64 {
            _dev_t st_dev;
            _ino_t st_ino;
            unsigned short st_mode;
            short st_nlink;
            short st_uid;
            short st_gid;
            _dev_t st_rdev;
            __int64 st_size;
            time_t st_atime;
            time_t st_mtime;
            time_t st_ctime;
        };
        #endif /* __MSVCRT__ */

This is a header file that came with MinGW - it looks like there's a
version of MinGW that supports a 64 bit integer type (although they
call it __int64, not int64_t).  I notice I have something called
'msvcrt.dll' all over my hard disk - it's the Microsoft Visual C
runtime library, and seems to come with a bunch of different programs
I've installed.  I guess it's freely available, unlike the MS C
compiler itself.

I've looked at the MinGW site ( http://www.mingw.org/ ) but not found
the version which allows me to use 64 bit integers.

Perhaps you are right Jason, and this isn't very important in the
scheme of things, but it is quite ugly how it stands.  I don't like
the idea of showing ever file of 4Gb and over as 4Gb-1 bytes - the
reason I found this bug in the first place was I had a disk that was
filling up and was trying to find which of my disk images was the
biggest.  Showing them all as being the same size wouldn't have helped
me at all...

I've made changes that work for me, and I'll keep using them.  I've
modified 3 files:

ms-w32.h: to add a field to struct stat for the high 32 bits
   w32.c: to write to that field (once for stat, once for fstat)
 dired.c: to use the new field.  I assume that if the high 32 bits
          are non-zero then the size won't fit into an Emacs integer.
          That's true at the moment, but is it safe to assume?

My test cases are as follows:

before:
------------------------------------------------------------------------
  h:/tmp:
  total used in directory 4457473 available 7428568
  drwxrwxrwx   1 Chris    root        0 11-13 23:54 .
  drwxrwxrwx   1 Chris    root        0 1970-01-01  ..
  -rw-rw-rw-   1 Chris    root        1 11-12 19:30 1
  -rw-rw-rw-   1 Chris    root 1073741824 11-12 19:34 1g
  -rw-rw-rw-   1 Chris    root 1073741825 11-13 23:56 1g-plus-1
  -rw-rw-rw-   1 Chris    root  1048576 11-12 19:28 1m
  -rw-rw-rw-   1 Chris    root 268435456 11-12 19:29 256m
  -rw-rw-rw-   1 Chris    root 2147483648 11-12 19:38 2g
  -rw-rw-rw-   1 Chris    root        1 11-12 19:54 4g-plus-1
------------------------------------------------------------------------

after:
------------------------------------------------------------------------
  h:/tmp:
  total used in directory 8651777 available 7428568
  drwxrwxrwx   1 Chris    root        0 11-13 23:54 .
  drwxrwxrwx   1 Chris    root        0 1970-01-01  ..
  -rw-rw-rw-   1 Chris    root        1 11-12 19:30 1
  -rw-rw-rw-   1 Chris    root 1073741824 11-12 19:34 1g
  -rw-rw-rw-   1 Chris    root 1073741825 11-13 23:56 1g-plus-1
  -rw-rw-rw-   1 Chris    root  1048576 11-12 19:28 1m
  -rw-rw-rw-   1 Chris    root 268435456 11-12 19:29 256m
  -rw-rw-rw-   1 Chris    root 2147483648 11-12 19:38 2g
  -rw-rw-rw-   1 Chris    root 4294967297 11-12 19:54 4g-plus-1
------------------------------------------------------------------------

Unfortunately I no longer have the huge file to test it on.

Here are the patches:

-------cut-here-------8<--------cut-here--------8<-------cut-here-------
Index: w32.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32.c,v
retrieving revision 1.85
diff -c -r1.85 w32.c
*** w32.c       1 Sep 2003 15:45:57 -0000       1.85
--- w32.c       13 Nov 2003 23:01:56 -0000
***************
*** 2439,2444 ****
--- 2439,2445 ----
  
  
    buf->st_size = wfd.nFileSizeLow;
+   buf->st_size_high = wfd.nFileSizeHigh;
  
    /* Convert timestamps to Unix format. */
    buf->st_mtime = convert_time (wfd.ftLastWriteTime);
***************
*** 2523,2528 ****
--- 2524,2530 ----
    buf->st_rdev = info.dwVolumeSerialNumber;
  
    buf->st_size = info.nFileSizeLow;
+   buf->st_size_high = info.nFileSizeHigh;
  
    /* Convert timestamps to Unix format. */
    buf->st_mtime = convert_time (info.ftLastWriteTime);

Index: dired.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/dired.c,v
retrieving revision 1.105
diff -c -r1.105 dired.c
*** dired.c     1 Sep 2003 15:45:52 -0000       1.105
--- dired.c     13 Nov 2003 23:02:34 -0000
***************
*** 939,947 ****
--- 939,952 ----
    values[5] = make_time (s.st_mtime);
    values[6] = make_time (s.st_ctime);
    values[7] = make_number (s.st_size);
+ #ifdef WINDOWSNT
+   if (XINT (values[7]) != s.st_size || s.st_size_high)
+     values[7] = make_float ((double)s.st_size + ((double)s.st_size_high * 
0x10000) * 0x10000);
+ #else  /* not WINDOWSNT */
    /* If the size is out of range for an integer, return a float.  */
    if (XINT (values[7]) != s.st_size)
      values[7] = make_float ((double)s.st_size);
+ #endif /* not WINDOWSNT */
    /* If the size is negative, and its type is long, convert it back to
       positive.  */
    if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))

Index: ms-w32.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/s/ms-w32.h,v
retrieving revision 1.30
diff -c -r1.30 ms-w32.h
*** ms-w32.h    1 Sep 2003 15:45:58 -0000       1.30
--- ms-w32.h    13 Nov 2003 23:02:54 -0000
***************
*** 438,443 ****
--- 438,463 ----
  #endif
  #include <malloc.h>
  
+ #ifndef _STAT_DEFINED
+ struct stat
+ {
+       _dev_t  st_dev;         /* Equivalent to drive number 0=A 1=B ... */
+       _ino_t  st_ino;         /* Always zero ? */
+       _mode_t st_mode;        /* See above constants */
+       short   st_nlink;       /* Number of links. */
+       short   st_uid;         /* User: Maybe significant on NT ? */
+       short   st_gid;         /* Group: Ditto */
+       _dev_t  st_rdev;        /* Seems useless (not even filled in) */
+       _off_t  st_size;        /* Low 32 bits of file size in bytes */
+       _off_t  st_size_high;   /* High 32 bits of file size in bytes */
+       time_t  st_atime;       /* Accessed date (always 00:00 hrs local
+                                * on FAT) */
+       time_t  st_mtime;       /* Modified time */
+       time_t  st_ctime;       /* Creation time */
+ };
+ #define _STAT_DEFINED
+ #endif /* _STAT_DEFINED */
+ 
  #include <sys/stat.h>
  
  /* Define for those source files that do not include enough NT
-------cut-here-------8<--------cut-here--------8<-------cut-here-------

Chris.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]