breezed is a fan speed control daemon for Linux computers.
- Copyright (c) 2008, 2009 Francois Fleuret
+ Copyright (c) 2008, 2009, 2010 Francois Fleuret
Written by Francois Fleuret <francois@fleuret.org>
This file is part of breezed.
#include <string.h>
const int major_version_number = 1;
-const int minor_version_number = 2;
+const int minor_version_number = 4;
const int buffer_size = 1024;
int nb_temperature_thresholds;
int *temperature_thresholds = 0;
+char **speed_names = 0;
int nb_file_thermal = 0;
char **file_thermal = 0;
char *configuration_file;
+/********************************************************************/
+
+/* malloc with error checking. */
+
+void *safe_malloc(size_t n) {
+ void *p = malloc(n);
+ if (!p && n != 0) {
+ fprintf(stderr, "Can not allocate memory: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ return p;
+}
+
/******************************************************************/
char *next_word(char *buffer, char *r, int buffer_size) {
(*r != '\t') && (*r != ' ') && (*r != ',')) {
if(s == buffer + buffer_size) {
fprintf(stderr, "Buffer overflow in next_word.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
*s++ = *r++;
}
void set_fan_level(int fan_fd, int f, int max_fan_level) {
char buffer[buffer_size];
if(f < 0 || f > max_fan_level) f = max_fan_level;
- sprintf(buffer, "level %d\n", f);
+ sprintf(buffer, "level %s\n", speed_names[f]);
if(write(fan_fd, buffer, strlen(buffer)) < 0) {
fprintf(stderr, "Error in setting the fan level (%s).\n",
strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
}
if(file_thermal) {
fprintf(stderr, "Thermal files already defined.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
char *s;
nb_file_thermal++;
}
- file_thermal = (char **) malloc(nb_file_thermal * sizeof(char *));
- file_thermal_fd = (int *) malloc(nb_file_thermal * sizeof(int));
+ file_thermal = safe_malloc(nb_file_thermal * sizeof(char *));
+ file_thermal_fd = safe_malloc(nb_file_thermal * sizeof(int));
s = definition;
int k = 0;
while(s) {
if(temperature_thresholds) {
fprintf(stderr, "Temperature thresholds already defined.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
- nb_temperature_thresholds = 1;
+ nb_temperature_thresholds = 0;
+
+ char *s, *u;
- char *s;
s = definition;
while(s) {
s = next_word(token, s, buffer_size);
}
temperature_thresholds =
- (int *) malloc(nb_temperature_thresholds * sizeof(int));
+ safe_malloc(nb_temperature_thresholds * sizeof(int));
- temperature_thresholds[0] = -1;
+ speed_names =
+ safe_malloc(nb_temperature_thresholds * sizeof(char *));
s = definition;
- int k = 1;
+ int k = 0;
while(s) {
s = next_word(token, s, buffer_size);
- temperature_thresholds[k] = atoi(token);
+ u = token;
+ while(*u && *u != ':') { u++; }
+ if(*u) {
+ *u = '\0';
+ temperature_thresholds[k] = atoi(token);
+ u++;
+ speed_names[k] = strdup(u);
+ } else {
+ temperature_thresholds[k] = atoi(token);
+ snprintf(token, buffer_size, "%d", k);
+ speed_names[k] = strdup(token);
+ }
+
if(k > 0 &&
temperature_thresholds[k] < temperature_thresholds[k-1]) {
fprintf(stderr, "The temperature thresholds have to be increasing.\n");
- exit(0);
+ exit(EXIT_FAILURE);
}
k++;
}
+
+ if(nb_temperature_thresholds <= 0) {
+ fprintf(stderr, "There has to be at least one temperature.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(temperature_thresholds[0] > 0) {
+ fprintf(stderr, "The lowest temperature has to be 0.\n");
+ exit(EXIT_FAILURE);
+ }
+
}
void evaluate_one_configuration_line(char *line, int line_number) {
if(s == 0) {
fprintf(stderr, "Missing parameter in %s:%d\n",
configuration_file, line_number);
- exit(1);
+ exit(EXIT_FAILURE);
}
define_thermal_files(s);
}
else if(strcmp(token, "fan_file") == 0) {
if(file_fan) {
fprintf(stderr, "Fan file already defined.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
if(s == 0) {
fprintf(stderr, "Missing parameter in %s:%d\n",
configuration_file, line_number);
- exit(1);
+ exit(EXIT_FAILURE);
}
file_fan = strdup(s);
}
if(s == 0) {
fprintf(stderr, "Missing parameter in %s:%d\n",
configuration_file, line_number);
- exit(1);
+ exit(EXIT_FAILURE);
}
define_temperature_thresholds(s);
}
else if(token[0] && token[0] != '#') {
fprintf(stderr, "Unknown keyword '%s' in %s:%d.\n",
token, configuration_file, line_number);
- exit(1);
+ exit(EXIT_FAILURE);
}
}
i++;
if(i == argc) {
fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
- exit(1);
+ exit(EXIT_FAILURE);
}
free(configuration_file);
i++;
if(i == argc) {
fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
- exit(1);
+ exit(EXIT_FAILURE);
}
define_thermal_files(argv[i]);
i++;
i++;
if(i == argc) {
fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
- exit(1);
+ exit(EXIT_FAILURE);
}
if(file_fan) {
fprintf(stderr, "Fan file already defined.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
file_fan = strdup(argv[i]);
if(i == argc) {
fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
- exit(1);
+ exit(EXIT_FAILURE);
}
define_temperature_thresholds(argv[i]);
else {
fprintf(stderr, "Unknown argument %s.\n", argv[i]);
- exit(1);
+ exit(EXIT_FAILURE);
}
}
if(!file) {
fprintf(stderr, "Can not open `%s' for reading.\n", configuration_file);
- exit(1);
+ exit(EXIT_FAILURE);
}
start = 0;
buffer_size);
fprintf(stderr, raw_line);
fprintf(stderr, "\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
/* If we got a line, we replace the carriage return by a \0 to
if(nb_temperature_thresholds == 0) {
fprintf(stderr, "No temperature threshold was provided.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
if(nb_file_thermal == 0) {
fprintf(stderr, "No thermal file was provided.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
if(file_fan == 0){
fprintf(stderr, "No fan file was provided.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
for(i = 0; i < nb_file_thermal; i++) {
if(file_thermal_fd[i] < 0) {
fprintf(stderr, "Can not open %s for reading (%s).\n",
file_thermal[i], strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
}
if(file_fan_fd < 0) {
fprintf(stderr, "Can not open %s for writing (%s).\n",
file_fan, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
/******************************************************************/
printf("file_fan %s\n", file_fan);
for(t = 0; t < nb_temperature_thresholds; t++) {
- printf("temperature_thresholds[%d] %d",
- t, temperature_thresholds[t]);
+ printf("temperature_thresholds[%d] = %d speed_names[%d] = \"%s\"\n",
+ t, temperature_thresholds[t],
+ t, speed_names[t]);
}
}
fprintf(stderr, "Error while reading %s (too large).\n",
file_thermal[i]);
}
- exit(1);
+ exit(EXIT_FAILURE);
}
}
if(temperature < 0) {
fprintf(stderr, "Could not read a meaningful temperature.\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
nb_rounds_since_last_change++;
/* We set it every time, even when there is no change, to handle
when the level has been modified somewhere else (for instance
- when combing back from suspend). */
+ when coming back from suspend). */
set_fan_level(file_fan_fd, new_level, nb_temperature_thresholds - 1);
nb_rounds_since_last_change = 0;
last_level = new_level;
if(debug) {
- printf("Temperature is %dC setting the fan level to %d.",
- temperature, new_level);
+ printf("Temperature is %dC setting the fan level to %d (%s).\n",
+ temperature,
+ new_level,
+ speed_names[new_level]);
}
}