From 8cc8ad02bd5c410c61680735149ce7caf67f088d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 12 Aug 2017 11:29:37 +0300 Subject: [PATCH] Use Gnulib 'tempname' on MS-Windows * lib-src/ntlib.h (mkdir, open): Remove redefinitions. They are now in nt/inc/ms-w32.h. * lib-src/ntlib.c (sys_mkdir, sys_open): New functions. (mkostemp): Remove. * src/w32.c (mkostemp): Remove. (sys_mkdir): Accept a second (unused) argument. * src/fileio.c (Fmake_directory_internal): Remove the WINDOWSNT specific call to mkdir. (Bug#28023) * nt/inc/ms-w32.h (mkdir): Remove from "#ifdef emacs" and redefine to accept 2 arguments. (open): Remove from "#ifdef emacs". * nt/mingw-cfg.site (ac_cv_func_mkostemp): Remove. * nt/gnulib-cfg.mk (OMIT_GNULIB_MODULE_mkostemp) (OMIT_GNULIB_MODULE_tempname): Remove. --- lib-src/ntlib.c | 69 +++++++++++-------------------------------------------- lib-src/ntlib.h | 4 ---- nt/gnulib-cfg.mk | 2 -- nt/inc/ms-w32.h | 15 ++++++++---- nt/mingw-cfg.site | 1 - src/fileio.c | 4 ---- src/w32.c | 58 +--------------------------------------------- 7 files changed, 26 insertions(+), 127 deletions(-) diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 78ba9061f6b..9908f0fa452 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -36,9 +36,11 @@ along with GNU Emacs. If not, see . */ char *sys_ctime (const time_t *); FILE *sys_fopen (const char *, const char *); +int sys_mkdir (const char *, mode_t); int sys_chdir (const char *); int mkostemp (char *, int); int sys_rename (const char *, const char *); +int sys_open (const char *, int, int); /* MinGW64 defines _TIMEZONE_DEFINED and defines 'struct timespec' in its system headers. */ @@ -245,6 +247,12 @@ sys_chdir (const char * path) return _chdir (path); } +int +sys_mkdir (const char * path, mode_t mode) +{ + return _mkdir (path); +} + static FILETIME utc_base_ft; static long double utc_base; static int init = 0; @@ -396,61 +404,6 @@ 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) @@ -464,3 +417,9 @@ sys_rename (const char *from, const char *to) } return retval; } + +int +sys_open (const char * path, int oflag, int mode) +{ + return _open (path, oflag, mode); +} diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index 32189dcc7a0..b69a40b4f03 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -58,10 +58,6 @@ int fchown (int fd, unsigned uid, unsigned gid); #undef dup2 #define dup2 _dup2 #undef fopen -#undef mkdir -#define mkdir _mkdir -#undef open -#define open _open #undef pipe #define pipe _pipe #undef read diff --git a/nt/gnulib-cfg.mk b/nt/gnulib-cfg.mk index 175329fb9e7..d2b96f99e27 100644 --- a/nt/gnulib-cfg.mk +++ b/nt/gnulib-cfg.mk @@ -50,7 +50,6 @@ OMIT_GNULIB_MODULE_dirfd = true OMIT_GNULIB_MODULE_fcntl = true OMIT_GNULIB_MODULE_fcntl-h = true OMIT_GNULIB_MODULE_inttypes-incomplete = true -OMIT_GNULIB_MODULE_mkostemp = true OMIT_GNULIB_MODULE_pipe2 = true OMIT_GNULIB_MODULE_secure_getenv = true OMIT_GNULIB_MODULE_signal-h = true @@ -60,5 +59,4 @@ OMIT_GNULIB_MODULE_sys_select = true OMIT_GNULIB_MODULE_sys_stat = true OMIT_GNULIB_MODULE_sys_time = true OMIT_GNULIB_MODULE_sys_types = true -OMIT_GNULIB_MODULE_tempname = true OMIT_GNULIB_MODULE_unistd = true diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index 957d8c6bdbc..e1dbe29bbb8 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -237,9 +237,6 @@ extern void w32_reset_stack_overflow_guard (void); #define fopen sys_fopen #define link sys_link #define localtime sys_localtime -#define mkdir sys_mkdir -#undef open -#define open sys_open #undef read #define read sys_read #define rename sys_rename @@ -289,6 +286,10 @@ extern int sys_umask (int); #endif /* emacs */ +/* Used both in Emacs, in lib-src, and in Gnulib. */ +#undef open +#define open sys_open + /* Map to MSVC names. */ #define execlp _execlp #define execvp _execvp @@ -465,6 +466,12 @@ extern char *get_emacs_configuration_options (void); #include #endif +/* Needed in Emacs and in Gnulib. */ +/* This must be after including sys/stat.h, because we need mode_t. */ +#undef mkdir +#define mkdir(d,f) sys_mkdir(d,f) +int sys_mkdir (const char *, mode_t); + #ifdef emacs typedef void * (* malloc_fn)(size_t); @@ -518,9 +525,9 @@ extern int getpagesize (void); extern void * memrchr (void const *, int, size_t); +/* Declared here, since we don't use Gnulib's stdlib.h. */ extern int mkostemp (char *, int); - #if defined (__MINGW32__) /* Define to 1 if the system has the type `long long int'. */ diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site index a1067179797..d9a824008cb 100644 --- a/nt/mingw-cfg.site +++ b/nt/mingw-cfg.site @@ -79,7 +79,6 @@ ac_cv_func_getaddrinfo=yes # Implemented as an inline function in ws2tcpip.h ac_cv_func_gai_strerror=yes # Implemented in w32.c -ac_cv_func_mkostemp=yes ac_cv_func_readlink=yes ac_cv_func_symlink=yes # Avoid run-time tests of readlink and symlink, which will fail diff --git a/src/fileio.c b/src/fileio.c index 9aae7d997ee..8506a198fe3 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2178,11 +2178,7 @@ DEFUN ("make-directory-internal", Fmake_directory_internal, dir = SSDATA (encoded_dir); -#ifdef WINDOWSNT - if (mkdir (dir) != 0) -#else if (mkdir (dir, 0777 & ~auto_saving_dir_umask) != 0) -#endif report_file_error ("Creating directory", directory); return Qnil; diff --git a/src/w32.c b/src/w32.c index fa3cbe183fb..bdeaed0675b 100644 --- a/src/w32.c +++ b/src/w32.c @@ -74,7 +74,6 @@ char *sys_ctime (const time_t *); int sys_chdir (const char *); int sys_creat (const char *, int); FILE *sys_fopen (const char *, const char *); -int sys_mkdir (const char *); int sys_open (const char *, int, int); int sys_rename (char const *, char const *); int sys_rmdir (const char *); @@ -4344,7 +4343,7 @@ sys_link (const char * old, const char * new) } int -sys_mkdir (const char * path) +sys_mkdir (const char * path, mode_t mode) { path = map_w32_filename (path, NULL); @@ -4397,61 +4396,6 @@ sys_open (const char * path, int oflag, int mode) return res; } -/* Implementation of mkostemp for MS-Windows, to avoid race conditions - when using mktemp. - - Standard algorithm for generating a temporary file name seems to be - use pid or tid with a letter on the front (in place of the 6 X's) - and cycle through the letters to find a unique name. We extend - that to allow any reasonable character as the first of the 6 X's, - so that the number of simultaneously used temporary files will be - greater. */ - -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 = sys_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; -} - int fchmod (int fd, mode_t mode) { -- 2.11.4.GIT