XEmacs 21.2.24 "Hecate".
[chise/xemacs-chise.git.1] / src / nt.c
index b7b0362..0c99c25 100644 (file)
--- a/src/nt.c
+++ b/src/nt.c
@@ -34,6 +34,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "systime.h"
 #include "syssignal.h"
 #include "sysproc.h"
+#include "sysfile.h"
 
 #include <ctype.h>
 #include <direct.h>
@@ -42,13 +43,25 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include <io.h>
 #include <pwd.h>
 #include <signal.h>
-#include <stddef.h> /* for offsetof */
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 
 #include <windows.h>
+#ifndef __MINGW32__
 #include <mmsystem.h>
+#else
+typedef void (CALLBACK TIMECALLBACK)(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
+
+typedef TIMECALLBACK FAR *LPTIMECALLBACK;
+DWORD WINAPI timeGetTime(void);
+MMRESULT WINAPI timeSetEvent(UINT uDelay, UINT uResolution,
+    LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);
+MMRESULT WINAPI timeKillEvent(UINT uTimerID);
+MMRESULT WINAPI timeGetDevCaps(TIMECAPS* ptc, UINT cbtc);
+MMRESULT WINAPI timeBeginPeriod(UINT uPeriod);
+MMRESULT WINAPI timeEndPeriod(UINT uPeriod);
+#endif
 
 #include "nt.h"
 #include <sys/dir.h>
@@ -118,13 +131,13 @@ static struct passwd the_passwd =
   the_passwd_shell,
 };
 
-int 
+uid_t
 getuid () 
 { 
   return the_passwd.pw_uid;
 }
 
-int 
+uid_t 
 geteuid () 
 { 
   /* I could imagine arguing for checking to see whether the user is
@@ -133,20 +146,20 @@ geteuid ()
   return getuid (); 
 }
 
-int 
+gid_t
 getgid () 
 { 
   return the_passwd.pw_gid;
 }
 
-int 
+gid_t
 getegid () 
 { 
   return getgid ();
 }
 
 struct passwd *
-getpwuid (int uid)
+getpwuid (uid_t uid)
 {
   if (uid == the_passwd.pw_uid)
     return &the_passwd;
@@ -533,7 +546,6 @@ nt_get_resource (key, lpdwtype)
   LPBYTE lpvalue;
   HKEY hrootkey = NULL;
   DWORD cbData;
-  BOOL ok = FALSE;
   
   /* Check both the current user and the local machine to see if 
      we have any resources.  */
@@ -596,7 +608,9 @@ init_environment ()
       "EMACSLOCKDIR",
       "INFOPATH"
     };
-
+#ifdef HEAP_IN_DATA
+    cache_system_info ();
+#endif
     for (i = 0; i < countof (env_vars); i++) 
       {
        if (!getenv (env_vars[i]) &&
@@ -942,7 +956,7 @@ map_win32_filename (const char * name, const char ** pPath)
   static char shortname[MAX_PATH];
   char * str = shortname;
   char c;
-  char * path;
+  const char * path;
   const char * save_name = name;
 
   if (is_fat_volume (name, &path)) /* truncate to 8.3 */
@@ -1052,7 +1066,7 @@ opendir (const char *filename)
   /* Opening is done by FindFirstFile.  However, a read is inherent to
      this operation, so we defer the open until read time.  */
 
-  if (!(dirp = (DIR *) xmalloc (sizeof (DIR))))
+  if (!(dirp = xnew_and_zero(DIR)))
     return NULL;
   if (dir_find_handle != INVALID_HANDLE_VALUE)
     return NULL;
@@ -1077,7 +1091,7 @@ closedir (DIR *dirp)
       FindClose (dir_find_handle);
       dir_find_handle = INVALID_HANDLE_VALUE;
     }
-  xfree ((char *) dirp);
+  xfree (dirp);
 }
 
 struct direct *
@@ -1169,7 +1183,7 @@ sys_rename (const char * oldname, const char * newname)
        return -1;
     }
 
-  /* Emulate Unix behaviour - newname is deleted if it already exists
+  /* Emulate Unix behavior - newname is deleted if it already exists
      (at least if it is a file; don't do this for directories).
      However, don't do this if we are just changing the case of the file
      name - we will end up deleting the file we are trying to rename!  */
@@ -1288,7 +1302,7 @@ generate_inode_val (const char * name)
   unsigned hash;
 
   /* Get the truly canonical filename, if it exists.  (Note: this
-     doesn't resolve aliasing due to subst commands, or recognise hard
+     doesn't resolve aliasing due to subst commands, or recognize hard
      links.  */
   if (!win32_get_long_filename ((char *)name, fullname, MAX_PATH))
     abort ();
@@ -1301,6 +1315,40 @@ generate_inode_val (const char * name)
 
 #endif
 
