diff --git a/libguile/filesys.c b/libguile/filesys.c
index c27e5833d..d5ac8a29b 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -89,6 +89,9 @@
#include "pairs.h"
#include "ports-internal.h"
#include "ports.h"
+#ifdef __MINGW32__
+#include "posix-w32.h"
+#endif
#include "posix.h"
#if __MINGW32__
#include "posix-w32.h"
diff --git a/libguile/posix-w32.c b/libguile/posix-w32.c
index ad12bf0aa..6d5871d31 100644
--- a/libguile/posix-w32.c
+++ b/libguile/posix-w32.c
@@ -18,10 +18,11 @@
. */
#ifdef HAVE_CONFIG_H
-# include
+#include
#endif
#define WIN32_LEAN_AND_MEAN
+#define _CRT_RAND_S
#include
#include
#include
@@ -34,9 +35,14 @@
#include
#include
+<<<<<<< HEAD
#include "gc.h" /* for scm_*alloc, scm_strdup */
#include "filename.h"
#include "threads.h" /* for scm_i_scm_pthread_mutex_lock */
+=======
+#include "gc.h" /* for scm_*alloc, scm_strdup */
+#include "threads.h" /* for scm_i_scm_pthread_mutex_lock */
+>>>>>>> bbd90294d (Win32: add replacement for mkdtemp)
#include "posix-w32.h"
@@ -46,7 +52,8 @@
int
uname (struct utsname *uts)
{
- enum { WinNT, Win95, Win98, WinUnknown };
+ enum
+ { WinNT, Win95, Win98, WinUnknown };
OSVERSIONINFO osver;
SYSTEM_INFO sysinfo;
DWORD sLength;
@@ -60,55 +67,55 @@ uname (struct utsname *uts)
switch (osver.dwPlatformId)
{
- case VER_PLATFORM_WIN32_NT: /* NT, Windows 2000 or Windows XP */
+ case VER_PLATFORM_WIN32_NT: /* NT, Windows 2000 or Windows XP */
if (osver.dwMajorVersion == 4)
- strcpy (uts->sysname, "Windows NT4x"); /* NT4x */
+ strcpy (uts->sysname, "Windows NT4x"); /* NT4x */
else if (osver.dwMajorVersion <= 3)
- strcpy (uts->sysname, "Windows NT3x"); /* NT3x */
+ strcpy (uts->sysname, "Windows NT3x"); /* NT3x */
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion < 1)
- strcpy (uts->sysname, "Windows 2000"); /* 2k */
+ strcpy (uts->sysname, "Windows 2000"); /* 2k */
else if (osver.dwMajorVersion < 6)
- strcpy (uts->sysname, "Windows XP"); /* XP */
+ strcpy (uts->sysname, "Windows XP"); /* XP */
else if (osver.dwMajorVersion == 6)
- {
- if (osver.dwMinorVersion < 1)
- strcpy (uts->sysname, "Windows Vista"); /* Vista */
- else if (osver.dwMinorVersion < 2)
- strcpy (uts->sysname, "Windows 7"); /* Windows 7 */
- else if (osver.dwMinorVersion < 3)
- strcpy (uts->sysname, "Windows 8"); /* Windows 8 */
- else if (osver.dwMinorVersion < 4)
- strcpy (uts->sysname, "Windows 8.1"); /* Windows 8.1 */
- }
+ {
+ if (osver.dwMinorVersion < 1)
+ strcpy (uts->sysname, "Windows Vista"); /* Vista */
+ else if (osver.dwMinorVersion < 2)
+ strcpy (uts->sysname, "Windows 7"); /* Windows 7 */
+ else if (osver.dwMinorVersion < 3)
+ strcpy (uts->sysname, "Windows 8"); /* Windows 8 */
+ else if (osver.dwMinorVersion < 4)
+ strcpy (uts->sysname, "Windows 8.1"); /* Windows 8.1 */
+ }
else if (osver.dwMajorVersion >= 10)
- strcpy (uts->sysname, "Windows 10 or later"); /* Windows 10 and later */
+ strcpy (uts->sysname, "Windows 10 or later"); /* Windows 10 and later */
os = WinNT;
break;
- case VER_PLATFORM_WIN32_WINDOWS: /* Win95, Win98 or WinME */
+ case VER_PLATFORM_WIN32_WINDOWS: /* Win95, Win98 or WinME */
if ((osver.dwMajorVersion > 4) ||
- ((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0)))
- {
- if (osver.dwMinorVersion >= 90)
- strcpy (uts->sysname, "Windows ME"); /* ME */
- else
- strcpy (uts->sysname, "Windows 98"); /* 98 */
- os = Win98;
- }
+ ((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0)))
+ {
+ if (osver.dwMinorVersion >= 90)
+ strcpy (uts->sysname, "Windows ME"); /* ME */
+ else
+ strcpy (uts->sysname, "Windows 98"); /* 98 */
+ os = Win98;
+ }
else
- {
- strcpy (uts->sysname, "Windows 95"); /* 95 */
- os = Win95;
- }
+ {
+ strcpy (uts->sysname, "Windows 95"); /* 95 */
+ os = Win95;
+ }
break;
- case VER_PLATFORM_WIN32s: /* Windows 3.x */
+ case VER_PLATFORM_WIN32s: /* Windows 3.x */
strcpy (uts->sysname, "Windows");
break;
}
sprintf (uts->version, "%ld.%02ld",
- osver.dwMajorVersion, osver.dwMinorVersion);
+ osver.dwMajorVersion, osver.dwMinorVersion);
if (osver.szCSDVersion[0] != '\0' &&
(strlen (osver.szCSDVersion) + strlen (uts->version) + 1) <
@@ -140,28 +147,28 @@ uname (struct utsname *uts)
* wProcessorLevel is only valid in WinNT
*/
switch (os)
- {
- case Win95:
- case Win98:
- switch (sysinfo.dwProcessorType)
- {
- case PROCESSOR_INTEL_386:
- case PROCESSOR_INTEL_486:
- case PROCESSOR_INTEL_PENTIUM:
- sprintf (uts->machine, "i%ld", sysinfo.dwProcessorType);
- break;
- default:
- strcpy (uts->machine, "i386");
- break;
- }
- break;
- case WinNT:
- sprintf (uts->machine, "i%d86", sysinfo.wProcessorLevel);
- break;
- default:
- strcpy (uts->machine, "unknown");
- break;
- }
+ {
+ case Win95:
+ case Win98:
+ switch (sysinfo.dwProcessorType)
+ {
+ case PROCESSOR_INTEL_386:
+ case PROCESSOR_INTEL_486:
+ case PROCESSOR_INTEL_PENTIUM:
+ sprintf (uts->machine, "i%ld", sysinfo.dwProcessorType);
+ break;
+ default:
+ strcpy (uts->machine, "i386");
+ break;
+ }
+ break;
+ case WinNT:
+ sprintf (uts->machine, "i%d86", sysinfo.wProcessorLevel);
+ break;
+ default:
+ strcpy (uts->machine, "unknown");
+ break;
+ }
break;
case PROCESSOR_ARCHITECTURE_AMD64:
strcpy (uts->machine, "x86_64");
@@ -169,42 +176,43 @@ uname (struct utsname *uts)
default:
strcpy (uts->machine, "unknown");
break;
- }
+ }
sLength = sizeof (uts->nodename) - 1;
GetComputerName (uts->nodename, &sLength);
return 0;
}
-
+
/* Translate abnormal exit status of Windows programs into the signal
that terminated the program. This is required to support scm_kill
and WTERMSIG. */
-struct signal_and_status {
+struct signal_and_status
+{
int sig;
DWORD status;
};
static const struct signal_and_status sigtbl[] = {
- {SIGSEGV, 0xC0000005}, /* access to invalid address */
- {SIGSEGV, 0xC0000008}, /* invalid handle */
- {SIGILL, 0xC000001D}, /* illegal instruction */
- {SIGILL, 0xC0000025}, /* non-continuable instruction */
- {SIGSEGV, 0xC000008C}, /* array bounds exceeded */
- {SIGFPE, 0xC000008D}, /* float denormal */
- {SIGFPE, 0xC000008E}, /* float divide by zero */
- {SIGFPE, 0xC000008F}, /* float inexact */
- {SIGFPE, 0xC0000090}, /* float invalid operation */
- {SIGFPE, 0xC0000091}, /* float overflow */
- {SIGFPE, 0xC0000092}, /* float stack check */
- {SIGFPE, 0xC0000093}, /* float underflow */
- {SIGFPE, 0xC0000094}, /* integer divide by zero */
- {SIGFPE, 0xC0000095}, /* integer overflow */
- {SIGILL, 0xC0000096}, /* privileged instruction */
- {SIGSEGV, 0xC00000FD}, /* stack overflow */
- {SIGTERM, 0xC000013A}, /* Ctrl-C exit */
- {SIGINT, 0xC000013A}
+ {SIGSEGV, 0xC0000005}, /* access to invalid address */
+ {SIGSEGV, 0xC0000008}, /* invalid handle */
+ {SIGILL, 0xC000001D}, /* illegal instruction */
+ {SIGILL, 0xC0000025}, /* non-continuable instruction */
+ {SIGSEGV, 0xC000008C}, /* array bounds exceeded */
+ {SIGFPE, 0xC000008D}, /* float denormal */
+ {SIGFPE, 0xC000008E}, /* float divide by zero */
+ {SIGFPE, 0xC000008F}, /* float inexact */
+ {SIGFPE, 0xC0000090}, /* float invalid operation */
+ {SIGFPE, 0xC0000091}, /* float overflow */
+ {SIGFPE, 0xC0000092}, /* float stack check */
+ {SIGFPE, 0xC0000093}, /* float underflow */
+ {SIGFPE, 0xC0000094}, /* integer divide by zero */
+ {SIGFPE, 0xC0000095}, /* integer overflow */
+ {SIGILL, 0xC0000096}, /* privileged instruction */
+ {SIGSEGV, 0xC00000FD}, /* stack overflow */
+ {SIGTERM, 0xC000013A}, /* Ctrl-C exit */
+ {SIGINT, 0xC000013A}
};
static int
@@ -216,7 +224,7 @@ w32_signal_to_status (int sig)
if (sig == sigtbl[i].sig)
return sigtbl[i].status;
- return (int)0xC000013A;
+ return (int) 0xC000013A;
}
int
@@ -320,17 +328,17 @@ console_has_return_keyevent_w32 (int fdes)
{
bRet = PeekConsoleInput (h, irbuffer, NBUFFER, &avail);
if (!bRet || avail == 0)
- break;
+ break;
for (i = 0; i < avail; i++)
- if (irbuffer[i].EventType == KEY_EVENT)
- {
- n_chars ++;
- if (irbuffer[i].Event.KeyEvent.uChar.AsciiChar == 13)
- n_returns ++;
- }
+ if (irbuffer[i].EventType == KEY_EVENT)
+ {
+ n_chars++;
+ if (irbuffer[i].Event.KeyEvent.uChar.AsciiChar == 13)
+ n_returns++;
+ }
if (avail < NBUFFER)
- break;
+ break;
}
if (n_chars == 1 && n_returns == 1)
@@ -382,3 +390,86 @@ canonicalize_file_name_mingw (const char *name)
slashify_file_name (canon);
return canon;
}
+
+// Generate a random string of specified length using character set safe
+// for filenames
+static void
+generate_random_string (char *str, size_t len)
+{
+ const char charset[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+ const size_t charset_size = sizeof (charset) - 1;
+
+ for (size_t i = 0; i < len; i++)
+ {
+ unsigned int r;
+ if (rand_s (&r) != 0)
+ {
+ // Handle rand_s failure (rare, but possible)
+ str[i] = charset[0]; // Fallback to first character
+ continue;
+ }
+ str[i] = charset[r % charset_size];
+ }
+ str[len] = '\0';
+}
+
+char *
+mkdtemp (char *template)
+{
+ const int MAX_TRIES = 20;
+
+ if (template == NULL)
+ {
+ return NULL;
+ }
+
+ // Check if template ends with "XXXXXX"
+ size_t len = strlen (template);
+ if (len < 6 || strcmp (template + len - 6, "XXXXXX") != 0)
+ {
+ return NULL;
+ }
+
+ char *working_template = _strdup (template);
+ if (working_template == NULL)
+ {
+ return NULL;
+ }
+
+ // Locate the position of "XXXXXX" in the working copy
+ char *pattern_pos = working_template + len - 6;
+
+ // Try up to MAX_TRIES times to create a unique directory
+ for (int try = 0; try < MAX_TRIES; try++)
+ {
+ // Replace "XXXXXX" with a random 6-character string
+ generate_random_string (pattern_pos, 6);
+
+ if (CreateDirectoryA (working_template, NULL))
+ {
+ // Success: copy the modified name back to the original template
+ strcpy (template, working_template);
+ free (working_template);
+ return template;
+ }
+ else
+ {
+ DWORD error = GetLastError ();
+ if (error == ERROR_ALREADY_EXISTS)
+ {
+ // Name is taken, try again with a new random string
+ continue;
+ }
+ else
+ {
+ // Other error (e.g., invalid path, permission denied), give up
+ free (working_template);
+ return NULL;
+ }
+ }
+ }
+
+ // Failed to find a unique name after MAX_TRIES
+ free (working_template);
+ return NULL;
+}
diff --git a/libguile/posix-w32.h b/libguile/posix-w32.h
index 09de7db1c..a33ba54d9 100644
--- a/libguile/posix-w32.h
+++ b/libguile/posix-w32.h
@@ -76,9 +76,11 @@ SCM_INTERNAL int dlclose_w32 (void *handle);
SCM_INTERNAL char *dlerror_w32 (void);
SCM_INTERNAL int console_has_return_keyevent_w32 (int fdes);
SCM_INTERNAL int getpagesize_w32 (void);
+SCM_INTERNAL char* mkdtemp (char* template);
#define HAVE_UNAME 1
#define HAVE_WAITPID 1
+#define HAVE_MKDTEMP 1
#define RTLD_NOW 1
#define RTLD_LAZY 2