Do only one call to GetVersionEx in the common case.
authorBruno Haible <bruno@clisp.org>
Sat, 3 Oct 2009 18:34:12 +0000 (20:34 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 3 Oct 2009 18:34:12 +0000 (20:34 +0200)
ChangeLog
lib/uname.c

index 2d8cf65..5c9efe4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
 2009-10-03  Paolo Bonzini  <bonzini@gnu.org>
            Bruno Haible  <bruno@clisp.org>
 
+       * lib/uname.c: Include <string.h>.
+       (uname): Do only one call to GetVersionEx in the common case.
+
+2009-10-03  Paolo Bonzini  <bonzini@gnu.org>
+           Bruno Haible  <bruno@clisp.org>
+
        * lib/uname.c (VER_PLATFORM_WIN32_CE, PROCESSOR_ARCHITECTURE_AMD64,
        PROCESSOR_ARCHITECTURE_IA32_ON_WIN64): Define fallbacks.
        (uname): Add support for Windows CE and various non-x86 CPU types.
index 70ebb95..95c5776 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <windows.h>
 
@@ -49,16 +50,31 @@ int
 uname (struct utsname *buf)
 {
   OSVERSIONINFO version;
+  OSVERSIONINFOEX versionex;
+  BOOL have_versionex; /* indicates whether versionex is filled */
   const char *super_version;
 
+  /* Preparation: Fill version and, if possible, also versionex.
+     But try to call GetVersionEx only once in the common case.  */
+  versionex.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
+  have_versionex = GetVersionEx (&versionex);
+  if (have_versionex)
+    {
+      /* We know that OSVERSIONINFO is a subset of OSVERSIONINFOEX.  */
+      memcpy (&version, &versionex, sizeof (OSVERSIONINFO));
+    }
+  else
+    {
+      version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+      if (!GetVersionEx (&version))
+       abort ();
+    }
+
   /* Fill in nodename.  */
   if (gethostname (buf->nodename, sizeof (buf->nodename)) < 0)
     strcpy (buf->nodename, "localhost");
 
   /* Determine major-major Windows version.  */
-  version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-  if (!GetVersionEx (&version))
-    abort ();
   if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
     {
       /* Windows NT or newer.  */
@@ -135,11 +151,7 @@ uname (struct utsname *buf)
          }
       else if (version.dwMajorVersion == 6)
        {
-         OSVERSIONINFOEX versionex;
-
-         versionex.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
-         if (GetVersionEx ((OSVERSIONINFO *) &versionex)
-             && versionex.wProductType != VER_NT_WORKSTATION)
+         if (have_versionex && versionex.wProductType != VER_NT_WORKSTATION)
            strcpy (buf->release, "Windows Server 2008");
          else
            switch (version.dwMinorVersion)