This commit is contained in:
Daniel Graziotin 2012-06-11 21:43:53 +02:00
parent a179c7dc73
commit cd3c15ba9d
8 changed files with 327 additions and 25 deletions

View file

@ -40,8 +40,8 @@ GNU General Public License version 3
Based On Based On
--------------------- ---------------------
http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/ * http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/
http://allanmcrae.com/2011/08/mbp-fan-daemon-update/ * http://allanmcrae.com/2011/08/mbp-fan-daemon-update/
https://launchpad.net/macfanctld * https://launchpad.net/macfanctld
http://paste2.org/p/862259 * http://paste2.org/p/862259
http://www.lobotomo.com/products/FanControl/ * http://www.lobotomo.com/products/FanControl/

103
mbpfan.init Executable file
View file

@ -0,0 +1,103 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: mbpfan
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mbpfan initscript
# Description: Start the mbpfan daemon
### END INIT INFO
DESC="Start the mbpfan daemon"
NAME=mbpfan
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
DAEMON_ARGS=""
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
# Function that starts the daemon/service
do_start()
{
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
}
# Function that stops the daemon/service
do_stop()
{
# Return
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
return "$RETVAL"
}
# Function that sends a SIGHUP to the daemon/service
do_reload()
{
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:

106
src/daemon.c Normal file
View file

@ -0,0 +1,106 @@
/**
* Credits: http://peterlombardo.wikidot.com/linux-daemon-in-c
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include "mbpfan.h"
#include "global.h"
#define DAEMON_NAME "mbpfan"
#define PID_FILE "/var/run/mbpfan.pid"
void signal_handler(int signal)
{
switch(signal) {
case SIGHUP:
//TODO: restart myself
syslog(LOG_WARNING, "Received SIGHUP signal.");
exit(0);
break;
case SIGTERM:
syslog(LOG_WARNING, "Received SIGTERM signal.");
//TODO: free resources
exit(0);
break;
case SIGINT:
syslog(LOG_WARNING, "Received SIGINT signal.");
//TODO: free resources
exit(0);
default:
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
break;
}
}
void go_daemon(void (*function)())
{
// Setup signal handling before we start
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
syslog(LOG_INFO, "%s starting up", DAEMON_NAME);
// Setup syslog logging - see SETLOGMASK(3)
if(verbose) {
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
} else {
setlogmask(LOG_UPTO(LOG_INFO));
openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
}
pid_t pid;
pid_t sid;
if (daemonize) {
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
if (pid > 0) {
exit(EXIT_SUCCESS);
}
umask(0);
// new SID for the child process
sid = setsid();
if (sid < 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);
}
function();
if(daemonize)
syslog(LOG_INFO, "%s daemon exiting", DAEMON_NAME);
return;
}

9
src/daemon.h Normal file
View file

@ -0,0 +1,9 @@
/**
* ...handles signals :-)
*/
void signal_handler(int signal);
/**
* Daemonizes
*/
int go_daemon(void (*function)());

2
src/global.h Normal file
View file

@ -0,0 +1,2 @@
extern int daemonize;
extern int verbose;

50
src/main.c Normal file
View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mbpfan.h"
#include "daemon.h"
#include "global.h"
int daemonize = 1;
int verbose = 0;
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");
}
}
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;
}
}
// pointer to mbpfan() function in mbpfan.c
void (*function)() = mbpfan;
go_daemon(function);
exit(0);
}

View file

@ -28,12 +28,14 @@
*/ */
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <math.h>
#include <syslog.h>
#include "mbpfan.h" #include "mbpfan.h"
#include "global.h"
/* lazy min/max... */ /* lazy min/max... */
#define min(a,b) a < b ? a : b #define min(a,b) a < b ? a : b
@ -62,7 +64,7 @@ struct s_sensors {
}; };
t_sensors *find_sensors() t_sensors *retrieve_sensors()
{ {
t_sensors *sensors_head = NULL; t_sensors *sensors_head = NULL;
@ -130,14 +132,15 @@ void find_fans(t_sensors* sensors)
char number[1]; char number[1];
sprintf(number,"%d",0); sprintf(number,"%d",0);
int counter = 0; int n_sensors = 0;
int n_fans = 0;
for(counter = 0; counter<10; counter++) { for(n_sensors = 0; n_sensors<10; n_sensors++) {
path_min = (char*) malloc(sizeof( char ) * path_min_size); path_min = (char*) malloc(sizeof( char ) * path_min_size);
path_min[0] = '\0'; path_min[0] = '\0';
path_man = (char*) malloc(sizeof( char ) * path_man_size); path_man = (char*) malloc(sizeof( char ) * path_man_size);
path_man[0] = '\0'; path_man[0] = '\0';
sprintf(number,"%d",counter); 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) );
@ -158,10 +161,18 @@ void find_fans(t_sensors* sensors)
strcpy(tmp->fan_min_path, path_min); strcpy(tmp->fan_min_path, path_min);
strcpy(tmp->fan_man_path, path_man); strcpy(tmp->fan_man_path, path_man);
tmp = tmp->next; tmp = tmp->next;
n_fans++;
fclose(file); fclose(file);
} }
} }
if(verbose) {
printf("Found %d: sensors and %d fans\n", 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);
@ -239,17 +250,24 @@ unsigned short get_temp(t_sensors* sensors)
} }
int main() 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 = find_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) {
printf("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 ) /
@ -282,11 +300,21 @@ int main()
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) ); fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
} }
set_fan_speed(sensors, fan_speed); if(verbose) {
sleep(polling_interval);
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) {
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
}
} }
return 0; 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);
}
} }

View file

@ -11,7 +11,6 @@ extern int low_temp;
extern int high_temp; extern int high_temp;
extern int max_temp; extern int max_temp;
/** Temperature polling interval /** Temperature polling interval
* Default value was 10 (seconds) * Default value was 10 (seconds)
*/ */
@ -26,7 +25,7 @@ typedef struct s_sensors t_sensors;
* Detect the sensors in /sys/devices/platform/coretemp.0/temp * Detect the sensors in /sys/devices/platform/coretemp.0/temp
* Return a linked list of t_sensors (first temperature detected) * Return a linked list of t_sensors (first temperature detected)
*/ */
t_sensors *find_sensors(); t_sensors *retrieve_sensors();
/** /**
* Given a linked list of t_sensors, refresh their detected * Given a linked list of t_sensors, refresh their detected
@ -45,3 +44,8 @@ void find_fans(t_sensors *sensors);
* Set them to manual control * Set them to manual control
*/ */
void set_fans_man(t_sensors *sensors); void set_fans_man(t_sensors *sensors);
/**
* Main Program
*/
void mbpfan();