Submitted By: Jim Gifford <jim at cross-lfs dot org>
Date: 2010-07-26
Initial Package Version: 5.97
Upstream Status: Not Accepted
Origin: Gentoo - http://sources.gentoo.org/viewcvs.py/gentoo/src/patchsets/coreutils
Description: Display CPU Information from /proc/cpuinfo or /proc/sysinfo

Rediffed for 7.1 by Jim Gifford
Rediffed for 7.5 by Jim Gifford
Rediffed for 8.4 by Joe Ciccone
Rediffed for 8.9 by Joe Ciccone
Rediffed for 8.16 by Jonathan Norman - 2012-06-10
Rediffed for 8.19 by William Harrington - 2012-08-27
Renamed for 8.20 by William Harrington - 2012-11-01

diff -Naur coreutils-8.19.orig/src/uname.c coreutils-8.19/src/uname.c
--- coreutils-8.19.orig/src/uname.c	2012-07-21 14:54:31.000000000 +0000
+++ coreutils-8.19/src/uname.c	2012-08-27 21:20:07.103876901 +0000
@@ -49,6 +49,11 @@
 # include <mach-o/arch.h>
 #endif
 
+#if defined (__linux__)
+# define USE_PROCINFO
+# define UNAME_HARDWARE_PLATFORM
+#endif
+
 #include "system.h"
 #include "error.h"
 #include "quote.h"
@@ -153,6 +158,117 @@
   exit (status);
 }
 
