Submitted By: Jim Gifford 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 diff -Naur coreutils-8.16.orig/src/uname.c coreutils-8.16/src/uname.c --- coreutils-8.16.orig/src/uname.c 2012-06-10 08:41:13.381458681 +0000 +++ coreutils-8.16/src/uname.c 2012-06-10 08:41:29.665894170 +0000 @@ -49,6 +49,11 @@ # include #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.16.orig/src/uname.c.orig coreutils-8.16/src/uname.c.orig --- coreutils-8.16.orig/src/uname.c.orig 1970-01-01 00:00:00.000000000 +0000 +++ coreutils-8.16/src/uname.c.orig 2012-03-24 20:26:51.000000000 +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 . */ + +/* Written by David MacKenzie */ + +#include +#include +#include +#include +#include + +#if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H +# include +#endif + +#if HAVE_SYS_SYSCTL_H +# if HAVE_SYS_PARAM_H +# include /* needed for OpenBSD 3.0 */ +# endif +# include +# 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 +# include +#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); +}