summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1996-06-07 23:07:00 +0000
committerRichard M. Stallman <rms@gnu.org>1996-06-07 23:07:00 +0000
commit49bc796d5c435c4de5b8bf131e840f2f2920cc7c (patch)
treeff7fb365645bb48cfdf11aa3d791c5d8a10d54f6
parentf261a73877a88971a6cb74db1576332c8c2fa3cf (diff)
downloademacs-49bc796d5c435c4de5b8bf131e840f2f2920cc7c.tar.gz
(sys_mktemp): Complete rewrite.
-rw-r--r--src/w32.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/w32.c b/src/w32.c
index 7e9f59d1ae5..adda8f0ee85 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -988,10 +988,54 @@ sys_mkdir (const char * path)
return _mkdir (map_win32_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)
{
- return (char *) map_win32_filename ((const char *) _mktemp (template), NULL);
+ 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 (sys_access (template, 0) < 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