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

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

bug#10733: 24.0.93; w32 file truncation


From: Óscar Fuentes
Subject: bug#10733: 24.0.93; w32 file truncation
Date: Tue, 07 Feb 2012 00:27:07 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

[snip]

> No.  The `stat' Emacs uses is in w32.c.  What you see on
> lib-src/ntlib.c is just a minimal subset of what we have in w32.c.

That's important. Thanks.

>> Symlinks are detected and handled specially on MSVCRT's stat. In
>> aessence, for symlinks it uses fstat.
>
> But fstat probably calls GetFileInformationByHandle under the hood,
> and we already call that function in w32.c:stat.  So maybe the fix is
> not as ugly and inelegant as you thought.

Yup. This patch fixes the problem:

diff --git a/src/w32.c b/src/w32.c
index f610a36..035e1f2 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -3444,6 +3444,29 @@ stat (const char * path, struct stat * buf)
        }
     }
 
+  buf->st_size = 0;
+
+  if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+      (wfd.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
+    {
+      HANDLE fh;
+      BY_HANDLE_FILE_INFORMATION info;
+
+      if ((fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING,
+                            FILE_FLAG_BACKUP_SEMANTICS, NULL))
+          && GetFileInformationByHandle (fh, &info))
+        {
+          buf->st_size = info.nFileSizeHigh;
+          buf->st_size <<= 32;
+          buf->st_size += info.nFileSizeLow;
+        }
+      else
+        {
+          errno = ENOENT;
+          return -1;
+        }
+    }
+
   if (!(NILP (Vw32_get_true_file_attributes)
        || (EQ (Vw32_get_true_file_attributes, Qlocal) && is_slow_fs (name)))
       /* No access rights required to get info.  */
@@ -3532,9 +3555,12 @@ stat (const char * path, struct stat * buf)
   buf->st_dev = volume_info.serialnum;
   buf->st_rdev = volume_info.serialnum;
 
-  buf->st_size = wfd.nFileSizeHigh;
-  buf->st_size <<= 32;
-  buf->st_size += wfd.nFileSizeLow;
+  if (! buf->st_size)
+    {
+      buf->st_size = wfd.nFileSizeHigh;
+      buf->st_size <<= 32;
+      buf->st_size += wfd.nFileSizeLow;
+    }
 
   /* Convert timestamps to Unix format. */
   buf->st_mtime = convert_time (wfd.ftLastWriteTime);


Maybe it can be integrated in the

if (!(NILP(Vw32_get_true_file_attributes) ...

hence reusing the calls to CreateFile and GetFileInformationByHandle and
shortening the patch, but as I don't know what
Vw32_get_true_file_attributes does, preferread to follow the safe way.

However, we still have another implementation on ntlib.c.

And the fix is just for the size. Don't know if there are other
attributes suffer from the same problem. Possibly the right thing is to
do what MSVCRT does:

if is-symlink?
  use fstat
fi





reply via email to

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