coreutils-uname.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. On linux platforms, grok /proc/cpuinfo for the CPU/vendor info.
  2. Prob not suitable for upstream seeing as how it's 100% linux-specific
  3. http://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
  4. Patch originally by Carlos E. Gorges <carlos at techlinux.com.br>, but
  5. heavily reworked to suck less.
  6. To add support for additional platforms, check out the show_cpuinfo()
  7. func in the linux/arch/<ARCH>/ source tree of the kernel.
  8. --- coreutils/src/uname.c
  9. +++ coreutils/src/uname.c
  10. @@ -50,6 +50,11 @@
  11. # include <mach-o/arch.h>
  12. #endif
  13. +#if defined(__linux__)
  14. +# define USE_PROCINFO
  15. +# define UNAME_HARDWARE_PLATFORM
  16. +#endif
  17. +
  18. #include "system.h"
  19. #include "error.h"
  20. #include "quote.h"
  21. @@ -138,6 +143,117 @@
  22. exit (status);
  23. }
  24. +#if defined(USE_PROCINFO)
  25. +
  26. +# if defined(__s390__) || defined(__s390x__)
  27. +# define CPUINFO_FILE "/proc/sysinfo"
  28. +# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c"
  29. +# else
  30. +# define CPUINFO_FILE "/proc/cpuinfo"
  31. +# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c"
  32. +# endif
  33. +
  34. +# define PROCINFO_PROCESSOR 0
  35. +# define PROCINFO_HARDWARE_PLATFORM 1
  36. +
  37. +static void __eat_cpuinfo_space(char *buf)
  38. +{
  39. + /* first eat trailing space */
  40. + char *tmp = buf + strlen(buf) - 1;
  41. + while (tmp > buf && isspace(*tmp))
  42. + *tmp-- = '\0';
  43. + /* then eat leading space */
  44. + tmp = buf;
  45. + while (*tmp && isspace(*tmp))
  46. + tmp++;
  47. + if (tmp != buf)
  48. + memmove(buf, tmp, strlen(tmp)+1);
  49. + /* finally collapse whitespace */
  50. + tmp = buf;
  51. + while (tmp[0] && tmp[1]) {
  52. + if (isspace(tmp[0]) && isspace(tmp[1])) {
  53. + memmove(tmp, tmp+1, strlen(tmp));
  54. + continue;
  55. + }
  56. + ++tmp;
  57. + }
  58. +}
  59. +
  60. +static int __linux_procinfo(int x, char *fstr, size_t s)
  61. +{
  62. + FILE *fp;
  63. +
  64. + char *procinfo_keys[] = {
  65. + /* --processor --hardware-platform */
  66. + #if defined(__alpha__)
  67. + "cpu model", "system type"
  68. + #elif defined(__arm__)
  69. + "Processor", "Hardware"
  70. + #elif defined(__avr32__)
  71. + "processor", "cpu family"
  72. + #elif defined(__bfin__)
  73. + "CPU", "BOARD Name"
  74. + #elif defined(__cris__)
  75. + "cpu", "cpu model"
  76. + #elif defined(__frv__)
  77. + "CPU-Core", "System"
  78. + #elif defined(__i386__) || defined(__x86_64__)
  79. + "model name", "vendor_id"
  80. + #elif defined(__ia64__)
  81. + "family", "vendor"
  82. + #elif defined(__hppa__)
  83. + "cpu", "model"
  84. + #elif defined(__m68k__)
  85. + "CPU", "MMU"
  86. + #elif defined(__mips__)
  87. + "cpu model", "system type"
  88. + #elif defined(__powerpc__) || defined(__powerpc64__)
  89. + "cpu", "machine"
  90. + #elif defined(__s390__) || defined(__s390x__)
  91. + "Type", "Manufacturer"
  92. + #elif defined(__sh__)
  93. + "cpu type", "machine"
  94. + #elif defined(sparc) || defined(__sparc__)
  95. + "type", "cpu"
  96. + #elif defined(__vax__)
  97. + "cpu type", "cpu"
  98. + #else
  99. + "unknown", "unknown"
  100. + #endif
  101. + };
  102. +
  103. + if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
  104. + char key[65], value[257], eol, *ret = NULL;
  105. +
  106. + while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
  107. + __eat_cpuinfo_space(key);
  108. + if (!strcmp(key, procinfo_keys[x])) {
  109. + __eat_cpuinfo_space(value);
  110. + ret = value;
  111. + break;
  112. + }
  113. + if (eol != '\n') {
  114. + /* we need two fscanf's here in case the previous
  115. + * length limit caused us to read right up to the
  116. + * newline ... doing "%*[^\n]\n" wont eat the newline
  117. + */
  118. + fscanf(fp, "%*[^\n]");
  119. + fscanf(fp, "\n");
  120. + }
  121. + }
  122. + fclose(fp);
  123. +
  124. + if (ret) {
  125. + strncpy(fstr, ret, s);
  126. + return 0;
  127. + }
  128. + }
  129. +
  130. + return -1;
  131. +}
  132. +
  133. +#endif
  134. +
  135. /* Print ELEMENT, preceded by a space if something has already been
  136. printed. */
  137. @@ -250,10 +344,14 @@ main (int argc, char **argv)
  138. if (toprint & PRINT_PROCESSOR)
  139. {
  140. char const *element = unknown;
  141. -#if HAVE_SYSINFO && defined SI_ARCHITECTURE
  142. +#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
  143. {
  144. static char processor[257];
  145. +#if defined(USE_PROCINFO)
  146. + if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
  147. +#else
  148. if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
  149. +#endif
  150. element = processor;
  151. }
  152. #endif
  153. @@ -306,9 +404,13 @@ main (int argc, char **argv)
  154. if (element == unknown)
  155. {
  156. static char hardware_platform[257];
  157. +#if defined(USE_PROCINFO)
  158. + if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
  159. +#else
  160. size_t s = sizeof hardware_platform;
  161. static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
  162. if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
  163. +#endif
  164. element = hardware_platform;
  165. }
  166. #endif