Fixes #10
This commit is contained in:
parent
a6cc7a45b6
commit
1078814133
8 changed files with 550 additions and 336 deletions
|
@ -24,6 +24,11 @@ Compile with
|
||||||
Manually compile with
|
Manually compile with
|
||||||
gcc -o bin/mbpfan src/mbpfan.c -lm
|
gcc -o bin/mbpfan src/mbpfan.c -lm
|
||||||
|
|
||||||
|
Run The Tests (Recommended)
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
It is recommended to run the tests before installing the program
|
||||||
|
sudo ./bin/mbpfan -t
|
||||||
|
|
||||||
Install Instructions
|
Install Instructions
|
||||||
--------------------
|
--------------------
|
||||||
|
|
263
src/daemon.c
263
src/daemon.c
|
@ -29,150 +29,177 @@
|
||||||
#include "mbpfan.h"
|
#include "mbpfan.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
int write_pid(int pid){
|
int write_pid(int pid)
|
||||||
FILE *file = NULL;
|
{
|
||||||
file = fopen(program_pid, "w");
|
FILE *file = NULL;
|
||||||
if(file != NULL) {
|
file = fopen(program_pid, "w");
|
||||||
fprintf(file, "%d", pid);
|
if(file != NULL)
|
||||||
fclose(file);
|
{
|
||||||
return 1;
|
fprintf(file, "%d", pid);
|
||||||
}else{
|
fclose(file);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_pid(){
|
int read_pid()
|
||||||
FILE *file = NULL;
|
{
|
||||||
int pid = -1;
|
FILE *file = NULL;
|
||||||
file = fopen(program_pid, "r");
|
int pid = -1;
|
||||||
if(file != NULL) {
|
file = fopen(program_pid, "r");
|
||||||
fscanf(file, "%d", &pid);
|
if(file != NULL)
|
||||||
fclose(file);
|
{
|
||||||
return pid;
|
fscanf(file, "%d", &pid);
|
||||||
}
|
fclose(file);
|
||||||
return -1;
|
return pid;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_pid(){
|
int delete_pid()
|
||||||
return remove(program_pid);
|
{
|
||||||
|
return remove(program_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void signal_handler(int signal)
|
void signal_handler(int signal)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(signal) {
|
switch(signal)
|
||||||
case SIGHUP:
|
{
|
||||||
//TODO: restart myself
|
case SIGHUP:
|
||||||
syslog(LOG_WARNING, "Received SIGHUP signal.");
|
//TODO: restart myself
|
||||||
delete_pid();
|
syslog(LOG_WARNING, "Received SIGHUP signal.");
|
||||||
exit(0);
|
delete_pid();
|
||||||
break;
|
exit(0);
|
||||||
case SIGTERM:
|
break;
|
||||||
syslog(LOG_WARNING, "Received SIGTERM signal.");
|
case SIGTERM:
|
||||||
delete_pid();
|
syslog(LOG_WARNING, "Received SIGTERM signal.");
|
||||||
//TODO: free resources
|
delete_pid();
|
||||||
exit(0);
|
//TODO: free resources
|
||||||
break;
|
exit(0);
|
||||||
case SIGINT:
|
break;
|
||||||
syslog(LOG_WARNING, "Received SIGINT signal.");
|
case SIGINT:
|
||||||
delete_pid();
|
syslog(LOG_WARNING, "Received SIGINT signal.");
|
||||||
//TODO: free resources
|
delete_pid();
|
||||||
exit(0);
|
//TODO: free resources
|
||||||
default:
|
exit(0);
|
||||||
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
|
default:
|
||||||
break;
|
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void go_daemon(void (*fan_control)())
|
void go_daemon(void (*fan_control)())
|
||||||
{
|
{
|
||||||
|
|
||||||
// Setup signal handling before we start
|
// Setup signal handling before we start
|
||||||
signal(SIGHUP, signal_handler);
|
signal(SIGHUP, signal_handler);
|
||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
syslog(LOG_INFO, "%s starting up", program_name);
|
syslog(LOG_INFO, "%s starting up", program_name);
|
||||||
|
|
||||||
// Setup syslog logging - see SETLOGMASK(3)
|
// Setup syslog logging - see SETLOGMASK(3)
|
||||||
if(verbose) {
|
if(verbose)
|
||||||
setlogmask(LOG_UPTO(LOG_DEBUG));
|
{
|
||||||
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
|
setlogmask(LOG_UPTO(LOG_DEBUG));
|
||||||
} else {
|
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
|
||||||
setlogmask(LOG_UPTO(LOG_INFO));
|
}
|
||||||
openlog(program_name, LOG_CONS, LOG_USER);
|
else
|
||||||
|
{
|
||||||
|
setlogmask(LOG_UPTO(LOG_INFO));
|
||||||
|
openlog(program_name, LOG_CONS, LOG_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pid_t pid_slave;
|
||||||
|
pid_t sid_slave;
|
||||||
|
|
||||||
|
if (daemonize)
|
||||||
|
{
|
||||||
|
|
||||||
|
pid_slave = fork();
|
||||||
|
if (pid_slave < 0)
|
||||||
|
{
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (pid_slave > 0)
|
||||||
|
{
|
||||||
|
// kill the father
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
umask(0022);
|
||||||
|
|
||||||
|
// new sid_slave for the child process
|
||||||
|
sid_slave = setsid();
|
||||||
|
if (sid_slave < 0)
|
||||||
|
{
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((chdir("/")) < 0)
|
||||||
|
{
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pid_t pid_slave;
|
|
||||||
pid_t sid_slave;
|
|
||||||
|
|
||||||
if (daemonize) {
|
/* Close out the standard file descriptors */
|
||||||
|
close(STDIN_FILENO);
|
||||||
pid_slave = fork();
|
close(STDOUT_FILENO);
|
||||||
if (pid_slave < 0) {
|
close(STDERR_FILENO);
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
if (pid_slave > 0) {
|
|
||||||
// kill the father
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
umask(0022);
|
|
||||||
|
|
||||||
// new sid_slave for the child process
|
|
||||||
sid_slave = setsid();
|
|
||||||
if (sid_slave < 0) {
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((chdir("/")) < 0) {
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
int current_pid = getpid();
|
||||||
|
|
||||||
/* Close out the standard file descriptors */
|
if (read_pid() == -1)
|
||||||
close(STDIN_FILENO);
|
{
|
||||||
close(STDOUT_FILENO);
|
if (verbose)
|
||||||
close(STDERR_FILENO);
|
{
|
||||||
|
printf("Writing a new .pid file with value %d at: %s", current_pid, program_pid);
|
||||||
|
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, program_pid);
|
||||||
}
|
}
|
||||||
|
if (write_pid(current_pid) == 0)
|
||||||
|
{
|
||||||
int current_pid = getpid();
|
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
|
||||||
|
if (verbose)
|
||||||
if (read_pid() == -1){
|
{
|
||||||
if (verbose){
|
printf("ERROR: Can not create a .pid file at: %s. Aborting", program_pid);
|
||||||
printf("Writing a new .pid file with value %d at: %s", current_pid, program_pid);
|
}
|
||||||
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, program_pid);
|
exit(EXIT_FAILURE);
|
||||||
}
|
|
||||||
if (write_pid(current_pid) == 0){
|
|
||||||
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
|
|
||||||
if (verbose){
|
|
||||||
printf("ERROR: Can not create a .pid file at: %s. Aborting", program_pid);
|
|
||||||
}
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}else{
|
|
||||||
if (verbose){
|
|
||||||
printf("Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
|
|
||||||
syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
|
|
||||||
if (verbose){
|
|
||||||
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
|
|
||||||
}
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fan_control();
|
if (verbose)
|
||||||
|
{
|
||||||
if(daemonize){
|
printf("Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
|
||||||
syslog(LOG_INFO, "%s daemon exiting", program_name);
|
syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
|
||||||
|
}
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
fan_control();
|
||||||
|
|
||||||
|
if(daemonize)
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "%s daemon exiting", program_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ int read_pid();
|
||||||
* Return TRUE on success
|
* Return TRUE on success
|
||||||
* Return FALSE otherwise
|
* Return FALSE otherwise
|
||||||
*/
|
*/
|
||||||
int delete_pid();
|
int delete_pid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ...handles signals :-)
|
* ...handles signals :-)
|
||||||
|
|
71
src/main.c
71
src/main.c
|
@ -19,6 +19,7 @@
|
||||||
#include "mbpfan.h"
|
#include "mbpfan.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "minunit.h"
|
||||||
|
|
||||||
int daemonize = 1;
|
int daemonize = 1;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
@ -28,41 +29,51 @@ const char *program_pid = "/var/run/mbpfan.pid";
|
||||||
|
|
||||||
void print_usage(int argc, char *argv[])
|
void print_usage(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc >=1) {
|
if (argc >=1)
|
||||||
printf("Usage: %s OPTION(S) \n", argv[0]);
|
{
|
||||||
printf("Options:\n");
|
printf("Usage: %s OPTION(S) \n", argv[0]);
|
||||||
printf("\t-h Show this help screen\n");
|
printf("Options:\n");
|
||||||
printf("\t-f Run in foreground\n");
|
printf("\t-h Show this help screen\n");
|
||||||
printf("\t-v Be (a lot) verbose\n");
|
printf("\t-f Run in foreground\n");
|
||||||
printf("\n");
|
printf("\t-t Run the tests\n");
|
||||||
}
|
printf("\t-v Be (a lot) verbose\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while( (c = getopt(argc, argv, "hfv|help")) != -1) {
|
while( (c = getopt(argc, argv, "hftv|help")) != -1)
|
||||||
switch(c) {
|
{
|
||||||
case 'h':
|
switch(c)
|
||||||
print_usage(argc, argv);
|
{
|
||||||
exit(0);
|
case 'h':
|
||||||
break;
|
print_usage(argc, argv);
|
||||||
case 'f':
|
exit(0);
|
||||||
daemonize = 0;
|
break;
|
||||||
break;
|
case 'f':
|
||||||
case 'v':
|
daemonize = 0;
|
||||||
verbose = 1;
|
break;
|
||||||
break;
|
case 't':
|
||||||
default:
|
tests();
|
||||||
print_usage(argc, argv);
|
exit(0);
|
||||||
exit(0);
|
break;
|
||||||
break;
|
case 'v':
|
||||||
}
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_usage(argc, argv);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pointer to mbpfan() function in mbpfan.c
|
// pointer to mbpfan() function in mbpfan.c
|
||||||
void (*fan_control)() = mbpfan;
|
void (*fan_control)() = mbpfan;
|
||||||
go_daemon(fan_control);
|
go_daemon(fan_control);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
402
src/mbpfan.c
402
src/mbpfan.c
|
@ -55,161 +55,177 @@ int max_temp = 86; // do not set it > 90
|
||||||
int polling_interval = 7;
|
int polling_interval = 7;
|
||||||
|
|
||||||
|
|
||||||
struct s_sensors {
|
struct s_sensors
|
||||||
char* path;
|
{
|
||||||
char* fan_min_path;
|
char* path;
|
||||||
char* fan_man_path;
|
char* fan_min_path;
|
||||||
unsigned int temperature;
|
char* fan_man_path;
|
||||||
struct s_sensors *next;
|
unsigned int temperature;
|
||||||
|
struct s_sensors *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
t_sensors *retrieve_sensors()
|
t_sensors *retrieve_sensors()
|
||||||
{
|
{
|
||||||
|
|
||||||
t_sensors *sensors_head = NULL;
|
t_sensors *sensors_head = NULL;
|
||||||
t_sensors *s = NULL;
|
t_sensors *s = NULL;
|
||||||
|
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
const char *path_begin = "/sys/devices/platform/coretemp.0/temp";
|
const char *path_begin = "/sys/devices/platform/coretemp.0/temp";
|
||||||
const char *path_end = "_input";
|
const char *path_end = "_input";
|
||||||
|
|
||||||
int path_size = strlen(path_begin) + strlen(path_end) + 2;
|
int path_size = strlen(path_begin) + strlen(path_end) + 2;
|
||||||
char number[1];
|
char number[1];
|
||||||
sprintf(number,"%d",0);
|
sprintf(number,"%d",0);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i = 0; i<10; i++) {
|
for(i = 0; i<10; i++)
|
||||||
path = (char*) malloc(sizeof( char ) * path_size);
|
{
|
||||||
|
path = (char*) malloc(sizeof( char ) * path_size);
|
||||||
|
|
||||||
sprintf(number,"%d",i);
|
sprintf(number,"%d",i);
|
||||||
path[0] = '\0';
|
path[0] = '\0';
|
||||||
strncat( path, path_begin, strlen(path_begin) );
|
strncat( path, path_begin, strlen(path_begin) );
|
||||||
strncat( path, number, strlen(number) );
|
strncat( path, number, strlen(number) );
|
||||||
strncat( path, path_end, strlen(path_begin) );
|
strncat( path, path_end, strlen(path_begin) );
|
||||||
|
|
||||||
FILE *file = fopen(path, "r");
|
FILE *file = fopen(path, "r");
|
||||||
|
|
||||||
if(file != NULL) {
|
if(file != NULL)
|
||||||
s = (t_sensors *) malloc( sizeof( t_sensors ) );
|
{
|
||||||
s->path = (char *) malloc(sizeof( char ) * path_size);
|
s = (t_sensors *) malloc( sizeof( t_sensors ) );
|
||||||
strcpy(s->path, path);
|
s->path = (char *) malloc(sizeof( char ) * path_size);
|
||||||
fscanf(file, "%d", &s->temperature);
|
strcpy(s->path, path);
|
||||||
if (sensors_head == NULL) {
|
fscanf(file, "%d", &s->temperature);
|
||||||
sensors_head = s;
|
if (sensors_head == NULL)
|
||||||
sensors_head->next = NULL;
|
{
|
||||||
} else {
|
sensors_head = s;
|
||||||
t_sensors *tmp = sensors_head;
|
sensors_head->next = NULL;
|
||||||
while (tmp->next != NULL) {
|
}
|
||||||
tmp = tmp->next;
|
else
|
||||||
}
|
{
|
||||||
tmp->next = s;
|
t_sensors *tmp = sensors_head;
|
||||||
tmp->next->next = NULL;
|
while (tmp->next != NULL)
|
||||||
}
|
{
|
||||||
fclose(file);
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
free(path);
|
tmp->next = s;
|
||||||
path = NULL;
|
tmp->next->next = NULL;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
if(sensors_head != NULL)
|
free(path);
|
||||||
find_fans(sensors_head);
|
path = NULL;
|
||||||
return sensors_head;
|
}
|
||||||
|
if(sensors_head != NULL)
|
||||||
|
find_fans(sensors_head);
|
||||||
|
return sensors_head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void find_fans(t_sensors* sensors)
|
void find_fans(t_sensors* sensors)
|
||||||
{
|
{
|
||||||
t_sensors *tmp = sensors;
|
t_sensors *tmp = sensors;
|
||||||
|
|
||||||
char *path_min = NULL;
|
char *path_min = NULL;
|
||||||
char *path_man = NULL;
|
char *path_man = NULL;
|
||||||
|
|
||||||
const char *path_begin = "/sys/devices/platform/applesmc.768/fan";
|
const char *path_begin = "/sys/devices/platform/applesmc.768/fan";
|
||||||
const char *path_min_end = "_min";
|
const char *path_min_end = "_min";
|
||||||
const char *path_man_end = "_manual";
|
const char *path_man_end = "_manual";
|
||||||
|
|
||||||
int path_min_size = strlen(path_begin) + strlen(path_min_end) + 2;
|
int path_min_size = strlen(path_begin) + strlen(path_min_end) + 2;
|
||||||
int path_man_size = strlen(path_begin) + strlen(path_man_end) + 2;
|
int path_man_size = strlen(path_begin) + strlen(path_man_end) + 2;
|
||||||
char number[1];
|
char number[1];
|
||||||
sprintf(number,"%d",0);
|
sprintf(number,"%d",0);
|
||||||
|
|
||||||
int n_sensors = 0;
|
int n_sensors = 0;
|
||||||
int n_fans = 0;
|
int n_fans = 0;
|
||||||
|
|
||||||
for(n_sensors = 0; n_sensors<10; n_sensors++) {
|
for(n_sensors = 0; n_sensors<10; n_sensors++)
|
||||||
path_min = (char*) malloc(sizeof( char ) * path_min_size);
|
{
|
||||||
path_min[0] = '\0';
|
path_min = (char*) malloc(sizeof( char ) * path_min_size);
|
||||||
path_man = (char*) malloc(sizeof( char ) * path_man_size);
|
path_min[0] = '\0';
|
||||||
path_man[0] = '\0';
|
path_man = (char*) malloc(sizeof( char ) * path_man_size);
|
||||||
sprintf(number,"%d",n_sensors);
|
path_man[0] = '\0';
|
||||||
|
sprintf(number,"%d",n_sensors);
|
||||||
|
|
||||||
strncat( path_min, path_begin, strlen(path_begin) );
|
strncat( path_min, path_begin, strlen(path_begin) );
|
||||||
strncat( path_min, number, strlen(number) );
|
strncat( path_min, number, strlen(number) );
|
||||||
strncat( path_min, path_min_end, strlen(path_begin) );
|
strncat( path_min, path_min_end, strlen(path_begin) );
|
||||||
|
|
||||||
strncat( path_man, path_begin, strlen(path_begin) );
|
strncat( path_man, path_begin, strlen(path_begin) );
|
||||||
strncat( path_man, number, strlen(number) );
|
strncat( path_man, number, strlen(number) );
|
||||||
strncat( path_man, path_man_end, strlen(path_begin) );
|
strncat( path_man, path_man_end, strlen(path_begin) );
|
||||||
|
|
||||||
|
|
||||||
FILE *file = fopen(path_min, "r");
|
FILE *file = fopen(path_min, "r");
|
||||||
|
|
||||||
if(file != NULL) {
|
if(file != NULL)
|
||||||
if (tmp->path != NULL) {
|
{
|
||||||
tmp->fan_min_path = (char *) malloc(sizeof( char ) * path_min_size);
|
if (tmp->path != NULL)
|
||||||
tmp->fan_man_path = (char *) malloc(sizeof( char ) * path_man_size);
|
{
|
||||||
}
|
tmp->fan_min_path = (char *) malloc(sizeof( char ) * path_min_size);
|
||||||
strcpy(tmp->fan_min_path, path_min);
|
tmp->fan_man_path = (char *) malloc(sizeof( char ) * path_man_size);
|
||||||
strcpy(tmp->fan_man_path, path_man);
|
}
|
||||||
tmp = tmp->next;
|
strcpy(tmp->fan_min_path, path_min);
|
||||||
n_fans++;
|
strcpy(tmp->fan_man_path, path_man);
|
||||||
fclose(file);
|
tmp = tmp->next;
|
||||||
}
|
n_fans++;
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(verbose) {
|
if(verbose)
|
||||||
printf("Found %d: sensors and %d fans\n", n_sensors, n_fans);
|
{
|
||||||
if(daemonize) {
|
printf("Found %d: sensors and %d fans\n", n_sensors, n_fans);
|
||||||
syslog(LOG_INFO, "Found %d: sensors and %d fans", n_sensors, n_fans);
|
if(daemonize)
|
||||||
}
|
{
|
||||||
|
syslog(LOG_INFO, "Found %d: sensors and %d fans", n_sensors, n_fans);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(path_min);
|
free(path_min);
|
||||||
path_min = NULL;
|
path_min = NULL;
|
||||||
free(path_man);
|
free(path_man);
|
||||||
path_man = NULL;
|
path_man = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_fans_man(t_sensors *sensors)
|
void set_fans_man(t_sensors *sensors)
|
||||||
{
|
{
|
||||||
|
|
||||||
t_sensors *tmp = sensors;
|
t_sensors *tmp = sensors;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
while(tmp != NULL) {
|
while(tmp != NULL)
|
||||||
file = fopen(tmp->fan_man_path, "rw+");
|
{
|
||||||
if(file != NULL) {
|
file = fopen(tmp->fan_man_path, "rw+");
|
||||||
fprintf(file, "%d", 0);
|
if(file != NULL)
|
||||||
fclose(file);
|
{
|
||||||
}
|
fprintf(file, "%d", 0);
|
||||||
tmp = tmp->next;
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_sensors *refresh_sensors(t_sensors *sensors)
|
t_sensors *refresh_sensors(t_sensors *sensors)
|
||||||
{
|
{
|
||||||
|
|
||||||
t_sensors *tmp = sensors;
|
t_sensors *tmp = sensors;
|
||||||
|
|
||||||
while(tmp != NULL) {
|
while(tmp != NULL)
|
||||||
FILE *file = fopen(tmp->path, "r");
|
{
|
||||||
|
FILE *file = fopen(tmp->path, "r");
|
||||||
|
|
||||||
if(file != NULL) {
|
if(file != NULL)
|
||||||
fscanf(file, "%d", &tmp->temperature);
|
{
|
||||||
fclose(file);
|
fscanf(file, "%d", &tmp->temperature);
|
||||||
}
|
fclose(file);
|
||||||
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
}
|
||||||
return sensors;
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
return sensors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,18 +233,20 @@ t_sensors *refresh_sensors(t_sensors *sensors)
|
||||||
/* Controls the speed of the fan */
|
/* Controls the speed of the fan */
|
||||||
void set_fan_speed(t_sensors* sensors, int speed)
|
void set_fan_speed(t_sensors* sensors, int speed)
|
||||||
{
|
{
|
||||||
t_sensors *tmp = sensors;
|
t_sensors *tmp = sensors;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
while(tmp != NULL) {
|
while(tmp != NULL)
|
||||||
file = fopen(tmp->fan_min_path, "rw+");
|
{
|
||||||
if(file != NULL) {
|
file = fopen(tmp->fan_min_path, "rw+");
|
||||||
fprintf(file, "%d", speed);
|
if(file != NULL)
|
||||||
fclose(file);
|
{
|
||||||
}
|
fprintf(file, "%d", speed);
|
||||||
|
fclose(file);
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,85 +254,97 @@ void set_fan_speed(t_sensors* sensors, int speed)
|
||||||
/* Returns average CPU temp in degrees (ceiling) */
|
/* Returns average CPU temp in degrees (ceiling) */
|
||||||
unsigned short get_temp(t_sensors* sensors)
|
unsigned short get_temp(t_sensors* sensors)
|
||||||
{
|
{
|
||||||
sensors = refresh_sensors(sensors);
|
sensors = refresh_sensors(sensors);
|
||||||
int sum_temp = 0;
|
int sum_temp = 0;
|
||||||
unsigned short temp = 0;
|
unsigned short temp = 0;
|
||||||
|
|
||||||
t_sensors* tmp = sensors;
|
t_sensors* tmp = sensors;
|
||||||
while(tmp != NULL) {
|
while(tmp != NULL)
|
||||||
sum_temp += tmp->temperature;
|
{
|
||||||
tmp = tmp->next;
|
sum_temp += tmp->temperature;
|
||||||
}
|
tmp = tmp->next;
|
||||||
temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) );
|
}
|
||||||
return temp;
|
temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) );
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mbpfan()
|
void mbpfan()
|
||||||
{
|
{
|
||||||
int old_temp, new_temp, fan_speed, steps;
|
int old_temp, new_temp, fan_speed, steps;
|
||||||
int temp_change;
|
int temp_change;
|
||||||
int step_up, step_down;
|
int step_up, step_down;
|
||||||
|
|
||||||
t_sensors* sensors = retrieve_sensors();
|
t_sensors* sensors = retrieve_sensors();
|
||||||
set_fans_man(sensors);
|
set_fans_man(sensors);
|
||||||
new_temp = get_temp(sensors);
|
new_temp = get_temp(sensors);
|
||||||
fan_speed = 2000;
|
fan_speed = 2000;
|
||||||
set_fan_speed(sensors, fan_speed);
|
set_fan_speed(sensors, fan_speed);
|
||||||
|
|
||||||
if(verbose) {
|
if(verbose)
|
||||||
printf("Sleeping for %d seconds\n", polling_interval);
|
{
|
||||||
if(daemonize) {
|
printf("Sleeping for %d seconds\n", polling_interval);
|
||||||
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
|
if(daemonize)
|
||||||
}
|
{
|
||||||
|
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
|
||||||
}
|
}
|
||||||
sleep(polling_interval);
|
}
|
||||||
|
sleep(polling_interval);
|
||||||
|
|
||||||
step_up = (float)( max_fan_speed - min_fan_speed ) /
|
step_up = (float)( max_fan_speed - min_fan_speed ) /
|
||||||
(float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 );
|
(float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 );
|
||||||
|
|
||||||
step_down = (float)( max_fan_speed - min_fan_speed ) /
|
step_down = (float)( max_fan_speed - min_fan_speed ) /
|
||||||
(float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 );
|
(float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 );
|
||||||
|
|
||||||
while(1) {
|
while(1)
|
||||||
old_temp = new_temp;
|
{
|
||||||
new_temp = get_temp(sensors);
|
old_temp = new_temp;
|
||||||
|
new_temp = get_temp(sensors);
|
||||||
|
|
||||||
if(new_temp >= max_temp && fan_speed != max_fan_speed) {
|
if(new_temp >= max_temp && fan_speed != max_fan_speed)
|
||||||
fan_speed = max_fan_speed;
|
{
|
||||||
}
|
fan_speed = max_fan_speed;
|
||||||
|
|
||||||
if(new_temp <= low_temp && fan_speed != min_fan_speed) {
|
|
||||||
fan_speed = min_fan_speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_change = new_temp - old_temp;
|
|
||||||
|
|
||||||
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) {
|
|
||||||
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
|
|
||||||
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) {
|
|
||||||
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
|
|
||||||
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if(verbose) {
|
|
||||||
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
|
|
||||||
if(daemonize) {
|
|
||||||
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_fan_speed(sensors, fan_speed);
|
|
||||||
|
|
||||||
if(verbose) {
|
|
||||||
printf("Sleeping for %d seconds\n", polling_interval);
|
|
||||||
if(daemonize) {
|
|
||||||
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sleep(polling_interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(new_temp <= low_temp && fan_speed != min_fan_speed)
|
||||||
|
{
|
||||||
|
fan_speed = min_fan_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_change = new_temp - old_temp;
|
||||||
|
|
||||||
|
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp)
|
||||||
|
{
|
||||||
|
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
|
||||||
|
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp)
|
||||||
|
{
|
||||||
|
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
|
||||||
|
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
{
|
||||||
|
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
|
||||||
|
if(daemonize)
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_fan_speed(sensors, fan_speed);
|
||||||
|
|
||||||
|
if(verbose)
|
||||||
|
{
|
||||||
|
printf("Sleeping for %d seconds\n", polling_interval);
|
||||||
|
if(daemonize)
|
||||||
|
{
|
||||||
|
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(polling_interval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,11 @@ void find_fans(t_sensors *sensors);
|
||||||
*/
|
*/
|
||||||
void set_fans_man(t_sensors *sensors);
|
void set_fans_man(t_sensors *sensors);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return average CPU temp in degrees (ceiling)
|
||||||
|
*/
|
||||||
|
unsigned short get_temp(t_sensors* sensors);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Program
|
* Main Program
|
||||||
*/
|
*/
|
||||||
|
|
120
src/minunit.c
Normal file
120
src/minunit.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/* file minunit_example.c */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "mbpfan.h"
|
||||||
|
#include "minunit.h"
|
||||||
|
|
||||||
|
int tests_run = 0;
|
||||||
|
|
||||||
|
|
||||||
|
struct s_sensors
|
||||||
|
{
|
||||||
|
char* path;
|
||||||
|
char* fan_min_path;
|
||||||
|
char* fan_man_path;
|
||||||
|
unsigned int temperature;
|
||||||
|
struct s_sensors *next;
|
||||||
|
};
|
||||||
|
typedef s_sensors t_sensors;
|
||||||
|
|
||||||
|
|
||||||
|
static char *test_sensor_paths()
|
||||||
|
{
|
||||||
|
t_sensors* sensors = retrieve_sensors();
|
||||||
|
mu_assert("No sensors found", sensors != NULL);
|
||||||
|
t_sensors* tmp = sensors;
|
||||||
|
while(tmp != NULL)
|
||||||
|
{
|
||||||
|
mu_assert("Sensor does not have a valid path", tmp->path != NULL);
|
||||||
|
if(tmp->path != NULL)
|
||||||
|
mu_assert("Sensor does not have valid temperature", tmp->temperature > 0);
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *test_fan_paths()
|
||||||
|
{
|
||||||
|
t_sensors* sensors = retrieve_sensors();
|
||||||
|
mu_assert("No sensors found", sensors != NULL);
|
||||||
|
t_sensors* tmp = sensors;
|
||||||
|
int found_fan_path = 0;
|
||||||
|
while(tmp != NULL)
|
||||||
|
{
|
||||||
|
if(tmp->fan_min_path != NULL)
|
||||||
|
found_fan_path++;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
mu_assert("No fans found", found_fan_path != 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned time_seed()
|
||||||
|
{
|
||||||
|
time_t now = time ( 0 );
|
||||||
|
unsigned char *p = (unsigned char *)&now;
|
||||||
|
unsigned seed = 0;
|
||||||
|
size_t i;
|
||||||
|
for ( i = 0; i < sizeof now; i++ )
|
||||||
|
seed = seed * ( UCHAR_MAX + 2U ) + p[i];
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing better than a horrible piece of code to
|
||||||
|
// stress a little bit the CPU
|
||||||
|
int stress(int n)
|
||||||
|
{
|
||||||
|
int f = n;
|
||||||
|
while (f > 0)
|
||||||
|
{
|
||||||
|
while(n > 0)
|
||||||
|
{
|
||||||
|
srand ( time_seed() );
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
f--;
|
||||||
|
n = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *test_get_temp()
|
||||||
|
{
|
||||||
|
t_sensors* sensors = retrieve_sensors();
|
||||||
|
mu_assert("No sensors found", sensors != NULL);
|
||||||
|
unsigned short temp_1 = get_temp(sensors);
|
||||||
|
mu_assert("Invalid Global Temperature Found", temp_1 > 1 && temp_1 < 150);
|
||||||
|
stress(2000);
|
||||||
|
unsigned short temp_2 = get_temp(sensors);
|
||||||
|
mu_assert("Invalid Higher temp test (if fan was already spinning high, this is not worrying)", temp_1 < temp_2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *all_tests()
|
||||||
|
{
|
||||||
|
mu_run_test(test_sensor_paths);
|
||||||
|
mu_run_test(test_fan_paths);
|
||||||
|
mu_run_test(test_get_temp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tests()
|
||||||
|
{
|
||||||
|
printf("Starting the tests..\n");
|
||||||
|
printf("It is normal for them to take a bit to finish.\n");
|
||||||
|
char *result = all_tests();
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
printf("%s \n", result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ALL TESTS PASSED\n");
|
||||||
|
}
|
||||||
|
printf("Tests run: %d\n", tests_run);
|
||||||
|
|
||||||
|
return result != 0;
|
||||||
|
}
|
16
src/minunit.h
Normal file
16
src/minunit.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* This is the MinUnit testing framework - http://www.jera.com/techinfo/jtns/jtn002.html
|
||||||
|
*/
|
||||||
|
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
|
||||||
|
#define mu_run_test(test) do { char *message = test(); tests_run++; \
|
||||||
|
if (message) return message; } while (0)
|
||||||
|
|
||||||
|
extern int tests_run;
|
||||||
|
|
||||||
|
static char *test_sensor_paths();
|
||||||
|
static char *test_fan_paths();
|
||||||
|
static char *test_get_temp();
|
||||||
|
|
||||||
|
static char *all_tests();
|
||||||
|
|
||||||
|
int tests();
|
Loading…
Reference in a new issue