X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5244bc019bf7376caff3bb198ff674e0ad9fb0e6..a73de71b848da17719dcbbb9206302c09e0f79b9:/lib-src/ntlib.c diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 4e125eb6d7..4b25796830 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -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-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,26 @@ along with GNU Emacs. If not, see . */ #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. */ @@ -133,6 +138,12 @@ getuid (void) return 0; } +unsigned +geteuid (void) +{ + return getuid (); +} + unsigned getgid (void) { @@ -291,7 +302,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 +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; +}