~ 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