]> code.delx.au - gnu-emacs/blobdiff - src/w32.c
Merge from trunk.
[gnu-emacs] / src / w32.c
index 5011642adf27c9c87f678f0a39260ea89af43707..fb069c36673c6ac550b5219a604e39440b264ee3 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -29,10 +29,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <ctype.h>
 #include <signal.h>
 #include <sys/file.h>
+#include <time.h>      /* must be before nt/inc/sys/time.h, for MinGW64 */
 #include <sys/time.h>
 #include <sys/utime.h>
 #include <math.h>
-#include <time.h>
 
 /* must include CRT headers *before* config.h */
 
@@ -69,7 +69,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <pwd.h>
 #include <grp.h>
 
-#ifdef __GNUC__
+/* MinGW64 (_W64) defines these in its _mingw.h.  */
+#if defined(__GNUC__) && !defined(_W64)
 #define _ANONYMOUS_UNION
 #define _ANONYMOUS_STRUCT
 #endif
@@ -96,6 +97,7 @@ typedef struct _MEMORY_STATUS_EX {
 #ifndef _MSC_VER
 #include <w32api.h>
 #endif
+#if _WIN32_WINNT < 0x0500
 #if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15)
 /* This either is not in psapi.h or guarded by higher value of
    _WIN32_WINNT than what we use.  w32api supplied with MinGW 3.15
@@ -114,6 +116,7 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
   SIZE_T PrivateUsage;
 } PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
 #endif
+#endif
 
 #include <winioctl.h>
 #include <aclapi.h>
@@ -127,11 +130,11 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
 #define SDDL_REVISION_1        1
 #endif /* SDDL_REVISION_1 */
 
-#ifdef _MSC_VER
-/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the
-   associated macros, except on ntifs.h, which cannot be included
-   because it triggers conflicts with other Windows API headers.  So
-   we define it here by hand.  */
+#if defined(_MSC_VER) || defined(_W64)
+/* MSVC and MinGW64 don't provide the definition of
+   REPARSE_DATA_BUFFER and the associated macros, except on ntifs.h,
+   which cannot be included because it triggers conflicts with other
+   Windows API headers.  So we define it here by hand.  */
 
 typedef struct _REPARSE_DATA_BUFFER {
     ULONG  ReparseTag;
@@ -171,9 +174,12 @@ typedef struct _REPARSE_DATA_BUFFER {
 #ifndef CTL_CODE
 #define CTL_CODE(t,f,m,a)       (((t)<<16)|((a)<<14)|((f)<<2)|(m))
 #endif
+/* MinGW64 defines FSCTL_GET_REPARSE_POINT on winioctl.h.  */
+#ifndef FSCTL_GET_REPARSE_POINT
 #define FSCTL_GET_REPARSE_POINT \
   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #endif
+#endif
 
 /* TCP connection support.  */
 #include <sys/socket.h>
@@ -2388,8 +2394,8 @@ get_emacs_configuration_options (void)
 #include <sys/timeb.h>
 
 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95).  */
-void
-gettimeofday (struct timeval *tv, struct timezone *tz)
+int
+gettimeofday (struct timeval *restrict tv, struct timezone *restrict tz)
 {
   struct _timeb tb;
   _ftime (&tb);
@@ -2407,6 +2413,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
       tz->tz_minuteswest = tb.timezone;        /* minutes west of Greenwich  */
       tz->tz_dsttime = tb.dstflag;     /* type of dst correction  */
     }
+  return 0;
 }
 
 /* Emulate fdutimens.  */
@@ -3402,20 +3409,27 @@ int
 sys_open (const char * path, int oflag, int mode)
 {
   const char* mpath = map_w32_filename (path, NULL);
-  /* Try to open file without _O_CREAT, to be able to write to hidden
-     and system files. Force all file handles to be
-     non-inheritable. */
-  int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
+  int res = -1;
+
+  /* If possible, try to open file without _O_CREAT, to be able to
+     write to existing hidden and system files.  Force all file
+     handles to be non-inheritable. */
+  if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
+    res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
   if (res < 0)
     res = _open (mpath, oflag | _O_NOINHERIT, mode);
-  if (res >= 0 && res < MAXDESC)
-    fd_info[res].flags = 0;
 
   return res;
 }
 
 int
-sys_rename (const char * oldname, const char * newname)
+fchmod (int fd, mode_t mode)
+{
+  return 0;
+}
+
+int
+sys_rename_replace (const char *oldname, const char *newname, BOOL force)
 {
   BOOL result;
   char temp[MAX_PATH];
@@ -3471,7 +3485,7 @@ sys_rename (const char * oldname, const char * newname)
        return -1;
     }
 
-  /* Emulate Unix behavior - newname is deleted if it already exists
+  /* If FORCE, emulate Unix behavior - newname is deleted if it already exists
      (at least if it is a file; don't do this for directories).
 
      Since we mustn't do this if we are just changing the case of the
@@ -3489,7 +3503,7 @@ sys_rename (const char * oldname, const char * newname)
 
   result = rename (temp, newname);
 
-  if (result < 0)
+  if (result < 0 && force)
     {
       DWORD w32err = GetLastError ();
 
@@ -3528,6 +3542,12 @@ sys_rename (const char * oldname, const char * newname)
   return result;
 }
 
+int
+sys_rename (char const *old, char const *new)
+{
+  return sys_rename_replace (old, new, TRUE);
+}
+
 int
 sys_rmdir (const char * path)
 {
@@ -4410,9 +4430,9 @@ fstat (int desc, struct stat * buf)
 }
 
 int
-utime (const char *name, struct utimbuf *times)
+utime (const char *name, struct _utimbuf *times)
 {
-  struct utimbuf deftime;
+  struct _utimbuf deftime;
   HANDLE fh;
   FILETIME mtime;
   FILETIME atime;
@@ -5567,10 +5587,8 @@ ltime (ULONGLONG time_100ns)
 {
   ULONGLONG time_sec = time_100ns / 10000000;
   int subsec = time_100ns % 10000000;
-  return list4 (make_number (time_sec >> 16),
-               make_number (time_sec & 0xffff),
-               make_number (subsec / 10),
-               make_number (subsec % 10 * 100000));
+  return list4i (time_sec >> 16, time_sec & 0xffff,
+                subsec / 10, subsec % 10 * 100000);
 }
 
 #define U64_TO_LISP_TIME(time) ltime (time)