* dbusbind.c (xd_retrieve_arg): Pacify GCC on x86_64 GNU/Linux.
[bpt/emacs.git] / src / w32.c
index 9fe8883..5a82897 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -1,12 +1,12 @@
 /* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
    Copyright (C) 1994, 1995, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -32,6 +32,7 @@ Boston, MA 02110-1301, USA.
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/utime.h>
+#include <mbstring.h>  /* for _mbspbrk */
 
 /* must include CRT headers *before* config.h */
 
@@ -112,7 +113,7 @@ extern int w32_num_mouse_buttons;
 
 \f
 /*
-       Initialization states
+  Initialization states
  */
 static BOOL g_b_init_is_windows_9x;
 static BOOL g_b_init_open_process_token;
@@ -136,6 +137,15 @@ typedef BOOL (WINAPI * GetTokenInformation_Proc) (
     LPVOID TokenInformation,
     DWORD TokenInformationLength,
     PDWORD ReturnLength);
+typedef BOOL (WINAPI * GetProcessTimes_Proc) (
+    HANDLE process_handle,
+    LPFILETIME creation_time,
+    LPFILETIME exit_time,
+    LPFILETIME kernel_time,
+    LPFILETIME user_time);
+
+GetProcessTimes_Proc get_process_times_fn = NULL;
+
 #ifdef _UNICODE
 const char * const LookupAccountSid_Name = "LookupAccountSidW";
 #else
@@ -171,6 +181,46 @@ is_windows_9x ()
   return s_b_ret;
 }
 
+/* Get total user and system times for get-internal-run-time.
+   Returns a list of three integers if the times are provided by the OS
+   (NT derivatives), otherwise it returns the result of current-time. */
+Lisp_Object
+w32_get_internal_run_time ()
+{
+  if (get_process_times_fn)
+    {
+      FILETIME create, exit, kernel, user;
+      HANDLE proc = GetCurrentProcess();
+      if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user))
+        {
+          LARGE_INTEGER user_int, kernel_int, total;
+          int microseconds;
+          user_int.LowPart = user.dwLowDateTime;
+          user_int.HighPart = user.dwHighDateTime;
+          kernel_int.LowPart = kernel.dwLowDateTime;
+          kernel_int.HighPart = kernel.dwHighDateTime;
+          total.QuadPart = user_int.QuadPart + kernel_int.QuadPart;
+          /* FILETIME is 100 nanosecond increments, Emacs only wants
+             microsecond resolution.  */
+          total.QuadPart /= 10;
+          microseconds = total.QuadPart % 1000000;
+          total.QuadPart /= 1000000;
+
+          /* Sanity check to make sure we can represent the result.  */
+          if (total.HighPart == 0)
+            {
+              int secs = total.LowPart;
+
+              return list3 (make_number ((secs >> 16) & 0xffff),
+                            make_number (secs & 0xffff),
+                            make_number (microseconds));
+            }
+        }
+    }
+
+  return Fcurrent_time ();
+}
+
   /* ** The wrapper functions ** */
 
 BOOL WINAPI open_process_token (
@@ -485,20 +535,16 @@ init_user_info ()
      the user-sid as the user id value (same for group id using the
      primary group sid from the process token). */
 
-  char            user_sid[256], name[256], domain[256];
-  DWORD           length = sizeof (name), dlength = sizeof (domain), trash;
-  HANDLE          token = NULL;
-  SID_NAME_USE    user_type;
-
-  if (
-                       open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
-      && get_token_information (
-                                       token, TokenUser,
-                             (PVOID) user_sid, sizeof (user_sid), &trash)
-      && lookup_account_sid (
-                                       NULL, *((PSID *) user_sid), name, &length,
-                          domain, &dlength, &user_type)
-                       )
+  char         user_sid[256], name[256], domain[256];
+  DWORD        length = sizeof (name), dlength = sizeof (domain), trash;
+  HANDLE       token = NULL;
+  SID_NAME_USE user_type;
+
+  if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token)
+      && get_token_information (token, TokenUser,
+                               (PVOID) user_sid, sizeof (user_sid), &trash)
+      && lookup_account_sid (NULL, *((PSID *) user_sid), name, &length,
+                            domain, &dlength, &user_type))
     {
       strcpy (the_passwd.pw_name, name);
       /* Determine a reasonable uid value. */
@@ -523,7 +569,7 @@ init_user_info ()
 
          /* Get group id */
          if (get_token_information (token, TokenPrimaryGroup,
-                                  (PVOID) user_sid, sizeof (user_sid), &trash))
+                                    (PVOID) user_sid, sizeof (user_sid), &trash))
            {
              SID_IDENTIFIER_AUTHORITY * pSIA;
 
@@ -540,7 +586,7 @@ init_user_info ()
        }
     }
   /* If security calls are not supported (presumably because we
-       are running under Windows 95), fallback to this. */
+     are running under Windows 95), fallback to this. */
   else if (GetUserName (name, &length))
     {
       strcpy (the_passwd.pw_name, name);
@@ -739,7 +785,7 @@ get_long_basename (char * name, char * buf, int size)
   int len = 0;
 
   /* must be valid filename, no wild cards or other invalid characters */
-  if (strpbrk (name, "*?|<>\""))
+  if (_mbspbrk (name, "*?|<>\""))
     return 0;
 
   dir_handle = FindFirstFile (name, &find_data);
@@ -814,7 +860,7 @@ is_unc_volume (const char *filename)
   if (!IS_DIRECTORY_SEP (ptr[0]) || !IS_DIRECTORY_SEP (ptr[1]) || !ptr[2])
     return 0;
 
-  if (strpbrk (ptr + 2, "*?|<>\"\\/"))
+  if (_mbspbrk (ptr + 2, "*?|<>\"\\/"))
     return 0;
 
   return 1;
@@ -858,18 +904,6 @@ alarm (int seconds)
   return 0;
 }
 