+/* Since stat is encapsulated on Windows NT, we need to encapsulate
+   the equally broken fstat as well. */
+int
+fstat (int handle, struct stat *buffer)
+{
+  int ret;
+  BY_HANDLE_FILE_INFORMATION lpFileInfo;
+  /* Initialize values */
+  buffer->st_mode = 0;
+  buffer->st_size = 0;
+  buffer->st_dev = 0;
+  buffer->st_rdev = 0;
+  buffer->st_atime = 0;
+  buffer->st_ctime = 0;
+  buffer->st_mtime = 0;
+  buffer->st_nlink = 0;
+  ret = GetFileInformationByHandle((HANDLE) handle, &lpFileInfo);
+  if (!ret)
+    {
+      return -1;
+    }
+  else
+    {
+      buffer->st_mtime = convert_time (lpFileInfo.ftLastWriteTime);
+      buffer->st_atime = convert_time (lpFileInfo.ftLastAccessTime);
+      if (buffer->st_atime == 0) buffer->st_atime = buffer->st_mtime;
+      buffer->st_ctime = convert_time (lpFileInfo.ftCreationTime);
+      if (buffer->st_ctime == 0) buffer->st_ctime = buffer->st_mtime;
+      buffer->st_size = lpFileInfo.nFileSizeLow;
+      buffer->st_nlink = (short) lpFileInfo.nNumberOfLinks;
+      return 0;
+    }
+}
+
 /* MSVC stat function can't cope with UNC names and has other bugs, so
    replace it with our own.  This also allows us to calculate consistent
    inode values without hacks in the main Emacs code. */
@@ -1390,8 +1438,8 @@ stat (const char * path, struct stat * buf)
     }
   else if (!NILP (Vmswindows_get_true_file_attributes))
     {
-      /* This is more accurate in terms of gettting the correct number
-        of links, but is quite slow (it is noticable when Emacs is
+      /* This is more accurate in terms of getting the correct number
+        of links, but is quite slow (it is noticeable when Emacs is
         making a list of file name completions). */
       BY_HANDLE_FILE_INFORMATION info;
 
@@ -1527,67 +1575,6 @@ sys_pipe (int * phandles)
   return rc;
 }
 
-/* From ntproc.c */
-extern Lisp_Object Vwin32_pipe_read_delay;
-
-/* Function to do blocking read of one byte, needed to implement
-   select.  It is only allowed on sockets and pipes. */
-int
-_sys_read_ahead (int fd)
-{
-  child_process * cp;
-  int rc;
-
-  if (fd < 0 || fd >= MAXDESC)
-    return STATUS_READ_ERROR;
-
-  cp = fd_info[fd].cp;
-
-  if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
-    return STATUS_READ_ERROR;
-
-  if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
-      || (fd_info[fd].flags & FILE_READ) == 0)
-    {
-      /* fd is not a pipe or socket */
-      abort ();
-    }
-  
-  cp->status = STATUS_READ_IN_PROGRESS;
-  
-  if (fd_info[fd].flags & FILE_PIPE)
-    {
-      rc = _read (fd, &cp->chr, sizeof (char));
-
-      /* Give subprocess time to buffer some more output for us before
-        reporting that input is available; we need this because Win95
-        connects DOS programs to pipes by making the pipe appear to be
-        the normal console stdout - as a result most DOS programs will
-        write to stdout without buffering, ie.  one character at a
-        time.  Even some Win32 programs do this - "dir" in a command
-        shell on NT is very slow if we don't do this. */
-      if (rc > 0)
-       {
-         int wait = XINT (Vwin32_pipe_read_delay);
-
-         if (wait > 0)
-           Sleep (wait);
-         else if (wait < 0)
-           while (++wait <= 0)
-             /* Yield remainder of our time slice, effectively giving a
-                temporary priority boost to the child process. */
-             Sleep (0);
-       }
-    }
-
-  if (rc == sizeof (char))
-    cp->status = STATUS_READ_SUCCEEDED;
-  else
-    cp->status = STATUS_READ_FAILED;
-
-  return cp->status;
-}
-
 void
 term_ntproc (int unused)
 {
@@ -1810,6 +1797,7 @@ int msw_raise (int nsig)
     exit (3);
 
   /* Other signals are ignored by default */
+  return 0;
 }
 
 /*--------------------------------------------------------------------*/
@@ -1833,7 +1821,7 @@ int msw_raise (int nsig)
    */
 const int timer_prec = 10;
 
-/* Last itimevals, as set by calls to setitimer */
+/* Last itimervals, as set by calls to setitimer */
 static struct itimerval it_alarm;
 static struct itimerval it_prof;
 
@@ -1863,7 +1851,7 @@ static UINT period (const struct itimerval* it, UINT denom)
   if (tv->tv_sec == 0 && tv->tv_usec == 0)
     return 0;
   
-  /* Conver to ms and divide by denom */
+  /* Convert to ms and divide by denom */
   res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom;
   
   /* Converge to minimum timer resolution */
@@ -1928,4 +1916,45 @@ int setitimer (int kind, const struct itimerval* itnew,
     return errno = EINVAL;
 }
 
+int
+open_input_file (file_data *p_file, CONST char *filename)
+{
+  HANDLE file;
+  HANDLE file_mapping;
+  void  *file_base;
+  DWORD size, upper_size;
+
+  file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+  if (file == INVALID_HANDLE_VALUE) 
+    return FALSE;
+
+  size = GetFileSize (file, &upper_size);
+  file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY, 
+                                   0, size, NULL);
+  if (!file_mapping) 
+    return FALSE;
+
+  file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
+  if (file_base == 0) 
+    return FALSE;
+
+  p_file->name = (char*)filename;
+  p_file->size = size;
+  p_file->file = file;
+  p_file->file_mapping = file_mapping;
+  p_file->file_base = file_base;
+
+  return TRUE;
+}
+
+/* Close the system structures associated with the given file.  */
+void
+close_file_data (file_data *p_file)
+{
+    UnmapViewOfFile (p_file->file_base);
+    CloseHandle (p_file->file_mapping);
+    CloseHandle (p_file->file);
+}
+
 /* end of nt.c */