]> code.delx.au - gnu-emacs/blobdiff - lib-src/ntlib.c
Ibuffer change marks
[gnu-emacs] / lib-src / ntlib.c
index f43117457cb1de29b8f065ce0f13820b84abef8d..2ace218f8231330b54d351f4de04ac9dcf4a5a88 100644 (file)
@@ -1,6 +1,6 @@
 /* Utility and Unix shadow routines for GNU Emacs support programs on NT.
 
-Copyright (C) 1994, 2001-2013 Free Software Foundation, Inc.
+Copyright (C) 1994, 2001-2016 Free Software Foundation, Inc.
 
 Author: Geoff Voelker (voelker@cs.washington.edu)
 Created: 10-8-94
@@ -9,8 +9,8 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -34,21 +34,34 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "ntlib.h"
 
+char *sys_ctime (const time_t *);
+FILE *sys_fopen (const char *, const char *);
+int sys_chdir (const char *);
+int mkostemp (char *, int);
+int sys_rename (const char *, const char *);
+
+/* MinGW64 defines _TIMEZONE_DEFINED and defines 'struct timespec' in
+   its system headers.  */
+#ifndef _TIMEZONE_DEFINED
 struct timezone
 {
   int          tz_minuteswest; /* minutes west of Greenwich */
   int          tz_dsttime;     /* type of dst correction */
 };
+#endif
+
+void gettimeofday (struct timeval *, struct timezone *);
 
 #define MAXPATHLEN _MAX_PATH
 
 /* Emulate sleep...we could have done this with a define, but that
    would necessitate including windows.h in the files that used it.
    This is much easier.  */
-void
-sleep (unsigned long seconds)
+unsigned
+sleep (unsigned seconds)
 {
   Sleep (seconds * 1000);
+  return 0;
 }
 
 /* Get the current working directory.  */
@@ -133,6 +146,12 @@ getuid (void)
   return 0;
 }
 
+unsigned
+geteuid (void)
+{
+  return getuid ();
+}
+
 unsigned
 getgid (void)
 {
@@ -291,7 +310,7 @@ is_exec (const char * name)
         stricmp (p, ".cmd") == 0));
 }
 
-/* FIXME?  This is in config.nt now - is this still needed?  */
+/* 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
@@ -412,3 +431,71 @@ lstat (const char * path, struct stat * buf)
   return stat (path, buf);
 }
 
+/* Implementation of mkostemp for MS-Windows, to avoid race conditions
+   when using mktemp.  Copied from w32.c.
+
+   This is used only in update-game-score.c.  It is overkill for that
+   use case, since update-game-score renames the temporary file into
+   the game score file, which isn't atomic on MS-Windows anyway, when
+   the game score already existed before running the program, which it
+   almost always does.  But using a simpler implementation just to
+   make a point is uneconomical...  */
+
+int
+mkostemp (char * template, int flags)
+{
+  char * p;
+  int i, fd = -1;
+  unsigned uid = GetCurrentThreadId ();
+  int save_errno = errno;
+  static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
+
+  errno = EINVAL;
+  if (template == NULL)
+    return -1;
+
+  p = template + strlen (template);
+  i = 5;
+  /* replace up to the last 5 X's with uid in decimal */
+  while (--p >= template && p[0] == 'X' && --i >= 0)
+    {
+      p[0] = '0' + uid % 10;
+      uid /= 10;
+    }
+
+  if (i < 0 && p[0] == 'X')
+    {
+      i = 0;
+      do
+       {
+         p[0] = first_char[i];
+         if ((fd = open (template,
+                         flags | _O_CREAT | _O_EXCL | _O_RDWR,
+                         S_IRUSR | S_IWUSR)) >= 0
+             || errno != EEXIST)
+           {
+             if (fd >= 0)
+               errno = save_errno;
+             return fd;
+           }
+       }
+      while (++i < sizeof (first_char));
+    }
+
+  /* Template is badly formed or else we can't generate a unique name.  */
+  return -1;
+}
+
+/* On Windows, you cannot rename into an existing file.  */
+int
+sys_rename (const char *from, const char *to)
+{
+  int retval = rename (from, to);
+
+  if (retval < 0 && errno == EEXIST)
+    {
+      if (unlink (to) == 0)
+       retval = rename (from, to);
+    }
+  return retval;
+}