declare smobs in alloc.c
[bpt/emacs.git] / lib-src / ntlib.c
index feaad1c..23d7ba7 100644 (file)
@@ -1,6 +1,6 @@
 /* Utility and Unix shadow routines for GNU Emacs support programs on NT.
 
-Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc.
+Copyright (C) 1994, 2001-2014 Free Software Foundation, Inc.
 
 Author: Geoff Voelker (voelker@cs.washington.edu)
 Created: 10-8-94
@@ -30,24 +30,30 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <errno.h>
 #include <ctype.h>
 #include <sys/timeb.h>
+#include <mbstring.h>
 
 #include "ntlib.h"
 
+/* 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
 
 #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.  */
@@ -132,6 +138,12 @@ getuid (void)
   return 0;
 }
 
+unsigned
+geteuid (void)
+{
+  return getuid ();
+}
+
 unsigned
 getgid (void)
 {
@@ -411,3 +423,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;
+}