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.
This commit is contained in:
parent
84288cf421
commit
8cc8ad02bd
7 changed files with 26 additions and 127 deletions
|
@ -36,9 +36,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <malloc.h>
|
||||
#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'. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
58
src/w32.c
58
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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue