2 * Copyright (c) 2007 Daniel Borca All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "../sensors.h"
33 spawn_sync_read (const char *filename
, const char *const argv
[], int max
, char *out
)
55 dup2(fd
[WRITE
], STDOUT_FILENO
);
57 exit(execvp(filename
, (char *const *)argv
));
62 for (--max
, size
= 0, eof
= 0; !eof
;) {
64 int chunk
= read(fd
[READ
], buf
, sizeof(buf
));
68 eof
= (chunk
< (int)sizeof(buf
));
69 if (size
+ chunk
> max
) {
72 memcpy(&out
[size
], buf
, chunk
);
88 sensors_nvidia (const char *setting
, int *val
)
90 const char *argv
[] = { "nvidia-settings", "-q" , NULL
, NULL
};
94 argv
[2] = (char *)setting
;
100 if (spawn_sync_read(argv
[0], argv
, sizeof(out
), out
) < 0) {
104 if (sscanf(out
, " Attribute %*s %*s %d", val
) != 1) {
113 sensors_read_line (const char *filename
, int max
, char *out
)
117 f
= fopen(filename
, "rt");
121 if (fgets(out
, max
, f
) == NULL
) {
126 p
= strchr(out
, '\n');
136 add_sensor (SENSOR
*list
, const char *filename
, const char *name
, SENSOR_TYPE type
)
141 s
= malloc(sizeof(SENSOR
));
149 case S_ACPI_THERMAL_ZONE
:
150 p
= malloc(strlen(filename
) + 32);
154 strcat(strcpy(p
, filename
), "/trip_points");
156 if (sensors_read_line(p
, sizeof(buf
), buf
) > 0) {
157 sscanf(buf
, "%*s %*s %d", &s
->idata
);
159 s
->filename
= strcat(strcpy(p
, filename
), "/temperature");
160 s
->name
= strdup(name
);
161 if (s
->name
== NULL
) {
165 list_append(list
, s
);
167 case S_ACPI_AC_ADAPTER
:
168 p
= malloc(strlen(filename
) + 32);
172 s
->filename
= strcat(strcpy(p
, filename
), "/state");
173 s
->name
= strdup(name
);
174 if (s
->name
== NULL
) {
178 list_append(list
, s
);
181 p
= malloc(strlen(filename
) + 32);
185 s
->filename
= strcat(strcpy(p
, filename
), "/");
186 s
->name
= strdup(name
);
187 if (s
->name
== NULL
) {
191 list_append(list
, s
);
193 case S_HWMON_CORETEMP
:
194 p
= malloc(strlen(filename
) + 32);
198 strcat(strcpy(p
, filename
), "/device/name");
199 if (sensors_read_line(p
, sizeof(buf
), buf
) <= 0) {
203 if (strcmp(buf
, "coretemp")) {
207 strcat(strcpy(p
, filename
), "/device/temp1_crit");
209 if (sensors_read_line(p
, sizeof(buf
), buf
) > 0) {
210 sscanf(buf
, "%d", &s
->idata
);
212 strcat(strcpy(p
, filename
), "/device/temp1_label");
213 if (sensors_read_line(p
, sizeof(buf
), buf
) > 0) {
214 s
->name
= strdup(buf
);
216 s
->name
= strdup(name
);
218 s
->filename
= strcat(strcpy(p
, filename
), "/device/temp1_input");
219 if (s
->name
== NULL
) {
223 list_append(list
, s
);
225 case S_NVIDIA_SETTINGS_GPUCORETEMP
:
226 if (sensors_nvidia(name
, NULL
) != 0) {
229 p
= strdup(filename
);
234 s
->name
= strdup(name
);
235 if (s
->name
== NULL
) {
239 list_append(list
, s
);
249 scan_dirs (const char *dirname
, SENSOR
*list
, SENSOR_TYPE type
)
252 int len
= strlen(dirname
);
254 dir
= opendir(dirname
);
257 while ((ent
= readdir(dir
))) {
258 if (strcmp(ent
->d_name
, ".") && strcmp(ent
->d_name
, "..")) {
259 char *fullname
= malloc(len
+ 1 + strlen(ent
->d_name
) + 1);
260 if (fullname
!= NULL
) {
263 strcpy(fullname
, dirname
);
264 if (fullname
[l
- 1] != '/') {
267 strcpy(&fullname
[l
], ent
->d_name
);
268 /* don't use d_type */
269 if (stat(fullname
, &buf
) == 0 && S_ISDIR(buf
.st_mode
)) {
270 add_sensor(list
, fullname
, ent
->d_name
, type
);
286 list
= malloc(sizeof(SENSOR
));
294 scan_dirs("/proc/acpi/thermal_zone", list
, S_ACPI_THERMAL_ZONE
);
295 scan_dirs("/proc/acpi/ac_adapter", list
, S_ACPI_AC_ADAPTER
);
296 scan_dirs("/proc/acpi/battery", list
, S_ACPI_BATTERY
);
297 scan_dirs("/sys/class/hwmon", list
, S_HWMON_CORETEMP
);
298 add_sensor(list
, "nvidia-settings", "GPUCoreTemp", S_NVIDIA_SETTINGS_GPUCORETEMP
);
305 sensors_free (SENSOR
*list
)
309 list_foreach_s (s
, tmp
, list
) {
312 free((char *)s
->name
);