~ chicken-core (chicken-5) 566479b9221ced8071a060feacad1704dc59b0df
commit 566479b9221ced8071a060feacad1704dc59b0df
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Wed May 14 15:50:09 2025 +0100
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Wed May 14 15:50:09 2025 +0100
use wide char API on win32 for some file operations, ensure renamed-to file is deleted first
diff --git a/file.scm b/file.scm
index 563724d8..1e4d6a47 100644
--- a/file.scm
+++ b/file.scm
@@ -41,8 +41,6 @@
(foreign-declare #<<EOF
#include <errno.h>
-#define C_test_access(fn, m) C_fix(access(C_c_string(fn), C_unfix(m)))
-
/* For Windows */
#ifndef R_OK
# define R_OK 2
@@ -54,24 +52,46 @@
# define X_OK 2
#endif
-#define C_rename(old, new) C_fix(rename(C_c_string(old), C_c_string(new)))
-#define C_remove(str) C_fix(remove(C_c_string(str)))
-#define C_rmdir(str) C_fix(rmdir(C_c_string(str)))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define C_test_access(fn, m) C_fix(_waccess(C_utf16(fn, 0), C_unfix(m)))
-#ifndef _WIN32
-# include <sys/stat.h>
-# define C_mkdir(str) C_fix(mkdir(C_c_string(str), S_IRWXU | S_IRWXG | S_IRWXO))
+static C_word C_rename(C_word old, C_word new) {
+ C_char *s = C_utf16(old, 0), *s2 = C_utf16(new, 1);
+ _wremove(s2);
+ return(C_fix(_wrename(s, s2));
+}
+
+# define C_remove(str) C_fix(_wremove(C_utf16(str, 0)))
+# define C_rmdir(str) C_fix(_wrmdir(C_utf16(str, 0)))
+# define C_mkdir(str) C_fix(_wmkdir(C_utf16(str, 0), S_IRWXU | S_IRWXG | S_IRWXO))
#else
-# define C_mkdir(str) C_fix(mkdir(C_c_string(str)))
+# include <sys/stat.h>
+# define C_test_access(fn, m) C_fix(access(C_utf16(C_c_string(fn), C_unfix(m)))
+# define C_rename(old, new) C_fix(rename(C_c_string(old), C_c_string(new)))
+# define C_remove(str) C_fix(remove(C_c_string(str)))
+# define C_rmdir(str) C_fix(rmdir(C_c_string(str)))
+# define C_mkdir(str) C_fix(mkdir(C_c_string(str)))
#endif
#include <sys/types.h>
#include <dirent.h>
-#define C_opendir(s,h) C_set_block_item(h, 0, (C_word) opendir(C_c_string(s)))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define C_opendir(s,h) C_set_block_item(h, 0, (C_word) _wopendir(C_utf16(s, 0)))
+
+static C_word C_foundfile(C_word e,C_word b,C_word l) {
+ C_char *s = C_utf8(((struct dirent *) C_block_item(e, 0))->d_name);
+ C_strlcpy(C_c_string(b), s, C_unfix(l));
+ return(C_fix(strlen(s)));
+}
+
+#else
+# define C_opendir(s,h) C_set_block_item(h, 0, (C_word) opendir(C_c_string(s)))
+# define C_foundfile(e,b,l) (C_strlcpy(C_c_string(b), ((struct dirent *) C_block_item(e, 0))->d_name, C_unfix(l)), C_fix(strlen(((struct dirent *) C_block_item(e, 0))->d_name)))
+#endif
+
#define C_readdir(h,e) C_set_block_item(e, 0, (C_word) readdir((DIR *)C_block_item(h, 0)))
#define C_closedir(h) (closedir((DIR *)C_block_item(h, 0)), C_SCHEME_UNDEFINED)
-#define C_foundfile(e,b,l) (C_strlcpy(C_c_string(b), ((struct dirent *) C_block_item(e, 0))->d_name, l), C_fix(strlen(((struct dirent *) C_block_item(e, 0))->d_name)))
static C_word C_u_i_symbolic_linkp(C_word path)
{
Trap