Commit 63f5c6c2 authored by Eli Zaretskii's avatar Eli Zaretskii

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
parent 1d44e9dc
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
......
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):
......
......@@ -3414,25 +3414,46 @@ 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)
int
sys_open (const char * path, int oflag, int mode)
{
const char* mpath = map_w32_filename (path, NULL);
int res = -1;
/* If possible, try to open file without _O_CREAT, to be able to
write to existing hidden and system files. Force all file
handles to be non-inheritable. */
if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
if (res < 0)
res = _open (mpath, oflag | _O_NOINHERIT, 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;
int i, fd = -1;
unsigned uid = GetCurrentThreadId ();
int save_errno = errno;
static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
errno = EINVAL;
if (template == NULL)
return NULL;
return -1;
p = template + strlen (template);
i = 5;
/* replace up to the last 5 X's with uid in decimal */
......@@ -3447,38 +3468,22 @@ sys_mktemp (char * template)
i = 0;
do
{
int save_errno = errno;
p[0] = first_char[i];
if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0)
if ((fd = sys_open (template,
flags | _O_CREAT | _O_EXCL | _O_RDWR,
S_IRUSR | S_IWUSR)) >= 0
|| errno != EEXIST)
{
errno = save_errno;
return template;
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,
so return empty string */
template[0] = 0;
return template;
}
int
sys_open (const char * path, int oflag, int mode)
{
const char* mpath = map_w32_filename (path, NULL);
int res = -1;
/* If possible, try to open file without _O_CREAT, to be able to
write to existing hidden and system files. Force all file
handles to be non-inheritable. */
if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
if (res < 0)
res = _open (mpath, oflag | _O_NOINHERIT, mode);
return res;
/* Template is badly formed or else we can't generate a unique name. */
return -1;
}
int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment