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