Commit 1f8131bd authored by Daniel Graziotin's avatar Daniel Graziotin

Fixes #18. Seems ready for v1.4.0

parent 03ac2050
...@@ -3,8 +3,7 @@ Fan-Control-Daemon ...@@ -3,8 +3,7 @@ Fan-Control-Daemon
Introduction Introduction
--------------------- ---------------------
This is an enhanced version of [rvega's Fan-Control-Daemon](https://github.com/rvega/Fan-Control-Daemon), This is an enhanced version of [Allan McRae mbpfan](http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/)
which itself is an enhanced version of [Allan McRae mbpfan](http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/)
Fan-Control-Daemon is a daemon that uses input from coretemp module and sets the fan speed using the applesmc module. Fan-Control-Daemon is a daemon that uses input from coretemp module and sets the fan speed using the applesmc module.
This enhanced version assumes any number of processors and fans (max. 10). This enhanced version assumes any number of processors and fans (max. 10).
...@@ -50,10 +49,6 @@ Compile with ...@@ -50,10 +49,6 @@ Compile with
make make
Manually compile with
gcc -o bin/mbpfan src/mbpfan.c -lm
Install Instructions Install Instructions
-------------------- --------------------
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
#!/bin/bash #!/bin/bash
# Archlinux rc script
# not maintained in this proejct # not maintained in this project
# please, fix it and contribute back to the project
daemon_name=mbpfan daemon_name=mbpfan
......
...@@ -34,10 +34,12 @@ int write_pid(int pid) ...@@ -34,10 +34,12 @@ int write_pid(int pid)
{ {
FILE *file = NULL; FILE *file = NULL;
file = fopen(program_pid, "w"); file = fopen(program_pid, "w");
if(file != NULL) { if(file != NULL) {
fprintf(file, "%d", pid); fprintf(file, "%d", pid);
fclose(file); fclose(file);
return 1; return 1;
} else { } else {
return 0; return 0;
} }
...@@ -48,11 +50,13 @@ int read_pid() ...@@ -48,11 +50,13 @@ int read_pid()
FILE *file = NULL; FILE *file = NULL;
int pid = -1; int pid = -1;
file = fopen(program_pid, "r"); file = fopen(program_pid, "r");
if(file != NULL) { if(file != NULL) {
fscanf(file, "%d", &pid); fscanf(file, "%d", &pid);
fclose(file); fclose(file);
return pid; return pid;
} }
return -1; return -1;
} }
...@@ -103,6 +107,7 @@ void go_daemon(void (*fan_control)()) ...@@ -103,6 +107,7 @@ void go_daemon(void (*fan_control)())
if(verbose) { if(verbose) {
setlogmask(LOG_UPTO(LOG_DEBUG)); setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER); openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
} else { } else {
setlogmask(LOG_UPTO(LOG_INFO)); setlogmask(LOG_UPTO(LOG_INFO));
openlog(program_name, LOG_CONS, LOG_USER); openlog(program_name, LOG_CONS, LOG_USER);
...@@ -115,9 +120,11 @@ void go_daemon(void (*fan_control)()) ...@@ -115,9 +120,11 @@ void go_daemon(void (*fan_control)())
if (daemonize) { if (daemonize) {
pid_slave = fork(); pid_slave = fork();
if (pid_slave < 0) { if (pid_slave < 0) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (pid_slave > 0) { if (pid_slave > 0) {
// kill the father // kill the father
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
...@@ -127,6 +134,7 @@ void go_daemon(void (*fan_control)()) ...@@ -127,6 +134,7 @@ void go_daemon(void (*fan_control)())
// new sid_slave for the child process // new sid_slave for the child process
sid_slave = setsid(); sid_slave = setsid();
if (sid_slave < 0) { if (sid_slave < 0) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
...@@ -151,23 +159,30 @@ void go_daemon(void (*fan_control)()) ...@@ -151,23 +159,30 @@ void go_daemon(void (*fan_control)())
printf("Writing a new .pid file with value %d at: %s\n", current_pid, program_pid); printf("Writing a new .pid file with value %d at: %s\n", current_pid, program_pid);
syslog(LOG_INFO, "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) { if (write_pid(current_pid) == 0) {
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid); syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
if (verbose) { if (verbose) {
printf("ERROR: Can not create a .pid file at: %s. Aborting\n", program_pid); printf("ERROR: Can not create a .pid file at: %s. Aborting\n", program_pid);
} }
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else { } else {
if (verbose) { if (verbose) {
printf("Successfully written a new .pid file with value %d at: %s\n", current_pid, program_pid); printf("Successfully written a new .pid file with value %d at: %s\n", current_pid, program_pid);
syslog(LOG_INFO, "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 { } else {
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid); syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
if (verbose) { if (verbose) {
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid); printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
} }
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
* *
*/ */
#ifndef _DAEMON_H_
#define _DAEMON_H_
/** /**
* Write the PID of the forked daemon to the * Write the PID of the forked daemon to the
...@@ -48,3 +50,5 @@ void signal_handler(int signal); ...@@ -48,3 +50,5 @@ void signal_handler(int signal);
* Daemonizes * Daemonizes
*/ */
int go_daemon(void (*function)()); int go_daemon(void (*function)());
#endif
\ No newline at end of file
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
extern int daemonize; extern int daemonize;
extern int verbose; extern int verbose;
extern const char* program_name; extern const char* program_name;
extern const char* program_pid; extern const char* program_pid;
struct s_sensors {
char* path;
char* fan_output_path;
char* fan_manual_path;
unsigned int temperature;
struct s_sensors *next;
};
typedef s_sensors t_sensors;
#endif
\ No newline at end of file
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
* *
*/ */
/**
* Code formatted with astyle -A3 -s --break-blocks=all --add-brackets *.c *.h
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
...@@ -46,6 +50,7 @@ int main(int argc, char *argv[]) ...@@ -46,6 +50,7 @@ int main(int argc, char *argv[])
{ {
int c; int c;
while( (c = getopt(argc, argv, "hftv|help")) != -1) { while( (c = getopt(argc, argv, "hftv|help")) != -1) {
switch(c) { switch(c) {
case 'h': case 'h':
......
...@@ -57,7 +57,7 @@ int max_temp = 86; // do not set it > 90 ...@@ -57,7 +57,7 @@ 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* path;
char* fan_output_path; char* fan_output_path;
...@@ -65,6 +65,9 @@ struct s_sensors { ...@@ -65,6 +65,9 @@ struct s_sensors {
unsigned int temperature; unsigned int temperature;
struct s_sensors *next; struct s_sensors *next;
}; };
*/
typedef struct s_sensors t_sensors;
t_sensors *retrieve_sensors() t_sensors *retrieve_sensors()
...@@ -82,6 +85,7 @@ t_sensors *retrieve_sensors() ...@@ -82,6 +85,7 @@ t_sensors *retrieve_sensors()
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);
...@@ -98,24 +102,33 @@ t_sensors *retrieve_sensors() ...@@ -98,24 +102,33 @@ t_sensors *retrieve_sensors()
s->path = (char *) malloc(sizeof( char ) * path_size); s->path = (char *) malloc(sizeof( char ) * path_size);
strcpy(s->path, path); strcpy(s->path, path);
fscanf(file, "%d", &s->temperature); fscanf(file, "%d", &s->temperature);
if (sensors_head == NULL) { if (sensors_head == NULL) {
sensors_head = s; sensors_head = s;
sensors_head->next = NULL; sensors_head->next = NULL;
} else { } else {
t_sensors *tmp = sensors_head; t_sensors *tmp = sensors_head;
while (tmp->next != NULL) { while (tmp->next != NULL) {
tmp = tmp->next; tmp = tmp->next;
} }
tmp->next = s; tmp->next = s;
tmp->next->next = NULL; tmp->next->next = NULL;
} }
fclose(file); fclose(file);
} }
free(path); free(path);
path = NULL; path = NULL;
} }
if(sensors_head != NULL)
if(sensors_head != NULL) {
find_fans(sensors_head); find_fans(sensors_head);
}
return sensors_head; return sensors_head;
} }
...@@ -162,6 +175,7 @@ void find_fans(t_sensors* sensors) ...@@ -162,6 +175,7 @@ void find_fans(t_sensors* sensors)
tmp->fan_output_path = (char *) malloc(sizeof( char ) * path_min_size); tmp->fan_output_path = (char *) malloc(sizeof( char ) * path_min_size);
tmp->fan_manual_path = (char *) malloc(sizeof( char ) * path_man_size); tmp->fan_manual_path = (char *) malloc(sizeof( char ) * path_man_size);
} }
strcpy(tmp->fan_output_path, path_output); strcpy(tmp->fan_output_path, path_output);
strcpy(tmp->fan_manual_path, path_manual); strcpy(tmp->fan_manual_path, path_manual);
tmp = tmp->next; tmp = tmp->next;
...@@ -173,6 +187,7 @@ void find_fans(t_sensors* sensors) ...@@ -173,6 +187,7 @@ void find_fans(t_sensors* sensors)
if(verbose) { if(verbose) {
printf("Found %d sensors and %d fans\n", n_sensors, n_fans); printf("Found %d sensors and %d fans\n", n_sensors, n_fans);
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Found %d sensors and %d fans", n_sensors, n_fans); syslog(LOG_INFO, "Found %d sensors and %d fans", n_sensors, n_fans);
} }
...@@ -189,12 +204,15 @@ void set_fans_man(t_sensors *sensors) ...@@ -189,12 +204,15 @@ 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_manual_path, "rw+"); file = fopen(tmp->fan_manual_path, "rw+");
if(file != NULL) { if(file != NULL) {
fprintf(file, "%d", 1); fprintf(file, "%d", 1);
fclose(file); fclose(file);
} }
tmp = tmp->next; tmp = tmp->next;
} }
} }
...@@ -214,6 +232,7 @@ t_sensors *refresh_sensors(t_sensors *sensors) ...@@ -214,6 +232,7 @@ t_sensors *refresh_sensors(t_sensors *sensors)
tmp = tmp->next; tmp = tmp->next;
} }
return sensors; return sensors;
} }
...@@ -223,8 +242,10 @@ void set_fan_speed(t_sensors* sensors, int speed) ...@@ -223,8 +242,10 @@ 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_output_path, "rw+"); file = fopen(tmp->fan_output_path, "rw+");
if(file != NULL) { if(file != NULL) {
fprintf(file, "%d", speed); fprintf(file, "%d", speed);
fclose(file); fclose(file);
...@@ -243,10 +264,12 @@ unsigned short get_temp(t_sensors* sensors) ...@@ -243,10 +264,12 @@ unsigned short get_temp(t_sensors* sensors)
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; sum_temp += tmp->temperature;
tmp = tmp->next; tmp = tmp->next;
} }
temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) ); temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) );
return temp; return temp;
} }
...@@ -262,35 +285,63 @@ void retrieve_settings() ...@@ -262,35 +285,63 @@ void retrieve_settings()
/* Could not open configfile */ /* Could not open configfile */
if(verbose) { if(verbose) {
printf("Couldn't open configfile, using defaults\n"); printf("Couldn't open configfile, using defaults\n");
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Couldn't open configfile, using defaults"); syslog(LOG_INFO, "Couldn't open configfile, using defaults");
} }
} }
} else { } else {
settings = settings_open(f); settings = settings_open(f);
fclose(f); fclose(f);
if (settings == NULL) { if (settings == NULL) {
/* Could not read configfile */ /* Could not read configfile */
if(verbose) { if(verbose) {
printf("Couldn't read configfile\n"); printf("Couldn't read configfile\n");
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Couldn't read configfile"); syslog(LOG_INFO, "Couldn't read configfile");
} }
} }
} else { } else {
/* Read configfile values */ /* Read configfile values */
result = settings_get_int(settings, "general", "min_fan_speed"); result = settings_get_int(settings, "general", "min_fan_speed");
if (result != 0) min_fan_speed = result;
if (result != 0) {
min_fan_speed = result;
}
result = settings_get_int(settings, "general", "max_fan_speed"); result = settings_get_int(settings, "general", "max_fan_speed");
if (result != 0) max_fan_speed = result;
if (result != 0) {
max_fan_speed = result;
}
result = settings_get_int(settings, "general", "low_temp"); result = settings_get_int(settings, "general", "low_temp");
if (result != 0) low_temp = result;
if (result != 0) {
low_temp = result;
}
result = settings_get_int(settings, "general", "high_temp"); result = settings_get_int(settings, "general", "high_temp");
if (result != 0) high_temp = result;
if (result != 0) {
high_temp = result;
}
result = settings_get_int(settings, "general", "max_temp"); result = settings_get_int(settings, "general", "max_temp");
if (result != 0) max_temp = result;
if (result != 0) {
max_temp = result;
}
result = settings_get_int(settings, "general", "polling_interval"); result = settings_get_int(settings, "general", "polling_interval");
if (result != 0) polling_interval = result;
if (result != 0) {
polling_interval = result;
}
/* Destroy the settings object */ /* Destroy the settings object */
settings_delete(settings); settings_delete(settings);
...@@ -316,10 +367,12 @@ void mbpfan() ...@@ -316,10 +367,12 @@ void mbpfan()
if(verbose) { if(verbose) {
printf("Sleeping for %d seconds\n", polling_interval); printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval); syslog(LOG_INFO, "Sleeping for %d seconds", 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 ) /
...@@ -354,6 +407,7 @@ void mbpfan() ...@@ -354,6 +407,7 @@ void mbpfan()
if(verbose) { if(verbose) {
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed); printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed); syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed);
} }
...@@ -363,10 +417,12 @@ void mbpfan() ...@@ -363,10 +417,12 @@ void mbpfan()
if(verbose) { if(verbose) {
printf("Sleeping for %d seconds\n", polling_interval); printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize) { if(daemonize) {
syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval); syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval);
} }
} }
sleep(polling_interval); sleep(polling_interval);
} }
} }
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
* *
*/ */
#ifndef _MBPFAN_H_
#define _MBPFAN_H_
/** Basic fan speed parameters /** Basic fan speed parameters
*/ */
extern int min_fan_speed; extern int min_fan_speed;
...@@ -83,3 +86,5 @@ unsigned short get_temp(t_sensors* sensors); ...@@ -83,3 +86,5 @@ unsigned short get_temp(t_sensors* sensors);
* Main Program * Main Program
*/ */
void mbpfan(); void mbpfan();
#endif
\ No newline at end of file
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <limits.h> #include <limits.h>
#include "global.h"
#include "mbpfan.h" #include "mbpfan.h"
#include "settings.h" #include "settings.h"
#include "minunit.h" #include "minunit.h"
...@@ -10,32 +11,41 @@ ...@@ -10,32 +11,41 @@
int tests_run = 0; int tests_run = 0;
static char *test_sensor_paths() static const char *test_sensor_paths()
{ {
t_sensors* sensors = retrieve_sensors(); t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL); mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors; t_sensors* tmp = sensors;
while(tmp != NULL) { while(tmp != NULL) {
mu_assert("Sensor does not have a valid path", tmp->path != NULL); mu_assert("Sensor does not have a valid path", tmp->path != NULL);
if(tmp->path != NULL)
if(tmp->path != NULL) {
mu_assert("Sensor does not have valid temperature", tmp->temperature > 0); mu_assert("Sensor does not have valid temperature", tmp->temperature > 0);
}
tmp = tmp->next; tmp = tmp->next;
} }
return 0; return 0;
} }
static char *test_fan_paths() static const char *test_fan_paths()
{ {
t_sensors* sensors = retrieve_sensors(); t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL); mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors; t_sensors* tmp = sensors;
int found_fan_path = 0; int found_fan_path = 0;
while(tmp != NULL) { while(tmp != NULL) {
if(tmp->fan_output_path != NULL) if(tmp->fan_output_path != NULL) {
found_fan_path++; found_fan_path++;
}
tmp = tmp->next; tmp = tmp->next;
} }
mu_assert("No fans found", found_fan_path != 0); mu_assert("No fans found", found_fan_path != 0);
return 0; return 0;
} }
...@@ -46,8 +56,11 @@ unsigned time_seed() ...@@ -46,8 +56,11 @@ unsigned time_seed()
unsigned char *p = (unsigned char *)&now; unsigned char *p = (unsigned char *)&now;
unsigned seed = 0; unsigned seed = 0;
size_t i; size_t i;
for ( i = 0; i < sizeof now; i++ )
for ( i = 0; i < sizeof now; i++ ) {
seed = seed * ( UCHAR_MAX + 2U ) + p[i]; seed = seed * ( UCHAR_MAX + 2U ) + p[i];
}
return seed; return seed;
} }
...@@ -56,17 +69,19 @@ unsigned time_seed() ...@@ -56,17 +69,19 @@ unsigned time_seed()
int stress(int n) int stress(int n)
{ {
int f = n; int f = n;
while (f > 0) { while (f > 0) {
while(n > 0) { while(n > 0) {
srand ( time_seed() ); srand ( time_seed() );
n--; n--;
} }
f--; f--;
n = f; n = f;
} }
} }
static char *test_get_temp() static const char *test_get_temp()
{ {
t_sensors* sensors = retrieve_sensors(); t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL); mu_assert("No sensors found", sensors != NULL);
...@@ -78,21 +93,24 @@ static char *test_get_temp() ...@@ -78,21 +93,24 @@ static char *test_get_temp()
return 0; return 0;
} }
static char *test_config_file() static const char *test_config_file()
{ {
FILE *f = NULL; FILE *f = NULL;
Settings *settings = NULL; Settings *settings = NULL;
f = fopen("/etc/mbpfan.conf", "r"); f = fopen("/etc/mbpfan.conf", "r");
mu_assert("No config file found", f != NULL); mu_assert("No config file found", f != NULL);
if (f == NULL) if (f == NULL) {
return 0; return 0;
}
settings = settings_open(f); settings = settings_open(f);
fclose(f); fclose(f);
mu_assert("Could not read settings from config file", settings != NULL); mu_assert("Could not read settings from config file", settings != NULL);
if (settings == NULL)
if (settings == NULL) {
return 0; return 0;
}
mu_assert("Could not read min_fan_speed from config file",settings_get_int(settings, "general", "min_fan_speed") != 0); mu_assert("Could not read min_fan_speed from config file",settings_get_int(settings, "general", "min_fan_speed") != 0);
mu_assert("Could not read max_fan_speed from config file",settings_get_int(settings, "general", "max_fan_speed") != 0); mu_assert("Could not read max_fan_speed from config file",settings_get_int(settings, "general", "max_fan_speed") != 0);
...@@ -107,7 +125,7 @@ static char *test_config_file() ...@@ -107,7 +125,7 @@ static char *test_config_file()
} }
static char *all_tests() static const char *all_tests()
{ {
mu_run_test(test_sensor_paths); mu_run_test(test_sensor_paths);
mu_run_test(test_fan_paths); mu_run_test(test_fan_paths);
...@@ -120,12 +138,15 @@ int tests() ...@@ -120,12 +138,15 @@ int tests()
{ {
printf("Starting the tests..\n"); printf("Starting the tests..\n");
printf("It is normal for them to take a bit to finish.\n"); printf("It is normal for them to take a bit to finish.\n");
char *result = all_tests(); const char *result = all_tests();
if (result != 0) { if (result != 0) {
printf("%s \n", result); printf("%s \n", result);
} else { } else {
printf("ALL TESTS PASSED\n"); printf("ALL TESTS PASSED\n");
} }
printf("Tests run: %d\n", tests_run); printf("Tests run: %d\n", tests_run);
return result != 0; return result != 0;
......
/** /**
* This is the MinUnit testing framework - http://www.jera.com/techinfo/jtns/jtn002.html * 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)
struct s_sensors { #ifndef _MINUNIT_H_
char* path; #define _MINUNIT_H_
char* fan_output_path;
char* fan_manual_path;
unsigned int temperature;
struct s_sensors *next;
};
typedef s_sensors t_sensors;
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { const char *message = test(); tests_run++; \
if (message) return message; } while (0)
extern int tests_run; extern int tests_run;
static char *test_sensor_paths(); static const char *test_sensor_paths();
static char *test_fan_paths(); static const char *test_fan_paths();
static char *test_get_temp(); static const char *test_get_temp();
static char *test_config_file(); static const char *test_config_file();
static char *all_tests(); static const char *all_tests();
int tests(); int tests();
#endif
\ No newline at end of file
This diff is collapsed.
...@@ -62,15 +62,19 @@ StrMap * sm_new(unsigned int capacity) ...@@ -62,15 +62,19 @@ StrMap * sm_new(unsigned int capacity)
StrMap *map; StrMap *map;
map = (StrMap*)malloc(sizeof(StrMap)); map = (StrMap*)malloc(sizeof(StrMap));
if (map == NULL) { if (map == NULL) {
return NULL; return NULL;
} }
map->count = capacity; map->count = capacity;
map->buckets = (Bucket*)malloc(map->count * sizeof(Bucket)); map->buckets = (Bucket*)malloc(map->count * sizeof(Bucket));
if (map->buckets == NULL) { if (map->buckets == NULL) {
free(map); free(map);
return NULL; return NULL;
} }
memset(map->buckets, 0, map->count * sizeof(Bucket)); memset(map->buckets, 0, map->count * sizeof(Bucket));
return map; return map;
} }
...@@ -84,23 +88,28 @@ void sm_delete(StrMap *map) ...@@ -84,23 +88,28 @@ void sm_delete(StrMap *map)
if (map == NULL) { if (map == NULL) {
return; return;
} }
n = map->count; n = map->count;
bucket = map->buckets; bucket = map->buckets;
i = 0; i = 0;
while (i < n) { while (i < n) {
m = bucket->count; m = bucket->count;
pair = bucket->pairs; pair = bucket->pairs;
j = 0; j = 0;
while(j < m) { while(j < m) {
free(pair->key); free(pair->key);
free(pair->value); free(pair->value);
pair++; pair++;
j++; j++;
} }
free(bucket->pairs); free(bucket->pairs);
bucket++; bucket++;
i++; i++;
} }
free(map->buckets); free(map->buckets);
free(map); free(map);
} }
...@@ -114,24 +123,31 @@ int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out ...@@ -114,24 +123,31 @@ int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned int n_out
if (map == NULL) { if (map == NULL) {
return 0; return 0;
} }
if (key == NULL) { if (key == NULL) {
return 0; return 0;
} }
index = hash(key) % map->count; index = hash(key) % map->count;
bucket = &(map->buckets[index]); bucket = &(map->buckets[index]);
pair = get_pair(bucket, key); pair = get_pair(bucket, key);
if (pair == NULL) { if (pair == NULL) {
return 0; return 0;
} }
if (out_buf == NULL && n_out_buf == 0) { if (out_buf == NULL && n_out_buf == 0) {
return strlen(pair->value) + 1; return strlen(pair->value) + 1;
} }
if (out_buf == NULL) { if (out_buf == NULL) {
return 0; return 0;
} }
if (strlen(pair->value) >= n_out_buf) { if (strlen(pair->value) >= n_out_buf) {
return 0; return 0;
} }
strcpy(out_buf, pair->value); strcpy(out_buf, pair->value);
return 1; return 1;
} }
...@@ -145,15 +161,19 @@ int sm_exists(const StrMap *map, const char *key) ...@@ -145,15 +161,19 @@ int sm_exists(const StrMap *map, const char *key)
if (map == NULL) { if (map == NULL) {
return 0; return 0;
} }
if (key == NULL) { if (key == NULL) {
return 0; return 0;
} }
index = hash(key) % map->count; index = hash(key) % map->count;
bucket = &(map->buckets[index]); bucket = &(map->buckets[index]);
pair = get_pair(bucket, key); pair = get_pair(bucket, key);
if (pair == NULL) { if (pair == NULL) {
return 0; return 0;
} }
return 1; return 1;
} }
...@@ -168,14 +188,17 @@ int sm_put(StrMap *map, const char *key, const char *value) ...@@ -168,14 +188,17 @@ int sm_put(StrMap *map, const char *key, const char *value)
if (map == NULL) { if (map == NULL) {
return 0; return 0;
} }
if (key == NULL || value == NULL) { if (key == NULL || value == NULL) {
return 0; return 0;
} }
key_len = strlen(key); key_len = strlen(key);
value_len = strlen(value); value_len = strlen(value);
/* Get a pointer to the bucket the key string hashes to */ /* Get a pointer to the bucket the key string hashes to */
index = hash(key) % map->count; index = hash(key) % map->count;
bucket = &(map->buckets[index]); bucket = &(map->buckets[index]);
/* Check if we can handle insertion by simply replacing /* Check if we can handle insertion by simply replacing
* an existing value in a key-value pair in the bucket. * an existing value in a key-value pair in the bucket.
*/ */
...@@ -188,50 +211,64 @@ int sm_put(StrMap *map, const char *key, const char *value) ...@@ -188,50 +211,64 @@ int sm_put(StrMap *map, const char *key, const char *value)
* space for the new larger value. * space for the new larger value.
*/ */
tmp_value = (char*)realloc(pair->value, (value_len + 1) * sizeof(char)); tmp_value = (char*)realloc(pair->value, (value_len + 1) * sizeof(char));
if (tmp_value == NULL) { if (tmp_value == NULL) {
return 0; return 0;
} }
pair->value = tmp_value; pair->value = tmp_value;
} }
/* Copy the new value into the pair that matches the key */ /* Copy the new value into the pair that matches the key */
strcpy(pair->value, value); strcpy(pair->value, value);
return 1; return 1;
} }
/* Allocate space for a new key and value */ /* Allocate space for a new key and value */
new_key = (char*)malloc((key_len + 1) * sizeof(char)); new_key = (char*)malloc((key_len + 1) * sizeof(char));
if (new_key == NULL) { if (new_key == NULL) {
return 0; return 0;
} }
new_value = (char*)malloc((value_len + 1) * sizeof(char)); new_value = (char*)malloc((value_len + 1) * sizeof(char));
if (new_value == NULL) { if (new_value == NULL) {
free(new_key); free(new_key);
return 0; return 0;
} }
/* Create a key-value pair */ /* Create a key-value pair */
if (bucket->count == 0) { if (bucket->count == 0) {
/* The bucket is empty, lazily allocate space for a single /* The bucket is empty, lazily allocate space for a single
* key-value pair. * key-value pair.
*/ */
bucket->pairs = (Pair*)malloc(sizeof(Pair)); bucket->pairs = (Pair*)malloc(sizeof(Pair));
if (bucket->pairs == NULL) { if (bucket->pairs == NULL) {
free(new_key); free(new_key);
free(new_value); free(new_value);
return 0; return 0;
} }
bucket->count = 1; bucket->count = 1;
} else { } else {
/* The bucket wasn't empty but no pair existed that matches the provided /* The bucket wasn't empty but no pair existed that matches the provided
* key, so create a new key-value pair. * key, so create a new key-value pair.
*/ */
tmp_pairs = (Pair*)realloc(bucket->pairs, (bucket->count + 1) * sizeof(Pair)); tmp_pairs = (Pair*)realloc(bucket->pairs, (bucket->count + 1) * sizeof(Pair));
if (tmp_pairs == NULL) { if (tmp_pairs == NULL) {
free(new_key); free(new_key);
free(new_value); free(new_value);
return 0; return 0;
} }
bucket->pairs = tmp_pairs; bucket->pairs = tmp_pairs;
bucket->count++; bucket->count++;
} }
/* Get the last pair in the chain for the bucket */ /* Get the last pair in the chain for the bucket */
pair = &(bucket->pairs[bucket->count - 1]); pair = &(bucket->pairs[bucket->count - 1]);
pair->key = new_key; pair->key = new_key;
...@@ -252,22 +289,27 @@ int sm_get_count(const StrMap *map) ...@@ -252,22 +289,27 @@ int sm_get_count(const StrMap *map)
if (map == NULL) { if (map == NULL) {
return 0; return 0;
} }
bucket = map->buckets; bucket = map->buckets;
n = map->count; n = map->count;
i = 0; i = 0;
count = 0; count = 0;
while (i < n) { while (i < n) {
pair = bucket->pairs; pair = bucket->pairs;
m = bucket->count; m = bucket->count;
j = 0; j = 0;
while (j < m) { while (j < m) {
count++; count++;
pair++; pair++;
j++; j++;
} }
bucket++; bucket++;
i++; i++;
} }
return count; return count;
} }
...@@ -280,24 +322,30 @@ int sm_enum(const StrMap *map, sm_enum_func enum_func, const void *obj) ...@@ -280,24 +322,30 @@ int sm_enum(const StrMap *map, sm_enum_func enum_func, const void *obj)
if (map == NULL) { if (map == NULL) {
return 0; return 0;
} }
if (enum_func == NULL) { if (enum_func == NULL) {
return 0; return 0;
} }
bucket = map->buckets; bucket = map->buckets;
n = map->count; n = map->count;
i = 0; i = 0;
while (i < n) { while (i < n) {
pair = bucket->pairs; pair = bucket->pairs;
m = bucket->count; m = bucket->count;
j = 0; j = 0;
while (j < m) { while (j < m) {
enum_func(pair->key, pair->value, obj); enum_func(pair->key, pair->value, obj);
pair++; pair++;
j++; j++;
} }
bucket++; bucket++;
i++; i++;
} }
return 1; return 1;
} }
...@@ -311,20 +359,25 @@ static Pair * get_pair(Bucket *bucket, const char *key) ...@@ -311,20 +359,25 @@ static Pair * get_pair(Bucket *bucket, const char *key)
Pair *pair; Pair *pair;
n = bucket->count; n = bucket->count;
if (n == 0) { if (n == 0) {
return NULL; return NULL;
} }
pair = bucket->pairs; pair = bucket->pairs;
i = 0; i = 0;
while (i < n) { while (i < n) {
if (pair->key != NULL && pair->value != NULL) { if (pair->key != NULL && pair->value != NULL) {
if (strcmp(pair->key, key) == 0) { if (strcmp(pair->key, key) == 0) {
return pair; return pair;
} }
} }
pair++; pair++;
i++; i++;
} }
return NULL; return NULL;
} }
...@@ -339,6 +392,7 @@ static unsigned long hash(const char *str) ...@@ -339,6 +392,7 @@ static unsigned long hash(const char *str)
while (c = *str++) { while (c = *str++) {
hash = ((hash << 5) + hash) + c; hash = ((hash << 5) + hash) + c;
} }
return hash; return hash;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment