From 1dcd928c430f4f2d080e9ac9b0515b1bd20f7fc0 Mon Sep 17 00:00:00 2001 From: radekchalupa Date: Sun, 2 Feb 2025 21:49:51 +0100 Subject: [PATCH] =?UTF-8?q?Nahr=C3=A1ny=20soubory=20do=20=E2=80=9E/?= =?UTF-8?q?=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 20 ++++++ main.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 Makefile create mode 100644 main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2f24753 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +CC = gcc +CFLAGS = -Wall -pedantic -Werror -std=gnu99 -O2 +target = rc-status-sensors +source = main.c +#valgrind = -ggdb3 + +$(target): Makefile $(source) + $(CC) $(CFLAGS) -o $(target) $(source) + +clean: + rm -f $(target) + +runvg: + valgrind -s --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=vg.txt ./rc-status-sensors + cat vg.txt + +install: $(target) + @echo "Instaluji" + cp -f $(target) /usr/local/bin + sync diff --git a/main.c b/main.c new file mode 100644 index 0000000..d9bb3a0 --- /dev/null +++ b/main.c @@ -0,0 +1,200 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#define MAX_LABEL_LENGTH 32 +#define PARAM_SHORT_VIEW 1 +#define PARAM_MAX_ONLY 1 << 2 + +typedef struct { + float cpu; + float cpu_cores[64]; + float acpi_sensors[16]; + unsigned int cpu_cores_count; + unsigned int acpi_sensors_count; +} thermal_sensors; + +static void show_help(void) +{ + puts("parametry:"); + puts(" -m zobrazi pouze maximalni hodnoty"); + puts(" -s kratky vypis"); + puts(" -l "); +} + +static int load_sensors(thermal_sensors *sensors) +{ + memset(sensors, 0, sizeof(thermal_sensors)); + char buffer[1024]; + FILE *p_file = popen("sensors", "r"); + if (NULL == p_file) + return errno; + float dval; + const unsigned int section_cpu = 1; + const unsigned int section_acpitz = 0; + unsigned int section = 0; + size_t index_acpitz = 0; + size_t index_cpu = 0; + size_t max_cpu_count = sizeof(sensors->cpu_cores) / sizeof(float); + size_t max_acpi_count = sizeof(sensors->acpi_sensors) / sizeof(float); + char pattern[64]; + while (!feof(p_file)) { + if (index_acpitz >= max_acpi_count) + break; + if (index_cpu >= max_cpu_count) + break; + if (fgets(buffer, sizeof(buffer), p_file) != NULL) { + if (*buffer == '\n') { + section = 0; + continue; + } + if (0 == strncasecmp(buffer, "coretemp", 8)) { + section = section_cpu; + continue; + } + if (0 == strncasecmp(buffer, "acpitz", 6)) { + section = section_acpitz; + continue; + } + if (section_cpu == section) { + if (sscanf(buffer, "Package id 0: %f", &dval) == 1) { + sensors->cpu = dval; + continue; + } + (void)sprintf(pattern, "Core %d: ", (int)index_cpu); + (void)strncat(pattern, "%f", + sizeof(pattern) - strlen(pattern) - 1); + if (sscanf(buffer, pattern, &dval) == 1) { + sensors->cpu_cores[index_cpu] = dval; + index_cpu++; + continue; + } + } + else if (section_acpitz == section) { + (void)sprintf(pattern, "temp%d: ", (int)index_acpitz+1); + (void)strncat(pattern, "%f", + sizeof(pattern) - strlen(pattern) - 1); + if (sscanf(buffer, pattern, &dval) == 1) { + sensors->acpi_sensors[index_acpitz] = dval; + ++index_acpitz; + continue; + } + } + } + else + break; + } + sensors->cpu_cores_count = index_cpu; + sensors->acpi_sensors_count = index_acpitz; + (void)pclose(p_file); + return (index_cpu > 0 || index_acpitz > 0) ? 1 : -1; +} + +static void print_sensors_info_line(thermal_sensors *sensors, + const char *szlabel, uint_fast32_t params) { + if (szlabel && (*szlabel != 0)) { + printf(szlabel); + printf(" "); + } + float max_core = 0; + for (size_t i = 0; i < sensors->cpu_cores_count; ++i) { + if (sensors->cpu_cores[i] > max_core) + max_core = sensors->cpu_cores[i]; + } + if (params & PARAM_MAX_ONLY) { + if (params & PARAM_SHORT_VIEW) + (void)printf("%.0f°", + sensors->cpu > max_core ? sensors->cpu : max_core); + else + (void)printf("cpu: %.0f°C acpi:", + sensors->cpu > max_core ? sensors->cpu : max_core); + float max_acpi = 0.0; + for (size_t i = 0; i < sensors->acpi_sensors_count; ++i) { + if (sensors->acpi_sensors[i] > max_acpi) + max_acpi = sensors->acpi_sensors[i]; + } + if (params & PARAM_SHORT_VIEW) + (void)printf(" %.0f°", max_acpi); + else + (void)printf(" %.0f°C", max_acpi); + } + else { + if (params & PARAM_SHORT_VIEW) + (void)printf("%.0f° %.0f°, ", sensors->cpu, max_core); + else + (void)printf("cpu: %.0f°C %.0f°C acpi:", sensors->cpu, max_core); + for (size_t i = 0; i < sensors->acpi_sensors_count; ++i) { + if (params & PARAM_SHORT_VIEW) + (void)printf(" %.0f°", sensors->acpi_sensors[i]); + else + (void)printf(" %.0f°C", sensors->acpi_sensors[i]); + } + } + (void)printf("\n"); +} + +int main(int argc, char **argv) +{ + int opt; + uint_fast32_t params = 0; + char szlabel[MAX_LABEL_LENGTH]; + *szlabel = 0; + if (argc > 1) { + while ((opt = getopt(argc, argv, "mshl:")) != -1) { + switch (opt) { + case 'l': + if (strlen(optarg) <= sizeof(szlabel) - 1) + strcpy(szlabel, optarg); + break; + case 'm': + params |= PARAM_MAX_ONLY; + break; + case 's': + params |= PARAM_SHORT_VIEW; + break; + case 'h': + show_help(); + return EXIT_SUCCESS; + break; + } + } + } + thermal_sensors sensors; + int retval = load_sensors(&sensors); + if (-1 == retval) + return EXIT_FAILURE; + print_sensors_info_line(&sensors, szlabel, params); + return EXIT_SUCCESS; +}