200 lines
5.7 KiB
C
200 lines
5.7 KiB
C
/*
|
|
* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <getopt.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#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 <nadpis>");
|
|
}
|
|
|
|
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;
|
|
}
|