Implement mkostemp for MS-Windows.
nt/mingw-cfg.site (ac_cv_func_mkostemp): New var with value of "yes". nt/inc/ms-w32.h (mkostemp): Declare prototype. nt/config.nt (HAVE_MKOSTEMP): Define to 1. src/w32.c (mkostemp): New function. (mktemp): Remove, no longer used. Most of the code reused in mkostemp. Fixes: debbugs:15015
This commit is contained in:
parent
1d44e9dcad
commit
63f5c6c20d
6 changed files with 76 additions and 50 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-08-04 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* mingw-cfg.site (ac_cv_func_mkostemp): New var with value of
|
||||
"yes".
|
||||
|
||||
* inc/ms-w32.h (mkostemp): Declare prototype.
|
||||
|
||||
* config.nt (HAVE_MKOSTEMP): Define to 1. (Bug#15015)
|
||||
|
||||
2013-07-07 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* inc/sys/socket.h (F_SETFD, O_CLOEXEC, F_DUPFD_CLOEXEC)
|
||||
|
|
|
@ -796,6 +796,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
systems that support xmenu.c. */
|
||||
#undef HAVE_MENUS
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
#define HAVE_MKOSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `mkstemp' function. */
|
||||
#undef HAVE_MKSTEMP
|
||||
|
||||
|
|
|
@ -450,6 +450,8 @@ extern int getpagesize (void);
|
|||
|
||||
extern void * memrchr (void const *, int, size_t);
|
||||
|
||||
extern int mkostemp (char *, int);
|
||||
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ ac_cv_func_getpeername=yes
|
|||
# Implemented as sys_socket in w32.c
|
||||
ac_cv_func_socket=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
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2013-08-04 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32.c (mkostemp): New function.
|
||||
(mktemp): Remove, no longer used. Most of the code reused in
|
||||
mkostemp. (Bug#15015)
|
||||
|
||||
2013-08-04 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* dispnew.c (glyph_matrix_count, glyph_pool_count):
|
||||
|
|
105
src/w32.c
105
src/w32.c
|
@ -3414,56 +3414,6 @@ sys_mkdir (const char * path)
|
|||
return _mkdir (map_w32_filename (path, NULL));
|
||||
}
|
||||
|
||||
/* Because of long name mapping issues, we need to implement this
|
||||
ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
|
||||
a unique name, instead of setting the input template to an empty
|
||||
string.
|
||||
|
||||
Standard algorithm 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. */
|
||||
char *
|
||||
sys_mktemp (char * template)
|
||||
{
|
||||
char * p;
|
||||
int i;
|
||||
unsigned uid = GetCurrentThreadId ();
|
||||
static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
|
||||
|
||||
if (template == NULL)
|
||||
return NULL;
|
||||
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
|
||||
{
|
||||
int save_errno = errno;
|
||||
p[0] = first_char[i];
|
||||
if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0)
|
||||
{
|
||||
errno = save_errno;
|
||||
return template;
|
||||
}
|
||||
}
|
||||
while (++i < sizeof (first_char));
|
||||
}
|
||||
|
||||
/* Template is badly formed or else we can't generate a unique name,
|
||||
so return empty string */
|
||||
template[0] = 0;
|
||||
return template;
|
||||
}
|
||||
|
||||
int
|
||||
sys_open (const char * path, int oflag, int mode)
|
||||
{
|
||||
|
@ -3481,6 +3431,61 @@ 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