~ 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