X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/947aa1c6e77af64fc0ad29910cbe1a3430b5f088..1650d7102ae8ea943e4197b7d91198640f0e0ff6:/lib-src/ntlib.c diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 41b4e3a0cb..2ace218f82 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-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,6 +34,12 @@ along with GNU Emacs. If not, see . */ #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 @@ -44,6 +50,8 @@ struct timezone }; #endif +void gettimeofday (struct timeval *, struct timezone *); + #define MAXPATHLEN _MAX_PATH /* Emulate sleep...we could have done this with a define, but that @@ -302,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 @@ -422,3 +430,72 @@ 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; +}