+#if defined(USE_PROCINFO)
+
+# if defined(__s390__) || defined(__s390x__)
+#  define CPUINFO_FILE    "/proc/sysinfo"
+#  define CPUINFO_FORMAT  "%64[^\t :]%*[ :]%256[^\n]%c"
+# else
+#  define CPUINFO_FILE    "/proc/cpuinfo"
+#  define CPUINFO_FORMAT  "%64[^\t:]\t:%256[^\n]%c"
+# endif
+
+# define PROCINFO_PROCESSOR      0
+# define PROCINFO_HARDWARE_PLATFORM 1
+
+static void __eat_cpuinfo_space(char *buf)
+{
+	/* first eat trailing space */
+	char *tmp = buf + strlen(buf) - 1;
+	while (tmp > buf && isspace(*tmp))
+		*tmp-- = '\0';
+	/* then eat leading space */
+	tmp = buf;
+	while (*tmp && isspace(*tmp))
+		tmp++;
+	if (tmp != buf)
+		memmove(buf, tmp, strlen(tmp)+1);
+	/* finally collapse whitespace */
+	tmp = buf;
+	while (tmp[0] && tmp[1]) {
+		if (isspace(tmp[0]) && isspace(tmp[1])) {
+			memmove(tmp, tmp+1, strlen(tmp));
+			continue;
+		}
+		++tmp;
+	}
+}
+
+static int __linux_procinfo (int x, char *fstr, size_t s)
+{
+	FILE *fp;
+
+	char *procinfo_keys[] = {
+		/* --processor --hardware-platform */
+		#if defined(__alpha__)
+			"cpu model", "system type"
+		#elif defined(__arm__)
+			"Processor", "Hardware"
+		#elif defined(__avr32__)
+			"processor", "cpu family"
+		#elif defined(__bfin__)
+			"CPU", "BOARD Name"
+		#elif defined(__cris__)
+			"cpu", "cpu model"
+		#elif defined(__frv__)
+			"CPU-Core", "System"
+		#elif defined(__i386__) || defined(__x86_64__)
+			"model name", "vendor_id"
+		#elif defined(__ia64__)
+			"family", "vendor"
+		#elif defined(__hppa__)
+			"cpu", "model"
+		#elif defined(__m68k__)
+			"CPU", "MMU"
+		#elif defined(__mips__)
+			"cpu model", "system type"
+		#elif defined(__powerpc__) || defined(__powerpc64__)
+			"cpu", "machine"
+		#elif defined(__s390__) || defined(__s390x__)
+			"Type", "Manufacturer"
+		#elif defined(__sh__)
+			"cpu type", "machine"
+		#elif defined(sparc) || defined(__sparc__)
+			"type", "cpu"
+		#elif defined(__vax__)
+			"cpu type", "cpu"
+		#else
+			"unknown", "unknown"
+		#endif
+	};
+
+	if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
+		char key[65], value[257], eol, *ret = NULL;
+
+		while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
+			__eat_cpuinfo_space(key);
+			if (!strcmp(key, procinfo_keys[x])) {
+				__eat_cpuinfo_space(value);
+				ret = value;
+				break;
+			}
+			if (eol != '\n') {
+				/* we need two fscanf's here in case the previous
+				 * length limit caused us to read right up to the
+				 * newline ... doing "%*[^\n]\n" wont eat the newline
+				 */
+				fscanf(fp, "%*[^\n]");
+				fscanf(fp, "\n");
+			}
+		}
+		fclose(fp);
+
+		if (ret) {
+			strncpy(fstr, ret, s);
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+#endif
+
 /* Print ELEMENT, preceded by a space if something has already been
    printed.  */
 
@@ -300,10 +416,14 @@
   if (toprint & PRINT_PROCESSOR)
     {
       char const *element = unknown;
-#if HAVE_SYSINFO && defined SI_ARCHITECTURE
+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
       {
         static char processor[257];
+#if defined(USE_PROCINFO)
+        if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
+#else
         if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+#endif
           element = processor;
       }
 #endif
@@ -356,9 +476,13 @@
       if (element == unknown)
         {
           static char hardware_platform[257];
+#if defined(USE_PROCINFO)
+        if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
+#else
           size_t s = sizeof hardware_platform;
           static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
           if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
+#endif
             element = hardware_platform;
         }
 #endif
diff -Naur coreutils-8.19.orig/src/uname.c.orig coreutils-8.19/src/uname.c.orig
--- coreutils-8.19.orig/src/uname.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ coreutils-8.19/src/uname.c.orig	2012-08-27 21:20:07.103876901 +0000
@@ -0,0 +1,375 @@
+/* uname -- print system information
+
+   Copyright (C) 1989-2012 Free Software Foundation, Inc.
+
+   This program 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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
+
+#include <config.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <getopt.h>
+
+#if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
+# include <sys/systeminfo.h>
+#endif
+
+#if HAVE_SYS_SYSCTL_H
+# if HAVE_SYS_PARAM_H
+#  include <sys/param.h> /* needed for OpenBSD 3.0 */
+# endif
+# include <sys/sysctl.h>
+# ifdef HW_MODEL
+#  ifdef HW_MACHINE_ARCH
+/* E.g., FreeBSD 4.5, NetBSD 1.5.2 */
+#   define UNAME_HARDWARE_PLATFORM HW_MODEL
+#   define UNAME_PROCESSOR HW_MACHINE_ARCH
+#  else
+/* E.g., OpenBSD 3.0 */
+#   define UNAME_PROCESSOR HW_MODEL
+#  endif
+# endif
+#endif
+
+#ifdef __APPLE__
+# include <mach/machine.h>
+# include <mach-o/arch.h>
+#endif
+
+#include "system.h"
+#include "error.h"
+#include "quote.h"
+#include "uname.h"
+
+/* The official name of this program (e.g., no 'g' prefix).  */
+#define PROGRAM_NAME (uname_mode == UNAME_UNAME ? "uname" : "arch")
+
+#define AUTHORS proper_name ("David MacKenzie")
+#define ARCH_AUTHORS "David MacKenzie", "Karel Zak"
+
+/* Values that are bitwise or'd into 'toprint'. */
+/* Kernel name. */
+#define PRINT_KERNEL_NAME 1
+
+/* Node name on a communications network. */
+#define PRINT_NODENAME 2
+
+/* Kernel release. */
+#define PRINT_KERNEL_RELEASE 4
+
+/* Kernel version. */
+#define PRINT_KERNEL_VERSION 8
+
+/* Machine hardware name. */
+#define PRINT_MACHINE 16
+
+/* Processor type. */
+#define PRINT_PROCESSOR 32
+
+/* Hardware platform.  */
+#define PRINT_HARDWARE_PLATFORM 64
+
+/* Operating system.  */
+#define PRINT_OPERATING_SYSTEM 128
+
+static struct option const uname_long_options[] =
+{
+  {"all", no_argument, NULL, 'a'},
+  {"kernel-name", no_argument, NULL, 's'},
+  {"sysname", no_argument, NULL, 's'},	/* Obsolescent.  */
+  {"nodename", no_argument, NULL, 'n'},
+  {"kernel-release", no_argument, NULL, 'r'},
+  {"release", no_argument, NULL, 'r'},  /* Obsolescent.  */
+  {"kernel-version", no_argument, NULL, 'v'},
+  {"machine", no_argument, NULL, 'm'},
+  {"processor", no_argument, NULL, 'p'},
+  {"hardware-platform", no_argument, NULL, 'i'},
+  {"operating-system", no_argument, NULL, 'o'},
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+static struct option const arch_long_options[] =
+{
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+void
+usage (int status)
+{
+  if (status != EXIT_SUCCESS)
+    emit_try_help ();
+  else
+    {
+      printf (_("Usage: %s [OPTION]...\n"), program_name);
+
+      if (uname_mode == UNAME_UNAME)
+        {
+          fputs (_("\
+Print certain system information.  With no OPTION, same as -s.\n\
+\n\
+  -a, --all                print all information, in the following order,\n\
+                             except omit -p and -i if unknown:\n\
+  -s, --kernel-name        print the kernel name\n\
+  -n, --nodename           print the network node hostname\n\
+  -r, --kernel-release     print the kernel release\n\
+"), stdout);
+          fputs (_("\
+  -v, --kernel-version     print the kernel version\n\
+  -m, --machine            print the machine hardware name\n\
+  -p, --processor          print the processor type or \"unknown\"\n\
+  -i, --hardware-platform  print the hardware platform or \"unknown\"\n\
+  -o, --operating-system   print the operating system\n\
+"), stdout);
+        }
+      else
+        {
+          fputs (_("\
+Print machine architecture.\n\
+\n\
+"), stdout);
+        }
+
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      emit_ancillary_info ();
+    }
+  exit (status);
+}
+
+/* Print ELEMENT, preceded by a space if something has already been
+   printed.  */
+
+static void
+print_element (char const *element)
+{
+  static bool printed;
+  if (printed)
+    putchar (' ');
+  printed = true;
+  fputs (element, stdout);
+}
+
+
+/* Set all the option flags according to the switches specified.
+   Return the mask indicating which elements to print.  */
+
+static int
+decode_switches (int argc, char **argv)
+{
+  int c;
+  unsigned int toprint = 0;
+
+  if (uname_mode == UNAME_ARCH)
+    {
+      while ((c = getopt_long (argc, argv, "",
+                               arch_long_options, NULL)) != -1)
+        {
+          switch (c)
+            {
+            case_GETOPT_HELP_CHAR;
+
+            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, ARCH_AUTHORS);
+
+            default:
+              usage (EXIT_FAILURE);
+            }
+        }
+      toprint = PRINT_MACHINE;
+    }
+  else
+    {
+      while ((c = getopt_long (argc, argv, "asnrvmpio",
+                               uname_long_options, NULL)) != -1)
+        {
+          switch (c)
+            {
+            case 'a':
+              toprint = UINT_MAX;
+              break;
+
+            case 's':
+              toprint |= PRINT_KERNEL_NAME;
+              break;
+
+            case 'n':
+              toprint |= PRINT_NODENAME;
+              break;
+
+            case 'r':
+              toprint |= PRINT_KERNEL_RELEASE;
+              break;
+
+            case 'v':
+              toprint |= PRINT_KERNEL_VERSION;
+              break;
+
+            case 'm':
+              toprint |= PRINT_MACHINE;
+              break;
+
+            case 'p':
+              toprint |= PRINT_PROCESSOR;
+              break;
+
+            case 'i':
+              toprint |= PRINT_HARDWARE_PLATFORM;
+              break;
+
+            case 'o':
+              toprint |= PRINT_OPERATING_SYSTEM;
+              break;
+
+            case_GETOPT_HELP_CHAR;
+
+            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+            default:
+              usage (EXIT_FAILURE);
+            }
+        }
+    }
+
+  if (argc != optind)
+    {
+      error (0, 0, _("extra operand %s"), quote (argv[optind]));
+      usage (EXIT_FAILURE);
+    }
+
+  return toprint;
+}
+
+int
+main (int argc, char **argv)
+{
+  static char const unknown[] = "unknown";
+
+  /* Mask indicating which elements to print. */
+  unsigned int toprint = 0;
+
+  initialize_main (&argc, &argv);
+  set_program_name (argv[0]);
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  atexit (close_stdout);
+
+  toprint = decode_switches (argc, argv);
+
+  if (toprint == 0)
+    toprint = PRINT_KERNEL_NAME;
+
+  if (toprint
+       & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE
+          | PRINT_KERNEL_VERSION | PRINT_MACHINE))
+    {
+      struct utsname name;
+
+      if (uname (&name) == -1)
+        error (EXIT_FAILURE, errno, _("cannot get system name"));
+
+      if (toprint & PRINT_KERNEL_NAME)
+        print_element (name.sysname);
+      if (toprint & PRINT_NODENAME)
+        print_element (name.nodename);
+      if (toprint & PRINT_KERNEL_RELEASE)
+        print_element (name.release);
+      if (toprint & PRINT_KERNEL_VERSION)
+        print_element (name.version);
+      if (toprint & PRINT_MACHINE)
+        print_element (name.machine);
+    }
+
+  if (toprint & PRINT_PROCESSOR)
+    {
+      char const *element = unknown;
+#if HAVE_SYSINFO && defined SI_ARCHITECTURE
+      {
+        static char processor[257];
+        if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+          element = processor;
+      }
+#endif
+#ifdef UNAME_PROCESSOR
+      if (element == unknown)
+        {
+          static char processor[257];
+          size_t s = sizeof processor;
+          static int mib[] = { CTL_HW, UNAME_PROCESSOR };
+          if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)
+            element = processor;
+
+# ifdef __APPLE__
+          /* This kludge works around a bug in Mac OS X.  */
+          if (element == unknown)
+            {
+              cpu_type_t cputype;
+              size_t s = sizeof cputype;
+              NXArchInfo const *ai;
+              if (sysctlbyname ("hw.cputype", &cputype, &s, NULL, 0) == 0
+                  && (ai = NXGetArchInfoFromCpuType (cputype,
+                                                     CPU_SUBTYPE_MULTIPLE))
+                  != NULL)
+                element = ai->name;
+
+              /* Hack "safely" around the ppc vs. powerpc return value. */
+              if (cputype == CPU_TYPE_POWERPC
+                  && STRNCMP_LIT (element, "ppc") == 0)
+                element = "powerpc";
+            }
+# endif
+        }
+#endif
+      if (! (toprint == UINT_MAX && element == unknown))
+        print_element (element);
+    }
+
+  if (toprint & PRINT_HARDWARE_PLATFORM)
+    {
+      char const *element = unknown;
+#if HAVE_SYSINFO && defined SI_PLATFORM
+      {
+        static char hardware_platform[257];
+        if (0 <= sysinfo (SI_PLATFORM,
+                          hardware_platform, sizeof hardware_platform))
+          element = hardware_platform;
+      }
+#endif
+#ifdef UNAME_HARDWARE_PLATFORM
+      if (element == unknown)
+        {
+          static char hardware_platform[257];
+          size_t s = sizeof hardware_platform;
+          static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
+          if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
+            element = hardware_platform;
+        }
+#endif
+      if (! (toprint == UINT_MAX && element == unknown))
+        print_element (element);
+    }
+
+  if (toprint & PRINT_OPERATING_SYSTEM)
+    print_element (HOST_OPERATING_SYSTEM);
+
+  putchar ('\n');
+
+  exit (EXIT_SUCCESS);
+}
