]> code.delx.au - gnu-emacs/commitdiff
Implement mkostemp for MS-Windows.
authorEli Zaretskii <eliz@gnu.org>
Sun, 4 Aug 2013 15:32:12 +0000 (18:32 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sun, 4 Aug 2013 15:32:12 +0000 (18:32 +0300)
 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
nt/ChangeLog
nt/config.nt
nt/inc/ms-w32.h
nt/mingw-cfg.site
src/ChangeLog
src/w32.c

index c0598dd563041be772ab1af442cae3dcec68f20f..23c0c74b6f14f98de3433bd7e91506e3f78d466c 100644 (file)
@@ -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)
index 95b56f2dc64b3cf46c1713268a927fb3d839cc3a..3ba60a85752d61be1d10c75f1625de2724cd0382 100644 (file)
@@ -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
 
index 3e50c78f145afc59ae0087f38321defafa2d11e2..f01f254d81cd95501a998eb61119fea428fc0e1a 100644 (file)
@@ -450,6 +450,8 @@ extern int getpagesize (void);
 
 extern void * memrchr (void const *, int, size_t);
 
+extern int mkostemp (char *, int);
+
 
 #if defined (__MINGW32__)
 
index cf55fe04ed8a1833ad93fb892e3e2e64ceaa4af8..325bba29ae574171d6c46c310d99fbaf69eda210 100644 (file)
@@ -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
index 8a9de96358dae24a92679ddddc8a88e73a9d9b60..0fe6b4e6ce3c01e3fd8fff823c68661a752e6bb1 100644 (file)
@@ -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):
index fb2d7c75972326f24038e5033f4128c3b230b5aa..af42c6f39c2614669b34fa460fa44bee43961b47 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -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