Submitted By: Jim Gifford Date: 2009-09-12 Initial Package Version: 7.6 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 diff -Naur coreutils-7.6.orig/src/uname.c coreutils-7.6/src/uname.c --- coreutils-7.6.orig/src/uname.c 2009-09-01 04:01:16.000000000 -0700 +++ coreutils-7.6/src/uname.c 2009-09-12 01:32:54.000000000 -0700 @@ -50,6 +50,11 @@ # include #endif +#if defined (__linux__) +# define USE_PROCINFO +# define UNAME_HARDWARE_PLATFORM +#endif + #include "system.h" #include "error.h" #include "quote.h" @@ -155,6 +160,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. */ @@ -302,10 +418,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 @@ -358,9 +478,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