breezed is a fan speed control daemon for Linux computers.
- Copyright (c) 2008 Francois Fleuret
+ Copyright (c) 2008, 2009 Francois Fleuret
Written by Francois Fleuret <francois@fleuret.org>
This file is part of breezed.
*/
-#include <iostream>
-#include <fstream>
-#include <cmath>
#include <stdio.h>
#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
+#include <unistd.h>
#include <string.h>
+#define BUFFER_SIZE 4096
+
using namespace std;
const int major_version_number = 1;
-const int minor_version_number = 1;
+const int minor_version_number = 2;
const int buffer_size = 1024;
-const char *default_confguration_file = "/etc/breezed.conf";
+const char *default_configuration_file = "/etc/breezed.conf";
// The time period to check the temperature.
const int polling_delay = 5;
int file_fan_fd;
-int nb_temperature_thresholds = 0;
+int nb_temperature_thresholds;
int *temperature_thresholds = 0;
int nb_file_thermal = 0;
while((*r != '\r') && (*r != '\n') && (*r != '\0') &&
(*r != '\t') && (*r != ' ') && (*r != ',')) {
if(s == buffer + buffer_size) {
- cerr << "Buffer overflow in next_word." << endl;
+ fprintf(stderr, "Buffer overflow in next_word.\n");
exit(1);
}
*s++ = *r++;
if(f < 0 || f > max_fan_level) f = max_fan_level;
sprintf(buffer, "level %d\n", f);
if(write(fan_fd, buffer, strlen(buffer)) < 0) {
- cerr << "Error in setting the fan level (" << strerror(errno) << ")."
- << endl;
+ fprintf(stderr, "Error in setting the fan level (%s).\n",
+ strerror(errno));
exit(1);
}
}
char token[buffer_size];
if(file_thermal) {
- cerr << "Thermal files already defined." << endl;
+ fprintf(stderr, "Thermal files already defined.\n");
exit(1);
}
char token[buffer_size];
if(temperature_thresholds) {
- cerr << "Temperature thresholds already defined." << endl;
+ fprintf(stderr, "Temperature thresholds already defined.\n");
exit(1);
}
+ nb_temperature_thresholds = 1;
+
char *s;
s = definition;
while(s) {
temperature_thresholds = new int[nb_temperature_thresholds];
+ temperature_thresholds[0] = -1;
+
s = definition;
- int k = 0;
+ int k = 1;
while(s) {
s = next_word(token, s, buffer_size);
temperature_thresholds[k] = atoi(token);
if(k > 0 &&
temperature_thresholds[k] < temperature_thresholds[k-1]) {
- cerr << "The temperature thresholds have to be increasing."
- << endl;
+ fprintf(stderr, "The temperature thresholds have to be increasing.\n");
exit(0);
}
k++;
}
-
- temperature_thresholds[0] = -1;
}
//////////////////////////////////////////////////////////////////////
char buffer[buffer_size], token[buffer_size];
- configuration_file = new char[strlen(default_confguration_file) + 1];
- strcpy(configuration_file, default_confguration_file);
+ configuration_file = new char[strlen(default_configuration_file) + 1];
+ strcpy(configuration_file, default_configuration_file);
int i = 1;
while(i < argc) {
}
else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
- cout << "Breezed, "
- << "v" << major_version_number
- << "." << minor_version_number
- << ". "
- << "Written by Francois Fleuret (francois@fleuret.org).\n";
+ printf("Breezed v%d.%d. Written by Francois Fleuret (francois@fleuret.org).\n",
+ major_version_number, minor_version_number);
exit(0);
}
strcmp(argv[i], "-cf") == 0) {
i++;
if(i == argc) {
- cerr << "Missing parameter for " << argv[i - 1] << endl;
+ fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
exit(1);
}
strcmp(argv[i], "-tf") == 0) {
i++;
if(i == argc) {
- cerr << "Missing parameter for " << argv[i - 1] << endl;
+ fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
exit(1);
}
define_thermal_files(argv[i]);
strcmp(argv[i], "-ff") == 0) {
i++;
if(i == argc) {
- cerr << "Missing parameter for " << argv[i - 1] << endl;
+ fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
exit(1);
}
if(file_fan) {
- cerr << "Fan file already defined." << endl;
+ fprintf(stderr, "Fan file already defined.\n");
exit(1);
}
file_fan = new char[strlen(argv[i]) + 1];
i++;
if(i == argc) {
- cerr << "Missing parameter for " << argv[i - 1] << endl;
+ fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
exit(1);
}
else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
- cout << argv[0] << " [--version|-v] [--help|-h] [--debug|-d]\\\n\
+ printf("%s [--version|-v] [--help|-h] [--debug|-d]\\\n\
[--configuration-file|-cf <file>]\\\n\
[--no-configuration-file|-ncf]\\\n\
[--thermal-files|-tf <thermalfile1,thermalfile2,...>] \\\n\
Options can be set either in the configuration file, or on the \n\
command line. Options can not be set twice.\n\
\n\
-Version " << major_version_number << "."
- << minor_version_number << ", December 2008.\n\
+Version %d.%d, November 2009.\n\
\n\
-Written by Francois Fleuret (francois@fleuret.org).\n";
+Written by Francois Fleuret (francois@fleuret.org).\n",
+ argv[0],
+ major_version_number, minor_version_number);
exit(0);
}
else {
- cerr << "Unknown argument " << argv[i] << "." << endl;
+ fprintf(stderr, "Unknown argument %s.\n", argv[i]);
exit(1);
}
}
//////////////////////////////////////////////////////////////////////
if(configuration_file) {
- ifstream cf(configuration_file);
- if(cf.fail()) {
- cerr << "Can not open " << configuration_file << " for reading." << endl;
+ char raw_line[BUFFER_SIZE];
+ int start, end, eol, k;
+ FILE *file;
+
+ file = fopen(configuration_file, "r");
+
+ if(!file) {
+ fprintf(stderr, "Can not open `%s' for reading.\n", configuration_file);
exit(1);
}
+ start = 0;
+ end = 0;
+
char *s;
int line_number = 0;
- while(!cf.eof()) {
- cf.getline(buffer, buffer_size);
+ while(end > start || !feof(file)) {
+ eol = start;
+
+ /* Look for the end of a line in what is already in the buffer */
+ while(eol < end && raw_line[eol] != '\n') eol++;
+
+ /* if we did not find the of a line, move what has not been
+ processed and is in the buffer to the beginning of the buffer,
+ fill the buffer with new data from the file, and look for the
+ end of a line */
+ if(eol == end) {
+ for(k = 0; k < end - start; k++) {
+ raw_line[k] = raw_line[k + start];
+ }
+ end -= start;
+ eol -= start;
+ start = 0;
+ end += fread(raw_line + end, sizeof(char), BUFFER_SIZE - end, file);
+ while(eol < end && raw_line[eol] != '\n') eol++;
+ }
+
+ /* The end of the line is the buffer size, which means the line is
+ too long */
+
+ if(eol == BUFFER_SIZE) {
+ raw_line[BUFFER_SIZE - 1] = '\0';
+ fprintf(stderr, "Selector: Line too long (max is %d characters):\n",
+ BUFFER_SIZE);
+ fprintf(stderr, raw_line);
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+
+ /* If we got a line, we replace the carriage return by a \0 to
+ finish the string */
+
+ raw_line[eol] = '\0';
+
+ /* here we process the line */
+
line_number++;
- s = next_word(token, buffer, buffer_size);
+ if(debug) {
+ printf("%s:%d \"%s\"\n",
+ configuration_file, line_number, raw_line + start);
+ }
+
+ s = next_word(token, raw_line + start, buffer_size);
if(strcmp(token, "thermal_files") == 0) {
if(s == 0) {
- cerr << "Missing parameter in "
- << configuration_file << ":" << line_number << endl;
+ fprintf(stderr, "Missing parameter in %s:%d\n",
+ configuration_file, line_number);
exit(1);
}
define_thermal_files(s);
else if(strcmp(token, "fan_file") == 0) {
if(file_fan) {
- cerr << "Fan file already defined." << endl;
+ fprintf(stderr, "Fan file already defined.\n");
exit(1);
}
if(s == 0) {
- cerr << "Missing parameter in "
- << configuration_file << ":" << line_number << endl;
+ fprintf(stderr, "Missing parameter in %s:%d\n",
+ configuration_file, line_number);
exit(1);
}
file_fan = new char[strlen(s) + 1];
else if(strcmp(token, "temperature_thresholds") == 0) {
if(s == 0) {
- cerr << "Missing parameter in "
- << configuration_file << ":" << line_number << endl;
+ fprintf(stderr, "Missing parameter in %s:%d\n",
+ configuration_file, line_number);
exit(1);
}
define_temperature_thresholds(s);
}
else if(token[0] && token[0] != '#') {
- cerr << "Unknown keyword '" << token << "' in "
- << configuration_file << ":" << line_number << endl;
+ fprintf(stderr, "Unknown keyword '%s' in %s:%d.\n",
+ token, configuration_file, line_number);
exit(1);
}
+
+ start = eol + 1;
}
+
}
//////////////////////////////////////////////////////////////////////
if(nb_temperature_thresholds == 0) {
- cerr << "No temperature threshold was provided." << endl;
+ fprintf(stderr, "No temperature threshold was provided.\n");
exit(1);
}
if(nb_file_thermal == 0) {
- cerr << "No thermal file was provided." << endl;
+ fprintf(stderr, "No thermal file was provided.\n");
exit(1);
}
if(file_fan == 0){
- cerr << "No fan file was provided." << endl;
+ fprintf(stderr, "No fan file was provided.\n");
exit(1);
}
for(int i = 0; i < nb_file_thermal; i++) {
file_thermal_fd[i] = open(file_thermal[i], O_RDONLY);
if(file_thermal_fd[i] < 0) {
- cerr << "Can not open " << file_thermal[i]
- << " for reading (" << strerror(errno) << ")."
- << endl;
+ fprintf(stderr, "Can not open %s for reading (%s).\n",
+ file_thermal[i], strerror(errno));
exit(1);
}
}
file_fan_fd = open(file_fan, O_WRONLY);
if(file_fan_fd < 0) {
- cerr << "Can not open " << file_fan
- << " for writing (" << strerror(errno) << ")."
- << endl;
+ fprintf(stderr, "Can not open %s for writing (%s).\n",
+ file_fan, strerror(errno));
exit(1);
}
if(debug) {
for(int t = 0; t < nb_file_thermal; t++) {
- cout << "file_thermal[" << t << "] " << file_thermal[t] << endl;
+ printf("file_thermal[%d] %s\n", t, file_thermal[t]);
}
- cout << "file_fan " << file_fan << endl;
+ printf("file_fan %s\n", file_fan);
for(int t = 0; t < nb_temperature_thresholds; t++) {
- cout << "temperature_thresholds[" << t << "] "
- << temperature_thresholds[t] << endl;
+ printf("temperature_thresholds[%d] %d",
+ t, temperature_thresholds[t]);
}
}
int temperature = -1;
if(debug) {
- cout << "Temperature:";
+ printf("Temperature:");
}
for(int i = 0; i < nb_file_thermal; i++) {
t *= sign;
if(debug) {
- cout << " " << t;
+ printf(" %d", t);
}
+ // So that we can deal with the new files where the
+ // temperature are in 1/1000th of C
+ if(t > 1000) t /= 1000;
+
if(t > temperature) temperature = t;
}
}
if(debug) {
if(i < nb_file_thermal - 1)
- cout << " /";
+ printf(" /");
else
- cout << endl;
+ printf("\n");
}
} else {
if(size == 0) {
- cerr << "Nothing to read in " << file_thermal[i] << endl;
+ fprintf(stderr, "Nothing to read in %d.\n", file_thermal[i]);
} else if(size < 0) {
- cerr << "Error while reading " << file_thermal[i]
- << " (" << strerror(errno) << ")." << endl;
+ fprintf(stderr, "Error while reading %s (%s).\n",
+ file_thermal[i], strerror(errno));
} else {
- cerr << "Error while reading " << file_thermal[i]
- << " (too large)." << endl;
+ fprintf(stderr, "Error while reading %s (too large).\n",
+ file_thermal[i]);
}
exit(1);
}
}
if(temperature < 0) {
- cerr << "Could not read a meaningful temperature." << endl;
+ fprintf(stderr, "Could not read a meaningful temperature.\n");
exit(1);
}
nb_rounds_since_last_change = 0;
last_level = new_level;
if(debug) {
- cout << "Temperature is " << temperature << "C,"
- << " setting the fan level to " << new_level
- << endl;
+ printf("Temperature is %dC setting the fan level to %d.",
+ temperature, new_level);
}
}