Commit 10788141 authored by Daniel Graziotin's avatar Daniel Graziotin

Fixes #10

parent a6cc7a45
......@@ -24,6 +24,11 @@ Compile with
Manually compile with
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
--------------------
......
......@@ -29,150 +29,177 @@
#include "mbpfan.h"
#include "global.h"
int write_pid(int pid){
FILE *file = NULL;
file = fopen(program_pid, "w");
if(file != NULL) {
fprintf(file, "%d", pid);
fclose(file);
return 1;
}else{
return 0;
}
int write_pid(int pid)
{
FILE *file = NULL;
file = fopen(program_pid, "w");
if(file != NULL)
{
fprintf(file, "%d", pid);
fclose(file);
return 1;
}
else
{
return 0;
}
}
int read_pid(){
FILE *file = NULL;
int pid = -1;
file = fopen(program_pid, "r");
if(file != NULL) {
fscanf(file, "%d", &pid);
fclose(file);
return pid;
}
return -1;
int read_pid()
{
FILE *file = NULL;
int pid = -1;
file = fopen(program_pid, "r");
if(file != NULL)
{
fscanf(file, "%d", &pid);
fclose(file);
return pid;
}
return -1;
}
int delete_pid(){
return remove(program_pid);
int delete_pid()
{
return remove(program_pid);
}
void signal_handler(int signal)
{
switch(signal) {
case SIGHUP:
//TODO: restart myself
syslog(LOG_WARNING, "Received SIGHUP signal.");
delete_pid();
exit(0);
break;
case SIGTERM:
syslog(LOG_WARNING, "Received SIGTERM signal.");
delete_pid();
//TODO: free resources
exit(0);
break;
case SIGINT:
syslog(LOG_WARNING, "Received SIGINT signal.");
delete_pid();
//TODO: free resources
exit(0);
default:
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
break;
}
switch(signal)
{
case SIGHUP:
//TODO: restart myself
syslog(LOG_WARNING, "Received SIGHUP signal.");
delete_pid();
exit(0);
break;
case SIGTERM:
syslog(LOG_WARNING, "Received SIGTERM signal.");
delete_pid();
//TODO: free resources
exit(0);
break;
case SIGINT:
syslog(LOG_WARNING, "Received SIGINT signal.");
delete_pid();
//TODO: free resources
exit(0);
default:
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
break;
}
}
void go_daemon(void (*fan_control)())
{
// Setup signal handling before we start
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
// Setup signal handling before we start
signal(SIGHUP, signal_handler);
signal(SIGTERM, 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)
if(verbose) {
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
} else {
setlogmask(LOG_UPTO(LOG_INFO));
openlog(program_name, LOG_CONS, LOG_USER);
}
// Setup syslog logging - see SETLOGMASK(3)
if(verbose)
{
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
}
else
{
setlogmask(LOG_UPTO(LOG_INFO));
openlog(program_name, LOG_CONS, LOG_USER);
}
pid_t pid_slave;
pid_t sid_slave;
pid_t pid_slave;
pid_t sid_slave;
if (daemonize) {
if (daemonize)
{
pid_slave = fork();
if (pid_slave < 0) {
exit(EXIT_FAILURE);
}
if (pid_slave > 0) {
// kill the father
exit(EXIT_SUCCESS);
}
pid_slave = fork();
if (pid_slave < 0)
{
exit(EXIT_FAILURE);
}
if (pid_slave > 0)
{
// kill the father
exit(EXIT_SUCCESS);
}
umask(0022);
umask(0022);
// new sid_slave for the child process
sid_slave = setsid();
if (sid_slave < 0) {
exit(EXIT_FAILURE);
}
// new sid_slave for the child process
sid_slave = setsid();
if (sid_slave < 0)
{
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0) {
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0)
{
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
int current_pid = getpid();
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (read_pid() == -1)
{
if (verbose)
{
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);
}
int current_pid = getpid();
if (read_pid() == -1){
if (verbose){
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){
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);
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);
}
fan_control();
if(daemonize){
syslog(LOG_INFO, "%s daemon exiting", program_name);
}
fan_control();
if(daemonize)
{
syslog(LOG_INFO, "%s daemon exiting", program_name);
}
return;
return;
}
......@@ -36,7 +36,7 @@ int read_pid();
* Return TRUE on success
* Return FALSE otherwise
*/
int delete_pid();
int delete_pid();
/**
* ...handles signals :-)
......
......@@ -12,13 +12,14 @@
* GNU General Public License for more details.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mbpfan.h"
#include "daemon.h"
#include "global.h"
#include "minunit.h"
int daemonize = 1;
int verbose = 0;
......@@ -28,41 +29,51 @@ const char *program_pid = "/var/run/mbpfan.pid";
void print_usage(int argc, char *argv[])
{
if (argc >=1) {
printf("Usage: %s OPTION(S) \n", argv[0]);
printf("Options:\n");
printf("\t-h Show this help screen\n");
printf("\t-f Run in foreground\n");
printf("\t-v Be (a lot) verbose\n");
printf("\n");
}
if (argc >=1)
{
printf("Usage: %s OPTION(S) \n", argv[0]);
printf("Options:\n");
printf("\t-h Show this help screen\n");
printf("\t-f Run in foreground\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 c;
while( (c = getopt(argc, argv, "hfv|help")) != -1) {
switch(c) {
case 'h':
print_usage(argc, argv);
exit(0);
break;
case 'f':
daemonize = 0;
break;
case 'v':
verbose = 1;
break;
default:
print_usage(argc, argv);
exit(0);
break;
}
int c;
while( (c = getopt(argc, argv, "hftv|help")) != -1)
{
switch(c)
{
case 'h':
print_usage(argc, argv);
exit(0);
break;
case 'f':
daemonize = 0;
break;
case 't':
tests();
exit(0);
break;
case 'v':
verbose = 1;
break;
default:
print_usage(argc, argv);
exit(0);
break;
}
}
// pointer to mbpfan() function in mbpfan.c
void (*fan_control)() = mbpfan;
go_daemon(fan_control);
exit(0);
// pointer to mbpfan() function in mbpfan.c
void (*fan_control)() = mbpfan;
go_daemon(fan_control);
exit(0);
}
\ No newline at end of file
This diff is collapsed.
......@@ -61,6 +61,11 @@ void find_fans(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
*/
......
/* 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;
}
\ No newline at end of file
/**
* 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();
\ No newline at end of file
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