emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 3ec2299: Fix MS-Windows build broken by make-finger


From: Eli Zaretskii
Subject: [Emacs-diffs] master 3ec2299: Fix MS-Windows build broken by make-fingerprint changes
Date: Mon, 15 Apr 2019 10:18:12 -0400 (EDT)

branch: master
commit 3ec22997a208b8260c2a0e7a61888d7c0db4e4fd
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Fix MS-Windows build broken by make-fingerprint changes
    
    * lib-src/make-fingerprint.c (fseeko) [WNDOWSNT]: Define to
    fseeko64 for non-MinGW64 MinGW.
    
    * lib-src/ntlib.c (stat): Fix calculation of file size.
    (fstat): New function, a subset of src/w32.c:fstat.  This is
    needed because make-fingerprint.c now calls 'fstat', and the
    MS version will fail to produce reliable results because
    nt/inc/sys/stat.h redefines 'struct stat'.
---
 lib-src/make-fingerprint.c |   5 +++
 lib-src/ntlib.c            | 100 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/lib-src/make-fingerprint.c b/lib-src/make-fingerprint.c
index dc21fc2..535e575 100644
--- a/lib-src/make-fingerprint.c
+++ b/lib-src/make-fingerprint.c
@@ -50,6 +50,11 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
    is really just insurance.  */
 #undef fopen
 #include <direct.h>
+
+#ifndef MINGW_W64
+# undef fseeko
+# define fseeko fseeko64
+#endif
 #endif /* WINDOWSNT */
 
 int
diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c
index dbafc47..d992f54 100644
--- a/lib-src/ntlib.c
+++ b/lib-src/ntlib.c
@@ -290,8 +290,8 @@ is_exec (const char * name)
 /* FIXME?  This is in configure.ac now - is this still needed?  */
 #define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\')
 
-/* We need this because nt/inc/sys/stat.h defines struct stat that is
-   incompatible with the MS run-time libraries.  */
+/* We need stat/fsfat below because nt/inc/sys/stat.h defines struct
+   stat that is incompatible with the MS run-time libraries.  */
 int
 stat (const char * path, struct stat * buf)
 {
@@ -377,7 +377,9 @@ stat (const char * path, struct stat * buf)
     buf->st_dev = _getdrive ();
   buf->st_rdev = buf->st_dev;
 
-  buf->st_size = wfd.nFileSizeLow;
+  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);
@@ -408,6 +410,98 @@ lstat (const char * path, struct stat * buf)
   return stat (path, buf);
 }
 
+int
+fstat (int desc, struct stat * buf)
+{
+  HANDLE fh = (HANDLE) _get_osfhandle (desc);
+  BY_HANDLE_FILE_INFORMATION info;
+  unsigned __int64 fake_inode;
+  int permission;
+
+  if (!init)
+    {
+      /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
+      SYSTEMTIME st;
+
+      st.wYear = 1970;
+      st.wMonth = 1;
+      st.wDay = 1;
+      st.wHour = 0;
+      st.wMinute = 0;
+      st.wSecond = 0;
+      st.wMilliseconds = 0;
+
+      SystemTimeToFileTime (&st, &utc_base_ft);
+      utc_base = (long double) utc_base_ft.dwHighDateTime
+       * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
+      init = 1;
+    }
+
+  switch (GetFileType (fh) & ~FILE_TYPE_REMOTE)
+    {
+    case FILE_TYPE_DISK:
+      buf->st_mode = S_IFREG;
+      if (!GetFileInformationByHandle (fh, &info))
+       {
+         errno = EACCES;
+         return -1;
+       }
+      break;
+    case FILE_TYPE_PIPE:
+      buf->st_mode = S_IFIFO;
+      goto non_disk;
+    case FILE_TYPE_CHAR:
+    case FILE_TYPE_UNKNOWN:
+    default:
+      buf->st_mode = S_IFCHR;
+    non_disk:
+      memset (&info, 0, sizeof (info));
+      info.dwFileAttributes = 0;
+      info.ftCreationTime = utc_base_ft;
+      info.ftLastAccessTime = utc_base_ft;
+      info.ftLastWriteTime = utc_base_ft;
+    }
+
+  if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+      buf->st_mode = S_IFDIR;
+
+  buf->st_nlink = info.nNumberOfLinks;
+  /* Might as well use file index to fake inode values, but this
+     is not guaranteed to be unique unless we keep a handle open
+     all the time. */
+  fake_inode = info.nFileIndexHigh;
+  fake_inode <<= 32;
+  fake_inode += info.nFileIndexLow;
+  buf->st_ino = fake_inode;
+
+  buf->st_dev = info.dwVolumeSerialNumber;
+  buf->st_rdev = info.dwVolumeSerialNumber;
+
+  buf->st_size = info.nFileSizeHigh;
+  buf->st_size <<= 32;
+  buf->st_size += info.nFileSizeLow;
+
+  /* Convert timestamps to Unix format. */
+  buf->st_mtime = convert_time (info.ftLastWriteTime);
+  buf->st_atime = convert_time (info.ftLastAccessTime);
+  if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
+  buf->st_ctime = convert_time (info.ftCreationTime);
+  if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
+
+  /* determine rwx permissions */
+  if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+    permission = S_IREAD;
+  else
+    permission = S_IREAD | S_IWRITE;
+
+  if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+    permission |= S_IEXEC;
+
+  buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
+
+  return 0;
+}
+
 /* On Windows, you cannot rename into an existing file.  */
 int
 sys_rename (const char *from, const char *to)



reply via email to

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