Eliminate several calls to the C library in favor of native Win32 API
authorChris Hanson <org/chris-hanson/cph>
Sat, 23 Aug 1997 02:52:10 +0000 (02:52 +0000)
committerChris Hanson <org/chris-hanson/cph>
Sat, 23 Aug 1997 02:52:10 +0000 (02:52 +0000)
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.

v7/src/microcode/ntapi.h
v7/src/microcode/ntfs.c
v7/src/microcode/prntfs.c

index ceabfab520ff3998a64b1dd39090afc78e21fec5..3e5a4403cfc6fa65fa2e2ad20d34769dca566fcb 100644 (file)
@@ -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",
index 6b160fb4d3ab52213dd2086a212c1add0fda954e..b2f3fbe0dc9fbc963cbd389c7997d420000d2656 100644 (file)
@@ -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 <string.h>
 #include "outf.h"
 \f
-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));
+}
+\f
 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));
 }
 \f
 typedef struct nt_dir_struct
index 72847279bfb5b14a3ce2f7671206bfc0ba9b05ce..ff98fc24b9c404767b6a5dfc0280744a16901f38 100644 (file)
@@ -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 <sys/utime.h>
 #include <memory.h>
@@ -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))
-\f
-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));
-}
 \f
 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);
 }
 \f
@@ -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);