root/maint/gnulib/lib/uname.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uname

   1 /* uname replacement.
   2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include <config.h>
  18 
  19 /* Specification.  */
  20 #include <sys/utsname.h>
  21 
  22 /* This file provides an implementation only for the native Windows API.  */
  23 #if defined _WIN32 && ! defined __CYGWIN__
  24 
  25 # include <stdio.h>
  26 # include <stdlib.h>
  27 # include <string.h>
  28 # include <unistd.h>
  29 # include <windows.h>
  30 
  31 /* Mingw headers don't have all the platform codes.  */
  32 # ifndef VER_PLATFORM_WIN32_CE
  33 #  define VER_PLATFORM_WIN32_CE 3
  34 # endif
  35 
  36 /* Some headers don't have all the processor architecture codes.  */
  37 # ifndef PROCESSOR_ARCHITECTURE_AMD64
  38 #  define PROCESSOR_ARCHITECTURE_AMD64 9
  39 # endif
  40 # ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
  41 #  define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
  42 # endif
  43 
  44 /* Mingw headers don't have the latest processor codes.  */
  45 # ifndef PROCESSOR_AMD_X8664
  46 #  define PROCESSOR_AMD_X8664 8664
  47 # endif
  48 
  49 /* Don't assume that UNICODE is not defined.  */
  50 # undef OSVERSIONINFO
  51 # define OSVERSIONINFO OSVERSIONINFOA
  52 # undef GetVersionEx
  53 # define GetVersionEx GetVersionExA
  54 
  55 int
  56 uname (struct utsname *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58   OSVERSIONINFO version;
  59   OSVERSIONINFOEX versionex;
  60   BOOL have_versionex; /* indicates whether versionex is filled */
  61   const char *super_version;
  62 
  63   /* Preparation: Fill version and, if possible, also versionex.
  64      But try to call GetVersionEx only once in the common case.  */
  65   versionex.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
  66   have_versionex = GetVersionEx ((OSVERSIONINFO *) &versionex);
  67   if (have_versionex)
  68     {
  69       /* We know that OSVERSIONINFO is a subset of OSVERSIONINFOEX.  */
  70       memcpy (&version, &versionex, sizeof (OSVERSIONINFO));
  71     }
  72   else
  73     {
  74       version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  75       if (!GetVersionEx (&version))
  76         abort ();
  77     }
  78 
  79   /* Fill in nodename.  */
  80   if (gethostname (buf->nodename, sizeof (buf->nodename)) < 0)
  81     strcpy (buf->nodename, "localhost");
  82 
  83   /* Determine major-major Windows version.  */
  84   if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
  85     {
  86       /* Windows NT or newer.  */
  87       super_version = "NT";
  88     }
  89   else if (version.dwPlatformId == VER_PLATFORM_WIN32_CE)
  90     {
  91       /* Windows CE or Embedded CE.  */
  92       super_version = "CE";
  93     }
  94   else if (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  95     {
  96       /* Windows 95/98/ME.  */
  97       switch (version.dwMinorVersion)
  98         {
  99         case 0:
 100           super_version = "95";
 101           break;
 102         case 10:
 103           super_version = "98";
 104           break;
 105         case 90:
 106           super_version = "ME";
 107           break;
 108         default:
 109           super_version = "";
 110           break;
 111         }
 112     }
 113   else
 114     super_version = "";
 115 
 116   /* Fill in sysname.  */
 117 # ifdef __MINGW32__
 118   /* Returns a string compatible with the MSYS uname.exe program,
 119      so that no further changes are needed to GNU config.guess.
 120      For example,
 121        $ ./uname.exe -s      => MINGW32_NT-5.1
 122    */
 123   sprintf (buf->sysname, "MINGW32_%s-%u.%u", super_version,
 124            (unsigned int) version.dwMajorVersion,
 125            (unsigned int) version.dwMinorVersion);
 126 # else
 127   sprintf (buf->sysname, "Windows%s", super_version);
 128 # endif
 129 
 130   /* Fill in release, version.  */
 131   /* The MSYS uname.exe programs uses strings from a modified Cygwin runtime:
 132        $ ./uname.exe -r      => 1.0.11(0.46/3/2)
 133        $ ./uname.exe -v      => 2008-08-25 23:40
 134      There is no point in imitating this behaviour.  */
 135   if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
 136     {
 137       /* Windows NT or newer.  */
 138       struct windows_version
 139         {
 140           int major;
 141           int minor;
 142           unsigned int server_offset;
 143           const char *name;
 144         };
 145 
 146       /* Storing the workstation and server version names in a single
 147          stream does not waste memory when they are the same.  These
 148          macros abstract the representation.  VERSION1 is used if
 149          version.wProductType does not matter, VERSION2 if it does.  */
 150       #define VERSION1(major, minor, name) \
 151         { major, minor, 0, name }
 152       #define VERSION2(major, minor, workstation, server) \
 153         { major, minor, sizeof workstation, workstation "\0" server }
 154       static const struct windows_version versions[] =
 155         {
 156           VERSION2 (3, -1, "Windows NT Workstation", "Windows NT Server"),
 157           VERSION2 (4, -1, "Windows NT Workstation", "Windows NT Server"),
 158           VERSION1 (5, 0, "Windows 2000"),
 159           VERSION1 (5, 1, "Windows XP"),
 160           VERSION1 (5, 2, "Windows Server 2003"),
 161           VERSION2 (6, 0, "Windows Vista", "Windows Server 2008"),
 162           VERSION2 (6, 1, "Windows 7", "Windows Server 2008 R2"),
 163           VERSION2 (-1, -1, "Windows", "Windows Server")
 164         };
 165       const char *base;
 166       const struct windows_version *v = versions;
 167 
 168       /* Find a version that matches ours.  The last element is a
 169          wildcard that always ends the loop.  */
 170       while ((v->major != version.dwMajorVersion && v->major != -1)
 171              || (v->minor != version.dwMinorVersion && v->minor != -1))
 172         v++;
 173 
 174       if (have_versionex && versionex.wProductType != VER_NT_WORKSTATION)
 175         base = v->name + v->server_offset;
 176       else
 177         base = v->name;
 178       if (v->major == -1 || v->minor == -1)
 179         sprintf (buf->release, "%s %u.%u",
 180                  base,
 181                  (unsigned int) version.dwMajorVersion,
 182                  (unsigned int) version.dwMinorVersion);
 183       else
 184         strcpy (buf->release, base);
 185     }
 186   else if (version.dwPlatformId == VER_PLATFORM_WIN32_CE)
 187     {
 188       /* Windows CE or Embedded CE.  */
 189       sprintf (buf->release, "Windows CE %u.%u",
 190                (unsigned int) version.dwMajorVersion,
 191                (unsigned int) version.dwMinorVersion);
 192     }
 193   else
 194     {
 195       /* Windows 95/98/ME.  */
 196       sprintf (buf->release, "Windows %s", super_version);
 197     }
 198   strcpy (buf->version, version.szCSDVersion);
 199 
 200   /* Fill in machine.  */
 201   {
 202     SYSTEM_INFO info;
 203 
 204     GetSystemInfo (&info);
 205     /* Check for Windows NT or CE, since the info.wProcessorLevel is
 206        garbage on Windows 95. */
 207     if (version.dwPlatformId == VER_PLATFORM_WIN32_NT
 208         || version.dwPlatformId == VER_PLATFORM_WIN32_CE)
 209       {
 210         /* Windows NT or newer, or Windows CE or Embedded CE.  */
 211         switch (info.wProcessorArchitecture)
 212           {
 213           case PROCESSOR_ARCHITECTURE_AMD64:
 214             strcpy (buf->machine, "x86_64");
 215             break;
 216           case PROCESSOR_ARCHITECTURE_IA64:
 217             strcpy (buf->machine, "ia64");
 218             break;
 219           case PROCESSOR_ARCHITECTURE_INTEL:
 220             strcpy (buf->machine, "i386");
 221             if (info.wProcessorLevel >= 3)
 222               buf->machine[1] =
 223                 '0' + (info.wProcessorLevel <= 6 ? info.wProcessorLevel : 6);
 224             break;
 225           case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
 226             strcpy (buf->machine, "i686");
 227             break;
 228           case PROCESSOR_ARCHITECTURE_MIPS:
 229             strcpy (buf->machine, "mips");
 230             break;
 231           case PROCESSOR_ARCHITECTURE_ALPHA:
 232           case PROCESSOR_ARCHITECTURE_ALPHA64:
 233             strcpy (buf->machine, "alpha");
 234             break;
 235           case PROCESSOR_ARCHITECTURE_PPC:
 236             strcpy (buf->machine, "powerpc");
 237             break;
 238           case PROCESSOR_ARCHITECTURE_SHX:
 239             strcpy (buf->machine, "sh");
 240             break;
 241           case PROCESSOR_ARCHITECTURE_ARM:
 242             strcpy (buf->machine, "arm");
 243             break;
 244           default:
 245             strcpy (buf->machine, "unknown");
 246             break;
 247           }
 248       }
 249     else
 250       {
 251         /* Windows 95/98/ME.  */
 252         switch (info.dwProcessorType)
 253           {
 254           case PROCESSOR_AMD_X8664:
 255             strcpy (buf->machine, "x86_64");
 256             break;
 257           case PROCESSOR_INTEL_IA64:
 258             strcpy (buf->machine, "ia64");
 259             break;
 260           default:
 261             if (info.dwProcessorType % 100 == 86)
 262               sprintf (buf->machine, "i%u",
 263                        (unsigned int) info.dwProcessorType);
 264             else
 265               strcpy (buf->machine, "unknown");
 266             break;
 267           }
 268       }
 269   }
 270 
 271   return 0;
 272 }
 273 
 274 #endif

/* [previous][next][first][last][top][bottom][index][help] */