1 /* File: "os_files.c" */
3 /* Copyright (c) 1994-2011 by Marc Feeley, All Rights Reserved. */
6 * This module implements the operating system specific routines
7 * related to the file system.
10 #define ___INCLUDED_FROM_OS_FILES
11 #define ___VERSION 406003
20 /*---------------------------------------------------------------------------*/
23 ___files_module ___files_mod
=
27 #ifdef ___FILES_MODULE_INIT
33 /*---------------------------------------------------------------------------*/
35 #ifdef USE_CLASSIC_MACOS
38 /* String conversion utilities. */
40 ___HIDDEN Boolean c2pascal
51 StringPtr p1
= pstr
+1;
53 while (max_length
> 0 && *p2
!= '\0')
68 ___HIDDEN Boolean pascal2c
80 StringPtr p2
= pstr
+1;
94 #define DIR_SEPARATOR1 ':'
95 #define PARENT_HOP ":"
97 #define DIR_SEPARATOR(c)((c) == DIR_SEPARATOR1)
98 #define SEPARATOR(c)DIR_SEPARATOR(c)
101 ___HIDDEN OSErr make_ResolvedFSSpec
104 ConstStr255Param path
,
112 ConstStr255Param path
;
117 StringPtr start
= ___CAST(StringPtr
,path
+1);
118 StringPtr end
= start
+ path
[0];
119 StringPtr p1
= start
;
120 StringPtr p2
= name
+1;
134 while (p1
< end
&& DIR_SEPARATOR(*p1
)) /* copy leading ':'s */
136 while (p1
< end
&& !DIR_SEPARATOR(*p1
)) /* copy name that follows */
138 if (p1
< end
&& DIR_SEPARATOR(*p1
)) /* end with a ':' if folder */
139 *p2
++ = DIR_SEPARATOR1
;
140 name
[0] = p2
- (name
+1);
142 err
= FSMakeFSSpec (spec
->vRefNum
, spec
->parID
, name
, spec
);
143 if (err
== fnfErr
&& p1
== end
)
148 if ((err
= ResolveAliasFile (spec
, 1, &is_folder
, &is_aliased
)) != noErr
)
152 pb
.dirInfo
.ioNamePtr
= spec
->name
;
153 pb
.dirInfo
.ioVRefNum
= spec
->vRefNum
;
154 pb
.dirInfo
.ioDrDirID
= spec
->parID
;
155 pb
.dirInfo
.ioFDirIndex
= 0;
156 if ((err
= PBGetCatInfoSync (&pb
)) != noErr
)
158 spec
->parID
= pb
.hFileInfo
.ioDirID
;
169 ___HIDDEN OSErr ResolvedFSSpec_to_fullpath
180 StringPtr p
= result
+ sizeof(result
);
184 for (i
= spec
->name
[0]; i
> 0; i
--)
185 *--p
= spec
->name
[i
];
187 pb
.dirInfo
.ioNamePtr
= name
;
188 pb
.dirInfo
.ioVRefNum
= spec
->vRefNum
;
189 pb
.dirInfo
.ioDrParID
= spec
->parID
;
190 pb
.dirInfo
.ioFDirIndex
= -1;
194 pb
.dirInfo
.ioDrDirID
= pb
.dirInfo
.ioDrParID
;
195 if ((err
= PBGetCatInfoSync (&pb
)) != noErr
)
197 if (p
-name
[0]-1 < result
)
198 return bdNamErr
; /* file name is too long */
199 *--p
= DIR_SEPARATOR1
;
200 for (i
= name
[0]; i
> 0; i
--)
202 } while (pb
.dirInfo
.ioDrDirID
!= fsRtDirID
);
204 i
= result
+ sizeof(result
) - p
;
216 ___HIDDEN ___SCMOBJ path_expand_to_absolute
218 char *directory
,/******************* currently ignored*/
234 char tmp
[___PATH_MAX_LENGTH
+1];
241 /* "~~" or "~~:xxx..." */
251 if (path
[2]!='\0' && !DIR_SEPARATOR(path
[2]))
254 tilde_dir
= ___setup_params
.gambcdir
;
257 tilde_dir
= ___GAMBCDIR
;
259 tilde_dir
= ":Gambit-C";
264 while (*tilde_dir
!= '\0')
265 if (j
< ___PATH_MAX_LENGTH
)
267 tmp
[j
] = *tilde_dir
++;
273 while (path
[i
] != '\0')
274 if (j
< ___PATH_MAX_LENGTH
)
276 if (DIR_SEPARATOR(path
[i
]))
278 tmp
[j
++] = path
[i
++];
284 if (j
< ___PATH_MAX_LENGTH
)
285 tmp
[j
++] = DIR_SEPARATOR1
;
292 if (FindFolder (kOnSystemDisk
,
293 kPreferencesFolderType
,
300 else if (path
[1]!='\0' && !DIR_SEPARATOR(path
[1]))
302 /* "~user" or "~user:xxx..." */
304 goto ret
; /* no equivalent on Macintosh */
308 /* "~" or "~:xxx..." */
311 vol
= 0; /* use default volume and directory
312 (folder containing application) */
318 vol
= 0; /* use default volume and directory
319 (folder containing application) */
323 if (!c2pascal (path
, ppath
, 255) ||
324 make_ResolvedFSSpec (vol
, dir
, ppath
, &spec
) != noErr
||
325 ResolvedFSSpec_to_fullpath (&spec
, ppath
) != noErr
||
326 !pascal2c (ppath
, new_path
, max_length
))
337 ___HIDDEN OSErr copy_file_sectors
338 ___P((short src_refnum
,
351 count1
= sizeof (buf
);
352 err1
= FSRead (src_refnum
, &count1
, buf
);
353 if (err1
!= noErr
&& err1
!= eofErr
)
356 err2
= FSWrite (dst_refnum
, &count2
, buf
);
357 if (err2
!= noErr
|| count1
!= count2
)
359 } while (err1
!= eofErr
);
365 ___HIDDEN OSErr copy_file
366 ___P((FSSpec src_spec
,
374 short src_refnum
, dst_refnum
;
377 if (((err
= FSpDelete (&dst_spec
)) == noErr
|| err
== fnfErr
) &&
378 (err
= FSpGetFInfo (&src_spec
, &src_info
)) == noErr
&&
379 (err
= FSpCreate (&dst_spec
, 0x3f3f3f3f, 0x3f3f3f3f, 0)) == noErr
)
381 src_info
.fdFlags
= src_info
.fdFlags
& ~kHasBeenInited
;
382 if ((err
= FSpSetFInfo (&dst_spec
, &src_info
) == noErr
) &&
383 (err
= FSpOpenRF (&src_spec
, fsRdPerm
, &src_refnum
) == noErr
))
385 if ((err
= FSpOpenRF (&dst_spec
, fsWrPerm
, &dst_refnum
)) == noErr
)
387 err
= copy_file_sectors (src_refnum
, dst_refnum
);
388 err2
= FSClose (dst_refnum
);
392 err2
= FSClose (src_refnum
);
396 (err
= FSpOpenDF (&src_spec
, fsRdPerm
, &src_refnum
) == noErr
))
398 if ((err
= FSpOpenDF (&dst_spec
, fsWrPerm
, &dst_refnum
)) == noErr
)
400 err
= copy_file_sectors (src_refnum
, dst_refnum
);
401 err2
= FSClose (dst_refnum
);
405 err2
= FSClose (src_refnum
);
411 FSpDelete (&dst_spec
);
421 /*---------------------------------------------------------------------------*/
423 /* Filesystem path expansion. */
426 ___SCMOBJ ___os_path_homedir ___PVOID
430 ___UCS_2STRING cstr1
;
432 static ___UCS_2 cvar1
[] =
433 { 'H', 'O', 'M', 'E', '\0' };
435 if ((e
= ___getenv_UCS_2 (cvar1
, &cstr1
)) != ___FIX(___NO_ERR
))
441 if ((e
= ___UCS_2STRING_to_SCMOBJ
445 != ___FIX(___NO_ERR
))
448 ___release_scmobj (result
);
456 ___CHAR_TYPE(___PATH_CE_SELECT
) homedir
[___PATH_MAX_LENGTH
+1];
457 int len
= ___PATH_MAX_LENGTH
+1;
460 static ___CHAR_TYPE(___GETENV_CE_SELECT
) cvar2
[] =
461 { 'H', 'O', 'M', 'E', 'D', 'R', 'I', 'V', 'E', '\0' };
463 static ___CHAR_TYPE(___GETENV_CE_SELECT
) cvar3
[] =
464 { 'H', 'O', 'M', 'E', 'P', 'A', 'T', 'H', '\0' };
466 n
= GetEnvironmentVariable (cvar2
, homedir
, len
);
468 if (n
> 0 && n
< len
)
472 n
= GetEnvironmentVariable (cvar3
, homedir
+n
, len
);
474 if (n
> 0 && n
< len
)
476 if ((e
= ___NONNULLSTRING_to_SCMOBJ
480 ___CE(___PATH_CE_SELECT
)))
481 != ___FIX(___NO_ERR
))
484 ___release_scmobj (result
);
504 ___SCMOBJ ___os_path_gambcdir ___PVOID
511 #ifdef USE_GetModuleFileName
512 if (___setup_params
.gambcdir
== 0)
514 ___CHAR_TYPE(___PATH_CE_SELECT
) temp
[___PATH_MAX_LENGTH
+1];
517 n
= GetModuleFileName (NULL
, temp
, ___PATH_MAX_LENGTH
+1);
521 ___UCS_2STRING gambcdir
= 0;
522 /* remove filename */
523 *(_tcsrchr (temp
, '\\')) = 0;
524 /* remove bin subdirectory, if present */
525 cch
= _tcslen (temp
);
526 if (cch
> 7) /* e.g. C:\x\bin */
528 if (0 == _tcsicmp (temp
+cch
-4, _T("\\bin")))
535 gambcdir
= ___CAST(___UCS_2STRING
,
536 ___alloc_mem ((cch
+1) * sizeof (___UCS_2
)));
540 e
= ___FIX(___HEAP_OVERFLOW_ERR
);
546 _tcscpy (gambcdir
, temp
);
548 mbstowcs (gambcdir
, temp
, cch
);
549 gambcdir
[cch
] = '\0';
551 ___setup_params
.gambcdir
= gambcdir
;
559 if (___setup_params
.gambcdir
!= 0)
561 if ((e
= ___NONNULLUCS_2STRING_to_SCMOBJ
562 (___setup_params
.gambcdir
,
565 != ___FIX(___NO_ERR
))
568 ___release_scmobj (result
);
575 #define STRINGIFY1(x) #x
576 #define STRINGIFY2(x) STRINGIFY1(x)
579 #define ___GAMBCDIR "/usr/local/Gambit-C/" STRINGIFY2(___VERSION)
583 /* Will only be used if GetModuleFileName path fails */
584 #define ___GAMBCDIR "c:\\Gambit-C\\" STRINGIFY2(___VERSION)
587 #ifdef USE_CLASSIC_MACOS
588 #define ___GAMBCDIR ":Gambit-C:" STRINGIFY2(___VERSION)
593 if ((e
= ___NONNULLCHARSTRING_to_SCMOBJ
597 != ___FIX(___NO_ERR
))
600 ___release_scmobj (result
);
607 #ifndef ___GAMBCDIR_MAP_CE_SELECT
608 #define ___GAMBCDIR_MAP_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
611 #ifndef ___CONFIG_GAMBCDIR_MAP_CE_SELECT
612 #define ___CONFIG_GAMBCDIR_MAP_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
617 * TODO: the current implementation of the lookup duplicates the
618 * lookup logic because the configuration map and the map from the
619 * runtime options are not represented with the same string type. The
620 * proper approach would be to represent OS environment variables
621 * using UTF-8 strings, but this would require substantial changes.
625 ___HIDDEN
___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) gambcdir_map_lookup
626 ___P((___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) d
),
628 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) d
;)
630 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) dir
;
631 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) *p
= ___setup_params
.gambcdir_map
;
636 while ((dir
= *p
++) != 0)
649 else if ((dir
[i
] == '=') || (dir
[i
] != c
))
661 ___HIDDEN
___STRING_TYPE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
) config_gambcdir_map
[] =
663 #ifdef ___GAMBCDIR_BIN
664 "bin=" ___GAMBCDIR_BIN
,
666 #ifdef ___GAMBCDIR_DOC
667 "doc=" ___GAMBCDIR_DOC
,
669 #ifdef ___GAMBCDIR_INCLUDE
670 "include=" ___GAMBCDIR_INCLUDE
,
672 #ifdef ___GAMBCDIR_INFO
673 "info=" ___GAMBCDIR_INFO
,
675 #ifdef ___GAMBCDIR_LIB
676 "lib=" ___GAMBCDIR_LIB
,
678 #ifdef ___GAMBCDIR_SHARE
679 "share=" ___GAMBCDIR_SHARE
,
685 ___HIDDEN
___STRING_TYPE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
) config_gambcdir_map_lookup
686 ___P((___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) d
),
688 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) d
;)
690 ___STRING_TYPE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
) dir
;
691 ___STRING_TYPE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
) *p
= config_gambcdir_map
;
693 while ((dir
= *p
++) != 0)
706 else if ((dir
[i
] == '=') || (dir
[i
] != c
))
718 ___SCMOBJ ___os_path_gambcdir_map_lookup
719 ___P((___SCMOBJ dir
),
727 if ((e
= ___SCMOBJ_to_STRING
731 ___CE(___GAMBCDIR_MAP_CE_SELECT
),
733 != ___FIX(___NO_ERR
))
737 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) d
=
738 ___CAST(___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
),cdir
);
740 ___STRING_TYPE(___GAMBCDIR_MAP_CE_SELECT
) dir1
;
741 ___STRING_TYPE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
) dir2
;
743 if ((dir1
= gambcdir_map_lookup (d
)) != 0)
745 if ((e
= ___STRING_to_SCMOBJ
749 ___CE(___GAMBCDIR_MAP_CE_SELECT
)))
750 != ___FIX(___NO_ERR
))
753 ___release_scmobj (result
);
755 else if ((dir2
= config_gambcdir_map_lookup (d
)) != 0)
757 if ((e
= ___STRING_to_SCMOBJ
761 ___CE(___CONFIG_GAMBCDIR_MAP_CE_SELECT
)))
762 != ___FIX(___NO_ERR
))
765 ___release_scmobj (result
);
770 ___release_string (cdir
);
777 ___SCMOBJ ___os_path_normalize_directory
778 ___P((___SCMOBJ path
),
786 if ((e
= ___SCMOBJ_to_STRING
790 ___CE(___PATH_CE_SELECT
),
792 != ___FIX(___NO_ERR
))
796 ___STRING_TYPE(___PATH_CE_SELECT
) p
=
797 ___CAST(___STRING_TYPE(___PATH_CE_SELECT
),cpath
);
798 ___STRING_TYPE(___PATH_CE_SELECT
) dir
;
803 ___CHAR_TYPE(___PATH_CE_SELECT
) normalized_dir
[___PATH_MAX_LENGTH
+1+1];
804 ___FILE
*exist_check
;
806 dir
= normalized_dir
;
814 if (dir
== normalized_dir
|| dir
[-1] != '/')
819 dir
= normalized_dir
;
821 while (dir
[0] == '.' && dir
[1] == '/' && dir
[2] != '\0')
824 exist_check
= ___fopen (dir
, "r");
826 if (exist_check
== 0)
827 result
= fnf_or_err_code_from_errno ();
830 ___fclose (exist_check
);
832 if ((e
= ___NONNULLSTRING_to_SCMOBJ
836 ___CE(___PATH_CE_SELECT
)))
837 != ___FIX(___NO_ERR
))
840 ___release_scmobj (result
);
848 ___CHAR_TYPE(___PATH_CE_SELECT
) old_dir
[___PATH_MAX_LENGTH
+1+1];
849 ___CHAR_TYPE(___PATH_CE_SELECT
) normalized_dir
[___PATH_MAX_LENGTH
+1+1];
851 dir
= normalized_dir
;
853 if (getcwd (old_dir
, ___PATH_MAX_LENGTH
) == 0)
854 e
= err_code_from_errno ();
862 e
= err_code_from_errno ();
865 if (getcwd (normalized_dir
, ___PATH_MAX_LENGTH
) == 0)
866 e
= err_code_from_errno ();
868 e
= ___FIX(___NO_ERR
);
870 chdir (old_dir
); /* ignore error */
874 if (e
!= ___FIX(___NO_ERR
))
883 if (p
== dir
|| p
[-1] != '/')
889 if ((e
= ___NONNULLSTRING_to_SCMOBJ
893 ___CE(___PATH_CE_SELECT
)))
894 != ___FIX(___NO_ERR
))
897 ___release_scmobj (result
);
904 ___CHAR_TYPE(___PATH_CE_SELECT
) old_dir
[___PATH_MAX_LENGTH
+1+1];
905 ___CHAR_TYPE(___PATH_CE_SELECT
) normalized_dir
[___PATH_MAX_LENGTH
+1+1];
908 dir
= normalized_dir
;
910 n
= GetCurrentDirectory (___PATH_MAX_LENGTH
+1,
913 if (n
< 1 || n
> ___PATH_MAX_LENGTH
)
914 e
= err_code_from_GetLastError ();
921 if (!SetCurrentDirectory (p
))
922 e
= err_code_from_GetLastError ();
925 n
= GetCurrentDirectory (___PATH_MAX_LENGTH
+1,
928 if (n
< 1 || n
> ___PATH_MAX_LENGTH
)
929 e
= err_code_from_GetLastError ();
931 SetCurrentDirectory (old_dir
); /* ignore error */
936 if (e
!= ___FIX(___NO_ERR
))
945 if (p
== dir
|| (p
[-1] != '\\' && p
[-1] != '/'))
951 if ((e
= ___NONNULLSTRING_to_SCMOBJ
955 ___CE(___PATH_CE_SELECT
)))
956 != ___FIX(___NO_ERR
))
959 ___release_scmobj (result
);
964 ___release_string (cpath
);
971 /*---------------------------------------------------------------------------*/
973 /* File system operations. */
976 ___SCMOBJ ___os_create_directory
977 ___P((___SCMOBJ path
,
988 #ifndef USE_CreateDirectory
990 e
= ___FIX(___UNIMPL_ERR
);
997 #define ___CREATE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
999 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1003 ___CE(___CREATE_DIRECTORY_PATH_CE_SELECT
),
1005 == ___FIX(___NO_ERR
))
1007 if (mkdir (___CAST(___STRING_TYPE(___CREATE_DIRECTORY_PATH_CE_SELECT
),cpath
), ___INT(mode
)) < 0)
1008 e
= fnf_or_err_code_from_errno ();
1009 ___release_string (cpath
);
1014 #ifdef USE_CreateDirectory
1017 #define ___CREATE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1019 #define ___CREATE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1022 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1026 ___CE(___CREATE_DIRECTORY_PATH_CE_SELECT
),
1028 == ___FIX(___NO_ERR
))
1030 if (!CreateDirectory
1031 (___CAST(___STRING_TYPE(___CREATE_DIRECTORY_PATH_CE_SELECT
),
1034 e
= fnf_or_err_code_from_GetLastError ();
1035 ___release_string (cpath
);
1044 ___SCMOBJ ___os_create_fifo
1045 ___P((___SCMOBJ path
,
1057 e
= ___FIX(___UNIMPL_ERR
);
1063 #define ___CREATE_FIFO_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1065 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1069 ___CE(___CREATE_FIFO_PATH_CE_SELECT
),
1071 == ___FIX(___NO_ERR
))
1073 if (mkfifo (___CAST(___STRING_TYPE(___CREATE_FIFO_PATH_CE_SELECT
),cpath
), ___INT(mode
)) < 0)
1074 e
= fnf_or_err_code_from_errno ();
1075 ___release_string (cpath
);
1084 ___SCMOBJ ___os_create_link
1085 ___P((___SCMOBJ path1
,
1098 e
= ___FIX(___UNIMPL_ERR
);
1104 #define ___CREATE_LINK_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1106 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1110 ___CE(___CREATE_LINK_PATH_CE_SELECT
),
1112 == ___FIX(___NO_ERR
))
1114 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1118 ___CE(___CREATE_LINK_PATH_CE_SELECT
),
1120 == ___FIX(___NO_ERR
))
1122 if (link (___CAST(___STRING_TYPE(___CREATE_LINK_PATH_CE_SELECT
),cpath1
),
1123 ___CAST(___STRING_TYPE(___CREATE_LINK_PATH_CE_SELECT
),cpath2
))
1125 e
= fnf_or_err_code_from_errno ();
1126 ___release_string (cpath2
);
1128 ___release_string (cpath1
);
1137 ___SCMOBJ ___os_create_symbolic_link
1138 ___P((___SCMOBJ path1
,
1151 e
= ___FIX(___UNIMPL_ERR
);
1157 #define ___CREATE_SYMLINK_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1159 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1163 ___CE(___CREATE_SYMLINK_PATH_CE_SELECT
),
1165 == ___FIX(___NO_ERR
))
1167 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1171 ___CE(___CREATE_SYMLINK_PATH_CE_SELECT
),
1173 == ___FIX(___NO_ERR
))
1175 if (symlink (___CAST(___STRING_TYPE(___CREATE_SYMLINK_PATH_CE_SELECT
),cpath1
),
1176 ___CAST(___STRING_TYPE(___CREATE_SYMLINK_PATH_CE_SELECT
),cpath2
))
1178 e
= fnf_or_err_code_from_errno ();
1179 ___release_string (cpath2
);
1181 ___release_string (cpath1
);
1190 ___SCMOBJ ___os_delete_directory
1191 ___P((___SCMOBJ path
),
1199 #ifndef USE_RemoveDirectory
1201 e
= ___FIX(___UNIMPL_ERR
);
1208 #define ___DELETE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1210 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1214 ___CE(___DELETE_DIRECTORY_PATH_CE_SELECT
),
1216 == ___FIX(___NO_ERR
))
1218 if (rmdir (___CAST(___STRING_TYPE(___DELETE_DIRECTORY_PATH_CE_SELECT
),cpath
)) < 0)
1219 e
= fnf_or_err_code_from_errno ();
1220 ___release_string (cpath
);
1225 #ifdef USE_RemoveDirectory
1228 #define ___DELETE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1230 #define ___DELETE_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1233 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1237 ___CE(___DELETE_DIRECTORY_PATH_CE_SELECT
),
1239 == ___FIX(___NO_ERR
))
1241 if (!RemoveDirectory
1242 (___CAST(___STRING_TYPE(___DELETE_DIRECTORY_PATH_CE_SELECT
),
1244 e
= fnf_or_err_code_from_GetLastError ();
1245 ___release_string (cpath
);
1254 ___SCMOBJ ___os_set_current_directory
1255 ___P((___SCMOBJ path
),
1263 #ifndef USE_SetCurrentDirectory
1265 e
= ___FIX(___UNIMPL_ERR
);
1272 #define ___SET_CURRENT_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1274 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1278 ___CE(___SET_CURRENT_DIRECTORY_PATH_CE_SELECT
),
1280 == ___FIX(___NO_ERR
))
1282 if (chdir (___CAST(___STRING_TYPE(___SET_CURRENT_DIRECTORY_PATH_CE_SELECT
),cpath
)) < 0)
1283 e
= fnf_or_err_code_from_errno ();
1284 ___release_string (cpath
);
1289 #ifdef USE_SetCurrentDirectory
1292 #define ___SET_CURRENT_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1294 #define ___SET_CURRENT_DIRECTORY_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1297 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1301 ___CE(___SET_CURRENT_DIRECTORY_PATH_CE_SELECT
),
1303 == ___FIX(___NO_ERR
))
1305 if (!SetCurrentDirectory
1306 (___CAST(___STRING_TYPE(___SET_CURRENT_DIRECTORY_PATH_CE_SELECT
),
1308 e
= fnf_or_err_code_from_GetLastError ();
1309 ___release_string (cpath
);
1318 ___SCMOBJ ___os_rename_file
1319 ___P((___SCMOBJ path1
,
1331 #ifndef USE_MoveFile
1333 e
= ___FIX(___UNIMPL_ERR
);
1340 #define ___RENAME_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1342 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1346 ___CE(___RENAME_FILE_PATH_CE_SELECT
),
1348 == ___FIX(___NO_ERR
))
1350 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1354 ___CE(___RENAME_FILE_PATH_CE_SELECT
),
1356 == ___FIX(___NO_ERR
))
1358 if (rename (___CAST(___STRING_TYPE(___RENAME_FILE_PATH_CE_SELECT
),cpath1
),
1359 ___CAST(___STRING_TYPE(___RENAME_FILE_PATH_CE_SELECT
),cpath2
))
1361 e
= fnf_or_err_code_from_errno ();
1362 ___release_string (cpath2
);
1364 ___release_string (cpath1
);
1372 #define ___RENAME_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1374 #define ___RENAME_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1377 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1381 ___CE(___RENAME_FILE_PATH_CE_SELECT
),
1383 == ___FIX(___NO_ERR
))
1385 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1389 ___CE(___RENAME_FILE_PATH_CE_SELECT
),
1391 == ___FIX(___NO_ERR
))
1394 (___CAST(___STRING_TYPE(___RENAME_FILE_PATH_CE_SELECT
),
1396 ___CAST(___STRING_TYPE(___RENAME_FILE_PATH_CE_SELECT
),
1398 e
= fnf_or_err_code_from_GetLastError ();
1399 ___release_string (cpath2
);
1401 ___release_string (cpath1
);
1410 ___SCMOBJ ___os_copy_file
1411 ___P((___SCMOBJ path1
,
1423 #ifndef USE_CopyFile
1425 e
= ___FIX(___UNIMPL_ERR
);
1432 #define ___COPY_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1434 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1438 ___CE(___COPY_FILE_PATH_CE_SELECT
),
1440 == ___FIX(___NO_ERR
))
1442 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1446 ___CE(___COPY_FILE_PATH_CE_SELECT
),
1448 == ___FIX(___NO_ERR
))
1453 if ((fd1
= open (___CAST(___STRING_TYPE(___COPY_FILE_PATH_CE_SELECT
),
1460 e
= fnf_or_err_code_from_errno ();
1463 if ((fd2
= open (___CAST(___STRING_TYPE(___COPY_FILE_PATH_CE_SELECT
),
1468 O_WRONLY
|O_CREAT
|O_EXCL
,
1470 e
= fnf_or_err_code_from_errno ();
1479 nr
= read (fd1
, buffer
, sizeof (buffer
));
1484 if (nr
< 0 || (nw
= write (fd2
, buffer
, nr
)) < 0)
1486 e
= err_code_from_errno ();
1492 e
= ___FIX(___UNKNOWN_ERR
);
1497 if (close (fd2
) < 0 && e
!= ___FIX(___NO_ERR
))
1498 e
= err_code_from_errno ();
1501 if (close (fd1
) < 0 && e
!= ___FIX(___NO_ERR
))
1503 e
= err_code_from_errno ();
1504 unlink (___CAST(___STRING_TYPE(___COPY_FILE_PATH_CE_SELECT
),
1508 ___release_string (cpath2
);
1510 ___release_string (cpath1
);
1518 #define ___COPY_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1520 #define ___COPY_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1523 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1527 ___CE(___COPY_FILE_PATH_CE_SELECT
),
1529 == ___FIX(___NO_ERR
))
1531 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1535 ___CE(___COPY_FILE_PATH_CE_SELECT
),
1537 == ___FIX(___NO_ERR
))
1540 (___CAST(___STRING_TYPE(___COPY_FILE_PATH_CE_SELECT
),
1542 ___CAST(___STRING_TYPE(___COPY_FILE_PATH_CE_SELECT
),
1545 e
= fnf_or_err_code_from_GetLastError ();
1546 ___release_string (cpath2
);
1548 ___release_string (cpath1
);
1557 ___SCMOBJ ___os_delete_file
1558 ___P((___SCMOBJ path
),
1566 #ifndef USE_DeleteFile
1568 e
= ___FIX(___UNIMPL_ERR
);
1575 #define ___DELETE_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1577 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1581 ___CE(___DELETE_FILE_PATH_CE_SELECT
),
1583 == ___FIX(___NO_ERR
))
1585 if (unlink (___CAST(___STRING_TYPE(___DELETE_FILE_PATH_CE_SELECT
),cpath
))
1587 e
= fnf_or_err_code_from_errno ();
1588 ___release_string (cpath
);
1593 #ifdef USE_DeleteFile
1596 #define ___DELETE_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) ucs2
1598 #define ___DELETE_FILE_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native) native
1601 if ((e
= ___SCMOBJ_to_NONNULLSTRING
1605 ___CE(___DELETE_FILE_PATH_CE_SELECT
),
1607 == ___FIX(___NO_ERR
))
1610 (___CAST(___STRING_TYPE(___DELETE_FILE_PATH_CE_SELECT
),
1612 e
= fnf_or_err_code_from_GetLastError ();
1613 ___release_string (cpath
);
1622 /*---------------------------------------------------------------------------*/
1624 /* File system module initialization/finalization. */
1627 ___SCMOBJ ___setup_files_module ___PVOID
1629 if (!___files_mod
.setup
)
1631 ___files_mod
.setup
= 1;
1632 return ___FIX(___NO_ERR
);
1635 return ___FIX(___UNKNOWN_ERR
);
1639 void ___cleanup_files_module ___PVOID
1641 if (___files_mod
.setup
)
1643 ___files_mod
.setup
= 0;
1648 /*---------------------------------------------------------------------------*/