From: Chris Hanson Date: Sat, 23 Aug 1997 02:52:10 +0000 (+0000) Subject: Eliminate several calls to the C library in favor of native Win32 API X-Git-Tag: 20090517-FFI~5023 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=1870930cb5afc0cd700ebb257284aa9d7be1b4c1;p=mit-scheme.git Eliminate several calls to the C library in favor of native Win32 API calls. This was started to work around a bug in the Watcom C library, but is generally desirable to eliminate unnecessary dependencies on the C library. The bug that started this is that FILE-DIRECTORY? returned #F on directories with the FILE_ATTRIBUTE_ARCHIVE bit set. --- diff --git a/v7/src/microcode/ntapi.h b/v7/src/microcode/ntapi.h index ceabfab52..3e5a4403c 100644 --- a/v7/src/microcode/ntapi.h +++ b/v7/src/microcode/ntapi.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntapi.h,v 1.2 1997/01/05 23:37:21 cph Exp $ +$Id: ntapi.h,v 1.3 1997/08/23 02:52:10 cph Exp $ Copyright (c) 1997 Massachusetts Institute of Technology @@ -42,6 +42,8 @@ enum syscall_names apicall_CloseHandle, apicall_CopyFile, apicall_CreateFile, + apicall_CreateDirectory, + apicall_DeleteFile, apicall_FindFirstFile, apicall_GetFileAttributes, apicall_GetFileInformationByHandle, @@ -49,6 +51,7 @@ enum syscall_names apicall_GetFileTime, apicall_MoveFile, apicall_MsgWaitForMultipleObjects, + apicall_RemoveDirectory, apicall_SetCurrentDirectory, apicall_SetFileAttributes, apicall_SetFilePointer, @@ -802,6 +805,8 @@ static char * syscall_names_table [] = "CLOSE-HANDLE", "COPY-FILE", "CREATE-FILE", + "CREATE-DIRECTORY", + "DELETE-FILE", "FIND-FIRST-FILE", "GET-FILE-ATTRIBUTES", "GET-FILE-INFORMATION-BY-HANDLE", @@ -809,6 +814,7 @@ static char * syscall_names_table [] = "GET-FILE-TIME", "MOVE-FILE", "MSG-WAIT-FOR-MULTIPLE-OBJECTS", + "REMOVE-DIRECTORY", "SET-CURRENT-DIRECTORY", "SET-FILE-ATTRIBUTES", "SET-FILE-POINTER", diff --git a/v7/src/microcode/ntfs.c b/v7/src/microcode/ntfs.c index 6b160fb4d..b2f3fbe0d 100644 --- a/v7/src/microcode/ntfs.c +++ b/v7/src/microcode/ntfs.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntfs.c,v 1.15 1997/06/26 06:59:31 cph Exp $ +$Id: ntfs.c,v 1.16 1997/08/23 02:51:59 cph Exp $ Copyright (c) 1992-97 Massachusetts Institute of Technology @@ -33,57 +33,135 @@ promotional, or sales literature without prior written consent from MIT in each case. */ #include "nt.h" -#include "osfs.h" +#include "ntfs.h" #include #include "outf.h" -int -DEFUN (NT_read_file_status, (name, s), - CONST char * name AND - struct stat * s) -{ char filename[128]; +static HANDLE create_file_for_info (const char *); - nt_pathname_as_filename (name, filename); +static enum get_file_info_result get_file_info_from_dir + (const char *, BY_HANDLE_FILE_INFORMATION *); - while ((stat (filename, s)) < 0) +enum get_file_info_result +NT_get_file_info (const char * namestring, BY_HANDLE_FILE_INFORMATION * info) +{ + HANDLE hfile = (create_file_for_info (namestring)); + if (hfile == INVALID_HANDLE_VALUE) { - if (errno == EINTR) - continue; - if ((errno == ENOENT) || (errno == ENOTDIR)) - return (0); - NT_error_unix_call (errno, syscall_stat); + DWORD code = (GetLastError ()); + if (STAT_NOT_FOUND_P (code)) + return (gfi_not_found); + if (STAT_NOT_ACCESSIBLE_P (code)) + return (get_file_info_from_dir (namestring, info)); + NT_error_api_call (code, apicall_CreateFile); } - return (1); + if (!GetFileInformationByHandle (hfile, info)) + { + DWORD code = (GetLastError ()); + (void) CloseHandle (hfile); + if (STAT_NOT_FOUND_P (code)) + return (gfi_not_found); + if (STAT_NOT_ACCESSIBLE_P (code)) + return (gfi_not_accessible); + NT_error_api_call (code, apicall_GetFileInformationByHandle); + } + NT_close_file_handle (hfile); + return (gfi_ok); } +/* Incredible kludge. Some files (e.g. \pagefile.sys) cannot be + accessed by the usual technique, but much of the same information + is available by reading the directory. More M$ bullshit. */ +static enum get_file_info_result +get_file_info_from_dir (const char * namestring, + BY_HANDLE_FILE_INFORMATION * info) +{ + WIN32_FIND_DATA fi; + HANDLE handle = (FindFirstFile (namestring, (&fi))); + if (handle == INVALID_HANDLE_VALUE) + { + DWORD code = (GetLastError ()); + if (STAT_NOT_FOUND_P (code)) + return (gfi_not_found); + if (STAT_NOT_ACCESSIBLE_P (code)) + return (gfi_not_accessible); + NT_error_api_call (code, apicall_FindFirstFile); + } + FindClose (handle); + (info -> dwFileAttributes) = (fi . dwFileAttributes); + (info -> ftCreationTime) = (fi . ftCreationTime); + (info -> ftLastAccessTime) = (fi . ftLastAccessTime); + (info -> ftLastWriteTime) = (fi . ftLastWriteTime); + (info -> dwVolumeSerialNumber) = 0; + (info -> nFileSizeHigh) = (fi . nFileSizeHigh); + (info -> nFileSizeLow) = (fi . nFileSizeLow); + (info -> nNumberOfLinks) = 1; + (info -> nFileIndexHigh) = 0; + (info -> nFileIndexLow) = 0; + return (gfi_ok); +} + +static HANDLE +create_file_for_info (const char * namestring) +{ + return + (CreateFile (namestring, + 0, + (FILE_SHARE_READ | FILE_SHARE_WRITE), + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL)); +} + +void +NT_close_file_handle (HANDLE hfile) +{ + STD_BOOL_API_CALL (CloseHandle, (hfile)); +} + enum file_existence DEFUN (OS_file_existence_test, (name), CONST char * name) { - struct stat s; - char filename[128]; - - nt_pathname_as_filename (name, filename); - return (((stat (filename, (&s))) < 0) ? file_doesnt_exist : file_does_exist); + BY_HANDLE_FILE_INFORMATION info; + return + (((NT_get_file_info (name, (&info))) == gfi_ok) + ? file_does_exist + : file_doesnt_exist); } +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 + int DEFUN (OS_file_access, (name, mode), CONST char * name AND unsigned int mode) { - char filename[128]; - - nt_pathname_as_filename (name, filename); - return ((access (filename, mode)) == 0); + BY_HANDLE_FILE_INFORMATION info; + if ((NT_get_file_info (name, (&info))) != gfi_ok) + return (0); + if (((mode & W_OK) != 0) + && (((info . dwFileAttributes) & FILE_ATTRIBUTE_READONLY) != 0)) + return (0); + if (((mode & X_OK) != 0) + && (((info . dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) == 0)) + { + const char * extension = (strrchr (name, '.')); + if (! (((stricmp (extension, ".exe")) == 0) + || ((stricmp (extension, ".com")) == 0) + || ((stricmp (extension, ".bat")) == 0))) + return (0); + } + return (1); } int DEFUN (OS_file_directory_p, (name), CONST char * name) { - struct stat s; - char filename[128]; - - nt_pathname_as_filename(name, filename); - return (((stat (filename, (&s))) == 0) - && (((s . st_mode) & S_IFMT) == S_IFDIR)); + BY_HANDLE_FILE_INFORMATION info; + return + (((NT_get_file_info (name, (&info))) == gfi_ok) + && (((info . dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) != 0)); } CONST char * @@ -119,7 +197,7 @@ void DEFUN (OS_file_remove, (name), CONST char * name) { guarantee_writable (name, 1); - STD_VOID_UNIX_CALL (unlink, (name)); + STD_BOOL_API_CALL (DeleteFile, (name)); } void @@ -171,13 +249,13 @@ DEFUN (OS_file_link_soft, (from_name, to_name), void DEFUN (OS_directory_make, (name), CONST char * name) { - STD_VOID_UNIX_CALL (mkdir, (name)); + STD_BOOL_API_CALL (CreateDirectory, (name, 0)); } void DEFUN (OS_directory_delete, (name), CONST char * name) { - STD_VOID_UNIX_CALL (rmdir, (name)); + STD_BOOL_API_CALL (RemoveDirectory, (name)); } typedef struct nt_dir_struct diff --git a/v7/src/microcode/prntfs.c b/v7/src/microcode/prntfs.c index 72847279b..ff98fc24b 100644 --- a/v7/src/microcode/prntfs.c +++ b/v7/src/microcode/prntfs.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: prntfs.c,v 1.12 1997/06/19 05:17:14 cph Exp $ +$Id: prntfs.c,v 1.13 1997/08/23 02:52:05 cph Exp $ Copyright (c) 1993-97 Massachusetts Institute of Technology @@ -32,13 +32,12 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ -/* Unix-specific file-system primitives. */ -/* DOS Imitation */ +/* NT-specific file-system primitives. */ #include "scheme.h" #include "prims.h" #include "nt.h" -#include "osfs.h" +#include "ntfs.h" #include #include @@ -55,100 +54,6 @@ static void EXFUN (protect_fd, (int fd)); #ifndef FILE_TOUCH_OPEN_TRIES #define FILE_TOUCH_OPEN_TRIES 5 #endif - -#define STAT_NOT_FOUND_P(code) \ - (((code) == ERROR_FILE_NOT_FOUND) \ - || ((code) == ERROR_PATH_NOT_FOUND)) - -#define STAT_NOT_ACCESSIBLE_P(code) \ - (((code) == ERROR_ACCESS_DENIED) \ - || ((code) == ERROR_SHARING_VIOLATION)) - -static HANDLE create_file_for_info (const char *); -static void close_file_handle (HANDLE); - -enum get_file_info_result { gfi_ok, gfi_not_found, gfi_not_accessible }; - -static enum get_file_info_result get_file_info_from_dir - (const char *, BY_HANDLE_FILE_INFORMATION *); - -static enum get_file_info_result -get_file_info (const char * namestring, BY_HANDLE_FILE_INFORMATION * info) -{ - HANDLE hfile = (create_file_for_info (namestring)); - if (hfile == INVALID_HANDLE_VALUE) - { - DWORD code = (GetLastError ()); - if (STAT_NOT_FOUND_P (code)) - return (gfi_not_found); - if (STAT_NOT_ACCESSIBLE_P (code)) - return (get_file_info_from_dir (namestring, info)); - NT_error_api_call (code, apicall_CreateFile); - } - if (!GetFileInformationByHandle (hfile, info)) - { - DWORD code = (GetLastError ()); - (void) CloseHandle (hfile); - if (STAT_NOT_FOUND_P (code)) - return (gfi_not_found); - if (STAT_NOT_ACCESSIBLE_P (code)) - return (gfi_not_accessible); - NT_error_api_call (code, apicall_GetFileInformationByHandle); - } - close_file_handle (hfile); - return (gfi_ok); -} - -/* Incredible kludge. Some files (e.g. \pagefile.sys) cannot be - accessed by the usual technique, but much of the same information - is available by reading the directory. More M$ bullshit. */ -static enum get_file_info_result -get_file_info_from_dir (const char * namestring, - BY_HANDLE_FILE_INFORMATION * info) -{ - WIN32_FIND_DATA fi; - HANDLE handle = (FindFirstFile (namestring, (&fi))); - if (handle == INVALID_HANDLE_VALUE) - { - DWORD code = (GetLastError ()); - if (STAT_NOT_FOUND_P (code)) - return (gfi_not_found); - if (STAT_NOT_ACCESSIBLE_P (code)) - return (gfi_not_accessible); - NT_error_api_call (code, apicall_FindFirstFile); - } - FindClose (handle); - (info -> dwFileAttributes) = (fi . dwFileAttributes); - (info -> ftCreationTime) = (fi . ftCreationTime); - (info -> ftLastAccessTime) = (fi . ftLastAccessTime); - (info -> ftLastWriteTime) = (fi . ftLastWriteTime); - (info -> dwVolumeSerialNumber) = 0; - (info -> nFileSizeHigh) = (fi . nFileSizeHigh); - (info -> nFileSizeLow) = (fi . nFileSizeLow); - (info -> nNumberOfLinks) = 1; - (info -> nFileIndexHigh) = 0; - (info -> nFileIndexLow) = 0; - return (gfi_ok); -} - -static HANDLE -create_file_for_info (const char * namestring) -{ - return - (CreateFile (namestring, - 0, - (FILE_SHARE_READ | FILE_SHARE_WRITE), - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL)); -} - -static void -close_file_handle (HANDLE hfile) -{ - STD_BOOL_API_CALL (CloseHandle, (hfile)); -} static double ut_zero = 0.0; @@ -199,7 +104,7 @@ DEFINE_PRIMITIVE ("FILE-MODES", Prim_file_modes, 1, 1, { BY_HANDLE_FILE_INFORMATION info; PRIMITIVE_HEADER (1); - switch (get_file_info ((STRING_ARG (1)), (&info))) + switch (NT_get_file_info ((STRING_ARG (1)), (&info))) { case gfi_ok: PRIMITIVE_RETURN @@ -227,7 +132,7 @@ DEFINE_PRIMITIVE ("FILE-MOD-TIME", Prim_file_mod_time, 1, 1, 0) { BY_HANDLE_FILE_INFORMATION info; PRIMITIVE_HEADER (1); - switch (get_file_info ((STRING_ARG (1)), (&info))) + switch (NT_get_file_info ((STRING_ARG (1)), (&info))) { case gfi_ok: PRIMITIVE_RETURN @@ -280,7 +185,7 @@ The file must exist and you must be the owner.") } if (disable_ro) STD_BOOL_API_CALL (SetFileAttributes, (filename, attributes)); - close_file_handle (hfile); + NT_close_file_handle (hfile); PRIMITIVE_RETURN (UNSPECIFIC); } @@ -366,7 +271,7 @@ the result is #F.") BY_HANDLE_FILE_INFORMATION info; PRIMITIVE_HEADER (1); Primitive_GC_If_Needed (MAX_ATTRIBUTES_ALLOCATION); - switch (get_file_info ((STRING_ARG (1)), (&info))) + switch (NT_get_file_info ((STRING_ARG (1)), (&info))) { case gfi_not_found: PRIMITIVE_RETURN (SHARP_F);