From 8ff53d1ff250c8311efac7f2a8799801e3f0afb4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 5 Aug 2015 07:45:29 +0000 Subject: [PATCH 1/4] uname: Add --processor/--hardware-platform option On linux platforms, grok /proc/cpuinfo for the CPU/vendor info. Prob not suitable for upstream seeing as how it's 100% linux-specific http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html Patch originally by Carlos E. Gorges , but heavily reworked to suck less. To add support for additional platforms, check out the show_cpuinfo() func in the linux/arch// source tree of the kernel. --- src/uname.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/src/uname.c b/src/uname.c index 6635a6a8e..30c04f5be 100644 --- a/src/uname.c +++ b/src/uname.c @@ -49,6 +49,12 @@ # include #endif +#if defined (__linux__) +# define USE_PROCINFO +# define UNAME_HARDWARE_PLATFORM +#endif + +#include "ignore-value.h" #include "system.h" #include "die.h" #include "error.h" @@ -154,6 +160,119 @@ Print machine architecture.\n\ 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; + + const char * const procinfo_keys[] = { + /* --processor --hardware-platform */ + #if defined (__alpha__) + "cpu model", "system type" + #elif defined (__arm__) + /* linux-3.8+ uses "model name", but older uses "Processor". */ + "model name", "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__) + "model name", "vendor" + #elif defined (__hppa__) + "cpu", "model" + #elif defined (__m68k__) + "CPU", "MMU" + #elif defined (__microblaze__) + "CPU-Ver", "FPGA-Arch" + #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 something + * like "%*[^\n]\n" won't eat the newline. */ + ignore_value (fscanf (fp, "%*[^\n]")); + ignore_value (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. */ @@ -301,10 +420,14 @@ main (int argc, char **argv) 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 @@ -357,9 +480,13 @@ main (int argc, char **argv) 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 -- 2.15.1