123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /*
- htop - generic/uname.c
- (C) 2021 htop dev team
- Released under the GNU GPLv2+, see the COPYING file
- in the source distribution for its full text.
- */
- #include "config.h" // IWYU pragma: keep
- #include "generic/uname.h"
- #include <stdbool.h>
- #include <stdio.h>
- #include <string.h>
- #include "Macros.h"
- #include "XUtils.h"
- #ifdef HAVE_SYS_UTSNAME_H
- #include <sys/utsname.h>
- #endif
- #ifndef OSRELEASEFILE
- #define OSRELEASEFILE "/etc/os-release"
- #endif
- static void parseOSRelease(char* buffer, size_t bufferLen) {
- FILE* fp = fopen(OSRELEASEFILE, "r");
- if (!fp) {
- xSnprintf(buffer, bufferLen, "No OS Release");
- return;
- }
- char name[64] = {'\0'};
- char version[64] = {'\0'};
- char lineBuffer[256];
- while (fgets(lineBuffer, sizeof(lineBuffer), fp)) {
- if (String_startsWith(lineBuffer, "PRETTY_NAME=\"")) {
- const char* start = lineBuffer + strlen("PRETTY_NAME=\"");
- const char* stop = strrchr(lineBuffer, '"');
- if (!stop || stop <= start)
- continue;
- String_safeStrncpy(buffer, start, MINIMUM(bufferLen, (size_t)(stop - start + 1)));
- fclose(fp);
- return;
- }
- if (String_startsWith(lineBuffer, "NAME=\"")) {
- const char* start = lineBuffer + strlen("NAME=\"");
- const char* stop = strrchr(lineBuffer, '"');
- if (!stop || stop <= start)
- continue;
- String_safeStrncpy(name, start, MINIMUM(sizeof(name), (size_t)(stop - start + 1)));
- continue;
- }
- if (String_startsWith(lineBuffer, "VERSION=\"")) {
- const char* start = lineBuffer + strlen("VERSION=\"");
- const char* stop = strrchr(lineBuffer, '"');
- if (!stop || stop <= start)
- continue;
- String_safeStrncpy(version, start, MINIMUM(sizeof(version), (size_t)(stop - start + 1)));
- continue;
- }
- }
- fclose(fp);
- snprintf(buffer, bufferLen, "%s%s%s", name[0] ? name : "", name[0] && version[0] ? " " : "", version);
- }
- char* Generic_uname(void) {
- static char savedString[
- /* uname structure fields - manpages recommend sizeof */
- sizeof(((struct utsname*)0)->sysname) +
- sizeof(((struct utsname*)0)->release) +
- sizeof(((struct utsname*)0)->machine) +
- 16/*markup*/ +
- 128/*distro*/] = {'\0'};
- static bool loaded_data = false;
- if (!loaded_data) {
- struct utsname uname_info;
- int uname_result = uname(&uname_info);
- char distro[128];
- parseOSRelease(distro, sizeof(distro));
- if (uname_result == 0) {
- size_t written = xSnprintf(savedString, sizeof(savedString), "%s %s [%s]", uname_info.sysname, uname_info.release, uname_info.machine);
- if (!String_contains_i(savedString, distro, false) && sizeof(savedString) > written)
- snprintf(savedString + written, sizeof(savedString) - written, " @ %s", distro);
- } else {
- snprintf(savedString, sizeof(savedString), "%s", distro);
- }
- loaded_data = true;
- }
- return savedString;
- }
|