-void
-unrequest_sigio (void)
-{
-  return;
-}
-
-void
-request_sigio (void)
-{
-  return;
-}
-
 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
 
 LPBYTE
@@ -880,7 +914,6 @@ w32_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.  */
@@ -893,6 +926,7 @@ w32_get_resource (key, lpdwtype)
          && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
+          RegCloseKey (hrootkey);
          return (lpvalue);
        }
 
@@ -909,6 +943,7 @@ w32_get_resource (key, lpdwtype)
          && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
          && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
        {
+          RegCloseKey (hrootkey);
          return (lpvalue);
        }
 
@@ -1109,8 +1144,11 @@ init_environment (char ** argv)
          {
            int dont_free = 0;
 
-           if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
+           if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
+               /* Also ignore empty environment variables.  */
+               || *lpval == 0)
              {
+               if (lpval) xfree (lpval);
                lpval = env_vars[i].def_value;
                dwType = REG_EXPAND_SZ;
                dont_free = 1;
@@ -1231,12 +1269,6 @@ get_emacs_configuration (void)
       break;
 #endif
 
-#ifdef PROCESSOR_INTEL_860
-    case PROCESSOR_INTEL_860:
-      arch = "i860";
-      break;
-#endif
-
 #ifdef PROCESSOR_MIPS_R2000
     case PROCESSOR_MIPS_R2000:
     case PROCESSOR_MIPS_R3000:
@@ -2386,8 +2418,12 @@ stat (const char * path, struct stat * buf)
     }
 
   name = (char *) map_w32_filename (path, &path);
-  /* must be valid filename, no wild cards or other invalid characters */
-  if (strpbrk (name, "*?|<>\""))
+  /* Must be valid filename, no wild cards or other invalid
+     characters.  We use _mbspbrk to support multibyte strings that
+     might look to strpbrk as if they included literal *, ?, and other
+     characters mentioned below that are disallowed by Windows
+     filesystems.  */
+  if (_mbspbrk (name, "*?|<>\""))
     {
       errno = ENOENT;
       return -1;
@@ -2476,7 +2512,7 @@ stat (const char * path, struct stat * buf)
          != INVALID_HANDLE_VALUE)
     {
       /* This is more accurate in terms of gettting the correct number
-        of links, but is quite slow (it is noticable when Emacs is
+        of links, but is quite slow (it is noticeable when Emacs is
         making a list of file name completions). */
       BY_HANDLE_FILE_INFORMATION info;
 
@@ -2961,7 +2997,7 @@ struct {
   WSAEINVALIDPROCTABLE    , "Invalid procedure table from service provider",
   WSAEINVALIDPROVIDER     , "Invalid service provider version number",
   WSAEPROVIDERFAILEDINIT  , "Unable to initialize a service provider",
-  WSASYSCALLFAILURE       , "System call failured",
+  WSASYSCALLFAILURE       , "System call failure",
   WSASERVICE_NOT_FOUND    , "Service not found",           /* not sure */
   WSATYPE_NOT_FOUND       , "Class type not found",
   WSA_E_NO_MORE           , "No more resources available",  /* really not sure */
@@ -4143,6 +4179,11 @@ BOOL WINAPI shutdown_handler(DWORD type)
 void
 globals_of_w32 ()
 {
+  HMODULE kernel32 = GetModuleHandle ("kernel32.dll");
+
+  get_process_times_fn = (GetProcessTimes_Proc)
+    GetProcAddress (kernel32, "GetProcessTimes");
+
   g_b_init_is_windows_9x = 0;
   g_b_init_open_process_token = 0;
   g_b_init_get_token_information = 0;
@@ -4155,7 +4196,7 @@ globals_of_w32 ()
   SetConsoleCtrlHandler(shutdown_handler, TRUE);
 }
 
-/* end of nt.c */
+/* end of w32.c */
 
 /* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1
    (do not change this comment) */