Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
Fan-Control-Daemon
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
CeRiAl
Fan-Control-Daemon
Commits
10788141
Commit
10788141
authored
Jun 16, 2012
by
Daniel Graziotin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes #10
parent
a6cc7a45
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
559 additions
and
345 deletions
+559
-345
README.md
README.md
+5
-0
daemon.c
src/daemon.c
+141
-114
daemon.h
src/daemon.h
+1
-1
main.c
src/main.c
+42
-31
mbpfan.c
src/mbpfan.c
+229
-199
mbpfan.h
src/mbpfan.h
+5
-0
minunit.c
src/minunit.c
+120
-0
minunit.h
src/minunit.h
+16
-0
No files found.
README.md
View file @
10788141
...
@@ -24,6 +24,11 @@ Compile with
...
@@ -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
--------------------
--------------------
...
...
src/daemon.c
View file @
10788141
...
@@ -29,150 +29,177 @@
...
@@ -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
pid_slave
;
pid_t
sid_slave
;
pid_t
sid_slave
;
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
)
{
}
// kill the father
if
(
pid_slave
>
0
)
exit
(
EXIT_SUCCESS
);
{
}
// kill the father
exit
(
EXIT_SUCCESS
);
}
umask
(
0022
);
umask
(
0022
);
// 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
);
}
if
((
chdir
(
"/"
))
<
0
)
{
if
((
chdir
(
"/"
))
<
0
)
exit
(
EXIT_FAILURE
);
{
}
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 */
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
{
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
){
fan_control
();
syslog
(
LOG_INFO
,
"%s daemon exiting"
,
program_name
);
}
if
(
daemonize
)
{
syslog
(
LOG_INFO
,
"%s daemon exiting"
,
program_name
);
}
return
;
return
;
}
}
src/daemon.h
View file @
10788141
...
@@ -36,7 +36,7 @@ int read_pid();
...
@@ -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 :-)
...
...
src/main.c
View file @
10788141
...
@@ -12,13 +12,14 @@
...
@@ -12,13 +12,14 @@
* GNU General Public License for more details.
* GNU General Public License for more details.
*
*
*/
*/
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#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";
...
@@ -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
);
}
}
\ No newline at end of file
src/mbpfan.c
View file @
10788141
This diff is collapsed.
Click to expand it.
src/mbpfan.h
View file @
10788141
...
@@ -61,6 +61,11 @@ void find_fans(t_sensors *sensors);
...
@@ -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
*/
*/
...
...
src/minunit.c
0 → 100644
View file @
10788141
/* 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
src/minunit.h
0 → 100644
View file @
10788141
/**
* 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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment