New upstream version 2.1.1
Chow Loong Jin
4 years ago
4 | 4 | |
5 | 5 | Marji Cermak <marji AT morpht DOT com> |
6 | 6 | John Ferlito <john AT inodes DOT org> |
7 | Andrew Gaul <gaul AT gaul DOT org> | |
7 | 8 | Ismail Khatib <ikhatib AT gmail DOT com> |
8 | 9 | Trevor Joynson |
9 | 10 | Magnus Stubman <magnus AT stubman DOT eu> |
12 | 13 | Yi Yang <ahyangyi AT gmail DOT com> |
13 | 14 | Herminio Hernandez Jr <herminio.hernandezjr AT gmail DOT com> |
14 | 15 | Robert Musial <rmusial AT fastmail DOT com> |
16 | Ati Sharma <ati.sharma AT gmail DOT com> | |
15 | 17 | |
16 | 18 | |
17 | 19 | ORIGINARY AUTHORS |
9 | 9 | MAN = mbpfan.8.gz |
10 | 10 | |
11 | 11 | COPT = |
12 | CC = cc | |
12 | CC ?= cc | |
13 | 13 | OBJFLAG = -o |
14 | 14 | BINFLAG = -o |
15 | 15 | INCLUDES = |
0 | 0 | mbpfan |
1 | 1 | ==================== |
2 | 2 | |
3 | [![Build Status](https://travis-ci.org/dgraziotin/mbpfan.svg?branch=master)](https://travis-ci.org/dgraziotin/mbpfan) | |
4 | ||
3 | 5 | This is an enhanced version of [Allan McRae mbpfan](http://allanmcrae.com/2010/05/simple-macbook-pro-fan-daemon/) |
4 | 6 | |
5 | 7 | mbpfan is a daemon that uses input from coretemp module and sets the fan speed using the applesmc module. |
6 | 8 | This enhanced version assumes any number of processors and fans (max. 10). |
7 | 9 | |
8 | * It only uses the temperatures from the processors as input. | |
9 | * It requires coretemp and applesmc kernel modules to be loaded. | |
10 | * It requires root use | |
11 | * It daemonizes or stays in foreground | |
12 | * Verbose mode for both syslog and stdout | |
13 | * Users can configure it using the file /etc/mbpfan.conf | |
10 | * It only uses the temperatures from the processors as input. | |
11 | * It requires coretemp and applesmc kernel modules to be loaded. | |
12 | * It requires root use | |
13 | * It daemonizes or stays in foreground | |
14 | * Verbose mode for both syslog and stdout | |
15 | * Users can configure it using the file /etc/mbpfan.conf | |
14 | 16 | |
15 | 17 | **Table Of Contents** |
16 | 18 | |
17 | 19 | - [Supported GNU/Linux Distributions](#supported-gnulinux-distributions) |
18 | - [Tested Macbook Models](#tested-macbook-models) | |
19 | - [Tested iMac/Mac Mini Models](#tested-imacmac-mini-models) | |
20 | - [Tested MacBook Models](#tested-macbook-models) | |
21 | - [Tested iMac/Mac mini Models](#tested-imacmac-mini-models) | |
20 | 22 | - [Requirements](#requirements) |
21 | 23 | - [Installation](#installation) |
22 | 24 | - [Arch Linux](#arch-linux) |
47 | 49 | - Trisquel |
48 | 50 | - Solus |
49 | 51 | |
50 | ## Tested Macbook Models | |
52 | ## Tested MacBook Models | |
51 | 53 | |
52 | 54 | This section reports those models where mbpfan was tested successfully. It does not necessarily mean that the daemon does not work on non-listed models. |
53 | 55 | |
61 | 63 | - MacBook Pro 6,2 15" (Intel i7 - Linux 3.5.0) |
62 | 64 | - MacBook Pro 6,2 15" (Intel i7 - Linux 3.2.0) |
63 | 65 | - MacBook Pro 2,2 15" (Intel Core 2 Duo - Linux 3.4.4) |
66 | - MacBook Air 6,1 13" (Intel i7 - Linux 3.13) | |
64 | 67 | - MacBook Air 5,2 13" (Intel i5 - Linux 3.16) |
65 | 68 | - MacBook Air 1,1 13" (Intel Core Duo - Linux 4.4, Linux 4.8) |
66 | 69 | - MacBook Air 7,2 13" (Intel Core Duo - Linux 4.10) |
67 | 70 | - MacBook 1,1 (Intel Core Duo - Linux 3.16) |
68 | 71 | |
69 | ## Tested iMac/Mac Mini Models | |
70 | ||
71 | This section reports the iMac/Mac-mini models where mbpfan was tested successfully. | |
72 | ||
73 | - iMac Retina 16.2 21.5" (Intel i5 - Linux 4.4.0 Ubuntu 16.04) | |
72 | ## Tested iMac/Mac mini Models | |
73 | ||
74 | This section reports the iMac/Mac mini models where mbpfan was tested successfully. | |
75 | ||
76 | - iMac Retina 16.2 21.5" (Intel i5 - Linux 4.4.0 Ubuntu 16.04) | |
74 | 77 | - iMac 12,1 21.5" (Intel i7 - Linux 4.6.4) |
75 | 78 | - iMac 5,1 17" (Intel T7400 (Core 2 Duo) - Linux 14.04 Ubuntu) |
76 | - Mac Mini 2,1 (Core 2 Duo - Linux 4.4.0) | |
77 | - Mac Mini 5,3 (Core i7 2.0 - Linux 4.4.0 elementary/Ubuntu) | |
78 | - Mac Mini 6,1 (Core i7 2.3 - Linux 4.7.3-4-ck Archlinux) | |
79 | - Mac mini 2,1 (Core 2 Duo - Linux 4.4.0) | |
80 | - Mac mini 5,3 (Core i7 2.0 - Linux 4.4.0 elementary/Ubuntu) | |
81 | - Mac mini 6,1 (Core i7 2.3 - Linux 4.7.3-4-ck Archlinux) | |
82 | ||
83 | ## Tested Mac Pro Models | |
84 | ||
85 | This section reports the Mac Pro models where mbpfan was tested successfully. | |
86 | ||
87 | - Mac Pro 3,1 | |
88 | - Mac Pro 4,1 (with 5,1 firmware and hex-core Xeon X5690 mod - Linux 4.14) | |
79 | 89 | |
80 | 90 | ## Requirements |
81 | 91 | |
87 | 97 | |
88 | 98 | In most distributions, you can run the following command: |
89 | 99 | |
90 | `lsmod | grep coretemp && lsmod | grep applesmc` | |
100 | ```bash | |
101 | lsmod | grep -e applesmc -e coretemp | |
102 | ``` | |
91 | 103 | |
92 | 104 | If you see `coretemp` and `applesmc` listed, you are all set. |
93 | 105 | |
173 | 185 | |
174 | 186 | **Ubuntu** |
175 | 187 | |
176 | For systemd based init systems (Ubuntu 16.04+), the file mbpfan.service | |
177 | has been provided. | |
178 | For using it, execute: | |
179 | ||
180 | sudo cp mbpfan.service /etc/systemd/system/ | |
181 | sudo systemctl enable mbpfan.service | |
182 | ||
188 | For systemd based init systems (Ubuntu 16.04+), see the systemd section below. | |
183 | 189 | |
184 | 190 | For upstart based init systems (Ubuntu before 16.04), an example upstart job has been provided. |
185 | 191 | For using it, execute: |
221 | 227 | sudo systemctl daemon-reload |
222 | 228 | sudo systemctl start mbpfan.service |
223 | 229 | |
224 | To start the service automatically at boot, also execute the following: | |
225 | ||
226 | sudo systemctl enable mbpfan.service | |
227 | ||
228 | ||
229 | 230 | ## Usage |
230 | 231 | |
231 | 232 | Usage: ./mbpfan OPTION(S) |
253 | 254 | |
254 | 255 | **This Project uses following library:** |
255 | 256 | |
256 | * [ANSI C Application Settings Managment](http://pokristensson.com/settings.html) by Per Ola Kristensson. | |
257 | * [ANSI C Application Settings Management](http://pokristensson.com/settings.html) by Per Ola Kristensson. |
0 | 0 | [general] |
1 | 1 | # see https://ineed.coffee/3838/a-beginners-tutorial-for-mbpfan-under-ubuntu for the values |
2 | min_fan_speed = 2000 # put the *lowest* value of "cat /sys/devices/platform/applesmc.768/fan*_min" | |
3 | max_fan_speed = 6200 # put the *highest* value of "cat /sys/devices/platform/applesmc.768/fan*_max" | |
2 | # | |
3 | # mbpfan will load the max / min speed of from the files produced by the applesmc driver. If these files are not found it will set all fans to the default of min_speed = 2000 and max_speed = 6200 | |
4 | # by setting the values for the speeds in this config it will override whatever it finds in: | |
5 | # /sys/devices/platform/applesmc.768/fan*_min | |
6 | # /sys/devices/platform/applesmc.768/fan*_max | |
7 | # or the defaults. | |
8 | # | |
9 | # multiple fans can be configured by using the config key of min_fan*_speed and max_fan*_speed | |
10 | # the number used will correlate to the file number of the fan in the applesmc driver that are used to control the fan speed. | |
11 | # | |
12 | #min_fan1_speed = 2000 # put the *lowest* value of "cat /sys/devices/platform/applesmc.768/fan*_min" | |
13 | #max_fan1_speed = 6200 # put the *highest* value of "cat /sys/devices/platform/applesmc.768/fan*_max" | |
4 | 14 | low_temp = 63 # try ranges 55-63, default is 63 |
5 | 15 | high_temp = 66 # try ranges 58-66, default is 66 |
6 | 16 | max_temp = 86 # take highest number returned by "cat /sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_max", divide by 1000 |
7 | polling_interval = 7 # default is 7 seconds | |
17 | polling_interval = 1 # default is 1 seconds |
0 | [general] | |
1 | # see https://ineed.coffee/3838/a-beginners-tutorial-for-mbpfan-under-ubuntu for the values | |
2 | min_fan1_speed = 2000 # put the *lowest* value of "cat /sys/devices/platform/applesmc.768/fan*_min" | |
3 | max_fan1_speed = 6200 # put the *highest* value of "cat /sys/devices/platform/applesmc.768/fan*_max" | |
4 | low_temp = 63 # try ranges 55-63, default is 63 | |
5 | high_temp = 66 # try ranges 58-66, default is 66 | |
6 | max_temp = 86 # take highest number returned by "cat /sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_max", divide by 1000 | |
7 | polling_interval = 7 # default is 1 second |
0 | 0 | [general] |
1 | min_fan_speed = 6200 # default is 2000 | |
2 | max_fan_speed = 6200 # default is 6200 | |
1 | min_fan1_speed = 6200 # default is 2000 | |
2 | max_fan1_speed = 6200 # default is 6200 | |
3 | 3 | low_temp = 63 # try ranges 55-63, default is 63 |
4 | 4 | high_temp = 66 # try ranges 58-66, default is 66 |
5 | 5 | max_temp = 86 # do not set it > 90, default is 86 |
6 | polling_interval = 1 # default is 7 | |
6 | polling_interval = 2 # default is 1 second |
0 | [general] | |
1 | min_fan1_speed = 2000 # default is 2000 | |
2 | min_fan2_speed = 2000 # default is 6200 | |
3 | low_temp = 63 # try ranges 55-63, default is 63 | |
4 | high_temp = 66 # try ranges 58-66, default is 66 | |
5 | max_temp = 86 # do not set it > 90, default is 86 | |
6 | polling_interval = 1 # default is 1 second |
0 | Name: mbpfan | |
1 | URL: https://github.com/dgraziotin/mbpfan | |
2 | License: GPLv3 | |
3 | Group: System Environment/Daemons | |
4 | Version: %{SOURCE_VERSION} | |
5 | Release: 3 | |
6 | Summary: A simple daemon to control fan speed on all MacBook/MacBook Pros (probably all Apple computers) for Linux 3.x.x and 4.x.x | |
7 | Source: v%{version}.tar.gz | |
8 | ||
9 | %description | |
10 | This is an enhanced version of Allan McRae mbpfan | |
11 | ||
12 | mbpfan 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). | |
13 | ||
14 | It only uses the temperatures from the processors as input. | |
15 | It requires coretemp and applesmc kernel modules to be loaded. | |
16 | It requires root use | |
17 | It daemonizes or stays in foreground | |
18 | Verbose mode for both syslog and stdout | |
19 | Users can configure it using the file /etc/mbpfan.conf | |
20 | ||
21 | %prep | |
22 | %setup -q -n %{name}-%{version} | |
23 | ||
24 | %build | |
25 | make | |
26 | ||
27 | %install | |
28 | install -D -m755 bin/mbpfan $RPM_BUILD_ROOT/usr/sbin/mbpfan | |
29 | install -D -m644 mbpfan.conf $RPM_BUILD_ROOT/etc/mbpfan.conf | |
30 | install -D -m644 mbpfan.service $RPM_BUILD_ROOT/usr/lib/systemd/system/mbpfan.service | |
31 | ||
32 | %clean | |
33 | rm -rf $RPM_BUILD_ROOT | |
34 | ||
35 | %post | |
36 | %systemd_post mbpfan.service | |
37 | echo "mbpfan will auto detect sane values for min and max fan speeds." | |
38 | echo "If you want to customize these values please edit:" | |
39 | echo "/etc/mbpfan.conf" | |
40 | echo "To start the daemon now type:" | |
41 | echo "systemctl start mbpfan" | |
42 | echo "To run also at boot, type:" | |
43 | echo "systemctl enable mbpfan" | |
44 | ||
45 | %preun | |
46 | %systemd_preun mbpfan.service | |
47 | ||
48 | %postun | |
49 | %systemd_postun_with_restart mbpfan.service | |
50 | ||
51 | %files | |
52 | %defattr (-,root,root) | |
53 | %doc AUTHORS README.md | |
54 | /usr/sbin/mbpfan | |
55 | %config /etc/mbpfan.conf | |
56 | /usr/lib/systemd/system/mbpfan.service | |
57 | ||
58 | %changelog | |
59 | * Mon Sep 10 2018 Michele Codutti <codutti@gmail.com> - 2.0.2-3 | |
60 | - Removed autoconfig with suggested procedure because has been integrated on mbpfan. | |
61 | ||
62 | * Sun Aug 19 2018 Michele Codutti <codutti@gmail.com> - 2.0.2-2 | |
63 | - Autoconfig with suggested procedure. | |
64 | - Initial packaging |
16 | 16 | */ |
17 | 17 | |
18 | 18 | |
19 | #include <sys/prctl.h> | |
19 | 20 | #include <sys/types.h> |
20 | 21 | #include <sys/stat.h> |
21 | 22 | #include <stdio.h> |
110 | 111 | switch(signal) { |
111 | 112 | case SIGHUP: |
112 | 113 | syslog(LOG_WARNING, "Received SIGHUP signal."); |
113 | retrieve_settings(NULL); | |
114 | retrieve_settings(NULL, fans); | |
114 | 115 | break; |
115 | 116 | |
116 | 117 | case SIGTERM: |
117 | 118 | syslog(LOG_WARNING, "Received SIGTERM signal."); |
118 | 119 | cleanup_and_exit(EXIT_SUCCESS); |
120 | break; | |
119 | 121 | |
120 | 122 | case SIGQUIT: |
121 | 123 | syslog(LOG_WARNING, "Received SIGQUIT signal."); |
122 | 124 | cleanup_and_exit(EXIT_SUCCESS); |
125 | break; | |
123 | 126 | |
124 | 127 | case SIGINT: |
125 | 128 | syslog(LOG_WARNING, "Received SIGINT signal."); |
126 | 129 | cleanup_and_exit(EXIT_SUCCESS); |
130 | break; | |
127 | 131 | |
128 | 132 | default: |
129 | 133 | syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal)); |
152 | 156 | openlog(PROGRAM_NAME, LOG_CONS, LOG_USER); |
153 | 157 | } |
154 | 158 | |
159 | // configure timer slack | |
160 | int err = prctl(PR_SET_TIMERSLACK, 1000 * 1000 * 1000, 0, 0, 0); | |
161 | if (err == -1) { | |
162 | perror("prctl"); | |
163 | } | |
155 | 164 | |
156 | 165 | pid_t pid_slave; |
157 | 166 | pid_t sid_slave; |
18 | 18 | char* path; // TODO: unused |
19 | 19 | char* fan_output_path; |
20 | 20 | char* fan_manual_path; |
21 | int step_up; | |
22 | int step_down; | |
23 | int fan_id; | |
24 | int old_speed; | |
25 | int fan_max_speed; | |
26 | int fan_min_speed; | |
21 | 27 | struct s_fans *next; |
22 | 28 | }; |
23 | 29 | |
27 | 33 | extern t_sensors* sensors; |
28 | 34 | extern t_fans* fans; |
29 | 35 | |
30 | #endif⏎ | |
36 | #endif |
28 | 28 | #include "mbpfan.h" |
29 | 29 | #include "daemon.h" |
30 | 30 | #include "global.h" |
31 | #include "main.h" | |
31 | 32 | #include "minunit.h" |
32 | 33 | |
33 | 34 | int daemonize = 1; |
51 | 52 | printf("\n"); |
52 | 53 | } |
53 | 54 | } |
54 | ||
55 | 55 | |
56 | 56 | void check_requirements() |
57 | 57 | { |
95 | 95 | |
96 | 96 | } |
97 | 97 | |
98 | ||
99 | 98 | int main(int argc, char *argv[]) |
100 | 99 | { |
101 | 100 | |
113 | 112 | break; |
114 | 113 | |
115 | 114 | case 't': |
116 | tests(); | |
117 | exit(EXIT_SUCCESS); | |
118 | break; | |
115 | return tests(); | |
119 | 116 | |
120 | 117 | case 'v': |
121 | 118 | verbose = 1; |
128 | 125 | } |
129 | 126 | } |
130 | 127 | |
131 | ||
132 | ||
133 | 128 | check_requirements(); |
134 | 129 | |
135 | 130 | // pointer to mbpfan() function in mbpfan.c |
0 | void check_requirements(); |
4 | 4 | * Modifications (2012) by Ismail Khatib <ikhatib@gmail.com> |
5 | 5 | * Modifications (2012-present) by Daniel Graziotin <daniel@ineed.coffee> [CURRENT MAINTAINER] |
6 | 6 | * Modifications (2017-present) by Robert Musial <rmusial@fastmail.com> |
7 | * Modifications (2018-present) by Ati Sharma <ati.sharma@gmail.com> | |
7 | 8 | * |
8 | 9 | * This program is free software: you can redistribute it and/or modify |
9 | 10 | * it under the terms of the GNU General Public License as published by |
17 | 18 | * |
18 | 19 | * |
19 | 20 | * Notes: |
20 | * Assumes any number of processors and fans (max. 10) | |
21 | * Assumes any number of processors, cores and fans (max. 6, 16, 12 | |
22 | * as defined in NUM_PROCESSORS, NUM_HWMONS, NUM_TEMP_INPUTS and NUM_FANS) | |
21 | 23 | * It uses only the temperatures from the processors as input. |
22 | 24 | * Requires coretemp and applesmc kernel modules to be loaded. |
23 | 25 | * Requires root use |
25 | 27 | * Tested models: see README.md |
26 | 28 | */ |
27 | 29 | |
28 | ||
29 | 30 | #include <stdarg.h> |
30 | 31 | #include <stdio.h> |
31 | 32 | #include <stdlib.h> |
32 | 33 | #include <unistd.h> |
33 | 34 | #include <string.h> |
35 | #include <time.h> | |
34 | 36 | #include <math.h> |
35 | 37 | #include <syslog.h> |
36 | 38 | #include <stdbool.h> |
44 | 46 | #define min(a,b) ((a) < (b) ? (a) : (b)) |
45 | 47 | #define max(a,b) ((a) > (b) ? (a) : (b)) |
46 | 48 | |
47 | int min_fan_speed = 2000; | |
48 | int max_fan_speed = 6200; | |
49 | ||
50 | 49 | /* temperature thresholds |
51 | 50 | * low_temp - temperature below which fan speed will be at minimum |
52 | 51 | * high_temp - fan will increase speed when higher than this temperature |
55 | 54 | int high_temp = 66; // try ranges 58-66 |
56 | 55 | int max_temp = 86; // do not set it > 90 |
57 | 56 | |
58 | int polling_interval = 7; | |
57 | // maximum number of processors etc supported | |
58 | #define NUM_PROCESSORS 6 | |
59 | #define NUM_HWMONS 12 | |
60 | #define NUM_TEMP_INPUTS 16 | |
61 | #define NUM_FANS 10 | |
62 | // sane defaults when user provides unexpected values | |
63 | #define MIN_FAN_SPEED_DEFAULT 500 | |
64 | #define MAX_FAN_SPEED_DEFAULT 6500 | |
65 | ||
66 | int polling_interval = 1; | |
59 | 67 | |
60 | 68 | t_sensors* sensors = NULL; |
61 | 69 | t_fans* fans = NULL; |
62 | 70 | |
63 | ||
64 | static char *smprintf(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | |
65 | static char *smprintf(const char *fmt, ...) | |
71 | char *smprintf(const char *fmt, ...) | |
66 | 72 | { |
67 | 73 | char *buf; |
68 | 74 | int cnt; |
84 | 90 | return buf; |
85 | 91 | } |
86 | 92 | |
87 | bool is_legacy_sensors_path() | |
93 | bool is_modern_sensors_path() | |
88 | 94 | { |
89 | 95 | struct utsname kernel; |
90 | 96 | uname(&kernel); |
98 | 104 | exit(EXIT_FAILURE); |
99 | 105 | } |
100 | 106 | |
101 | ||
102 | // thanks http://stackoverflow.com/questions/18192998/plain-c-opening-a-directory-with-fopen | |
103 | fopen("/sys/devices/platform/coretemp.0/hwmon", "wb"); | |
104 | ||
105 | if (errno == EISDIR) { | |
106 | return 0; | |
107 | } else { | |
108 | return 1; | |
109 | } | |
110 | ||
111 | // | |
112 | // str_kernel_version = strtok(NULL, "."); | |
113 | // int kernel_version = atoi(str_kernel_version); | |
114 | ||
115 | // if(verbose) { | |
116 | // printf("Detected kernel version: %s\n", kernel.release); | |
117 | // printf("Detected kernel minor revision: %s\n", str_kernel_version); | |
118 | ||
119 | // if(daemonize) { | |
120 | // syslog(LOG_INFO, "Kernel version: %s", kernel.release); | |
121 | // syslog(LOG_INFO, "Detected kernel minor revision: %s", str_kernel_version); | |
122 | // } | |
123 | // } | |
124 | ||
125 | // return (atoi(kernel.release) == 3 && kernel_version < 15); | |
107 | int counter; | |
108 | ||
109 | for (counter = 0; counter < NUM_HWMONS; counter++) { | |
110 | int temp; | |
111 | for (temp = 1; temp < NUM_TEMP_INPUTS; ++temp) { | |
112 | char *path = smprintf("/sys/devices/platform/coretemp.0/hwmon/hwmon%d/temp%d_input", counter, temp); | |
113 | int res = access(path, R_OK); | |
114 | free(path); | |
115 | if (res == 0) { | |
116 | return 1; | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | return 0; | |
126 | 122 | } |
127 | 123 | |
128 | 124 | |
129 | 125 | t_sensors *retrieve_sensors() |
130 | 126 | { |
131 | ||
132 | 127 | t_sensors *sensors_head = NULL; |
133 | 128 | t_sensors *s = NULL; |
134 | 129 | |
135 | 130 | char *path = NULL; |
136 | 131 | char *path_begin = NULL; |
137 | 132 | |
138 | if (is_legacy_sensors_path()) { | |
133 | const char *path_end = "_input"; | |
134 | int sensors_found = 0; | |
135 | ||
136 | if (!is_modern_sensors_path()) { | |
139 | 137 | if(verbose) { |
140 | 138 | printf("Using legacy sensor path for kernel < 3.15.0\n"); |
141 | 139 | |
156 | 154 | } |
157 | 155 | } |
158 | 156 | |
159 | path_begin = strdup("/sys/devices/platform/coretemp.0/hwmon/hwmon"); | |
160 | ||
161 | int counter; | |
162 | for (counter = 0; counter < 10; counter++) { | |
163 | ||
164 | char hwmon_path[strlen(path_begin)+2]; | |
165 | ||
166 | sprintf(hwmon_path, "%s%d", path_begin, counter); | |
167 | ||
168 | // thanks http://stackoverflow.com/questions/18192998/plain-c-opening-a-directory-with-fopen | |
169 | fopen(hwmon_path, "wb"); | |
170 | ||
171 | if (errno == EISDIR) { | |
172 | ||
173 | path_begin = smprintf("%s/temp", hwmon_path); | |
174 | ||
175 | if(verbose) { | |
176 | printf("Found hwmon path at %s\n", path_begin); | |
177 | ||
178 | if(daemonize) { | |
179 | syslog(LOG_INFO, "Found hwmon path at %s\n", path_begin); | |
180 | } | |
181 | ||
182 | } | |
183 | ||
184 | break; | |
185 | } | |
186 | } | |
187 | } | |
188 | ||
189 | const char *path_end = "_input"; | |
190 | ||
191 | int sensors_found = 0; | |
192 | ||
193 | int counter = 0; | |
194 | for(counter = 0; counter<10; counter++) { | |
195 | path = smprintf("%s%d%s", path_begin, counter, path_end); | |
196 | ||
197 | FILE *file = fopen(path, "r"); | |
198 | ||
199 | if(file != NULL) { | |
200 | s = (t_sensors *) malloc( sizeof( t_sensors ) ); | |
201 | s->path = strdup(path); | |
202 | fscanf(file, "%d", &s->temperature); | |
203 | ||
204 | if (sensors_head == NULL) { | |
205 | sensors_head = s; | |
206 | sensors_head->next = NULL; | |
207 | ||
208 | } else { | |
209 | t_sensors *tmp = sensors_head; | |
210 | ||
211 | while (tmp->next != NULL) { | |
212 | tmp = tmp->next; | |
213 | } | |
214 | ||
215 | tmp->next = s; | |
216 | tmp->next->next = NULL; | |
217 | } | |
218 | ||
219 | s->file = file; | |
220 | sensors_found++; | |
221 | } | |
222 | ||
223 | free(path); | |
224 | path = NULL; | |
157 | // loop over up to 6 processors | |
158 | int processor; | |
159 | for (processor = 0; processor < NUM_PROCESSORS; processor++) { | |
160 | ||
161 | if (path_begin != NULL) { | |
162 | free(path_begin); | |
163 | } | |
164 | path_begin = smprintf("/sys/devices/platform/coretemp.%d/hwmon/hwmon", processor); | |
165 | ||
166 | int counter; | |
167 | for (counter = 0; counter < NUM_HWMONS; counter++) { | |
168 | ||
169 | char hwmon_path[strlen(path_begin)+2]; | |
170 | ||
171 | sprintf(hwmon_path, "%s%d", path_begin, counter); | |
172 | ||
173 | int res = access(hwmon_path, R_OK); | |
174 | if (res == 0) { | |
175 | ||
176 | free(path_begin); | |
177 | path_begin = smprintf("%s/temp", hwmon_path); | |
178 | ||
179 | if(verbose) { | |
180 | printf("Found hwmon path at %s\n", path_begin); | |
181 | ||
182 | if(daemonize) { | |
183 | syslog(LOG_INFO, "Found hwmon path at %s\n", path_begin); | |
184 | } | |
185 | ||
186 | } | |
187 | ||
188 | break; | |
189 | } | |
190 | } | |
191 | ||
192 | int core = 0; | |
193 | for(core = 0; core<NUM_TEMP_INPUTS; core++) { | |
194 | path = smprintf("%s%d%s", path_begin, core, path_end); | |
195 | ||
196 | FILE *file = fopen(path, "r"); | |
197 | ||
198 | if(file != NULL) { | |
199 | s = (t_sensors *) malloc( sizeof( t_sensors ) ); | |
200 | s->path = strdup(path); | |
201 | fscanf(file, "%d", &s->temperature); | |
202 | ||
203 | if (sensors_head == NULL) { | |
204 | sensors_head = s; | |
205 | sensors_head->next = NULL; | |
206 | ||
207 | } else { | |
208 | t_sensors *tmp = sensors_head; | |
209 | ||
210 | while (tmp->next != NULL) { | |
211 | tmp = tmp->next; | |
212 | } | |
213 | ||
214 | tmp->next = s; | |
215 | tmp->next->next = NULL; | |
216 | } | |
217 | ||
218 | s->file = file; | |
219 | sensors_found++; | |
220 | } | |
221 | ||
222 | free(path); | |
223 | path = NULL; | |
224 | } | |
225 | } | |
225 | 226 | } |
226 | 227 | |
227 | 228 | if(verbose) { |
244 | 245 | return sensors_head; |
245 | 246 | } |
246 | 247 | |
248 | static int read_value(const char *path) | |
249 | { | |
250 | int value = -1; | |
251 | FILE *file = fopen(path, "r"); | |
252 | if (file != NULL) { | |
253 | fscanf(file, "%d", &value); | |
254 | fclose(file); | |
255 | } | |
256 | return value; | |
257 | } | |
247 | 258 | |
248 | 259 | t_fans *retrieve_fans() |
249 | 260 | { |
250 | ||
251 | 261 | t_fans *fans_head = NULL; |
252 | 262 | t_fans *fan = NULL; |
253 | 263 | |
254 | 264 | char *path_output = NULL; |
255 | 265 | char *path_manual = NULL; |
266 | char *path_fan_max = NULL; | |
267 | char *path_fan_min = NULL; | |
256 | 268 | |
257 | 269 | const char *path_begin = "/sys/devices/platform/applesmc.768/fan"; |
258 | 270 | const char *path_output_end = "_output"; |
259 | 271 | const char *path_man_end = "_manual"; |
260 | ||
272 | const char *path_max_speed = "_max"; | |
273 | const char *path_min_speed = "_min"; | |
274 | ||
261 | 275 | int counter = 0; |
262 | 276 | int fans_found = 0; |
263 | 277 | |
264 | for(counter = 0; counter<10; counter++) { | |
278 | for(counter = 0; counter<NUM_FANS; counter++) { | |
265 | 279 | |
266 | 280 | path_output = smprintf("%s%d%s", path_begin, counter, path_output_end); |
267 | 281 | path_manual = smprintf("%s%d%s", path_begin, counter, path_man_end); |
282 | path_fan_min = smprintf("%s%d%s",path_begin, counter, path_min_speed); | |
283 | path_fan_max = smprintf("%s%d%s",path_begin, counter, path_max_speed); | |
268 | 284 | |
269 | 285 | FILE *file = fopen(path_output, "w"); |
270 | 286 | |
272 | 288 | fan = (t_fans *) malloc( sizeof( t_fans ) ); |
273 | 289 | fan->fan_output_path = strdup(path_output); |
274 | 290 | fan->fan_manual_path = strdup(path_manual); |
291 | fan->fan_id = counter; | |
292 | ||
293 | int fan_speed = read_value(path_fan_min); | |
294 | if(fan_speed == -1 || fan_speed < MIN_FAN_SPEED_DEFAULT) | |
295 | fan->fan_min_speed = MIN_FAN_SPEED_DEFAULT; | |
296 | else | |
297 | fan->fan_min_speed = fan_speed; | |
298 | ||
299 | fan_speed = read_value(path_fan_max); | |
300 | if(fan_speed == -1 || fan_speed > MAX_FAN_SPEED_DEFAULT) | |
301 | fan->fan_max_speed = MAX_FAN_SPEED_DEFAULT; | |
302 | else | |
303 | fan->fan_max_speed = fan_speed; | |
304 | ||
305 | fan->old_speed = 0; | |
275 | 306 | |
276 | 307 | if (fans_head == NULL) { |
277 | 308 | fans_head = fan; |
291 | 322 | fan->file = file; |
292 | 323 | fans_found++; |
293 | 324 | } |
294 | ||
325 | free(path_fan_min); | |
326 | path_fan_min = NULL; | |
327 | free(path_fan_max); | |
328 | path_fan_max = NULL; | |
295 | 329 | free(path_output); |
296 | 330 | path_output = NULL; |
297 | 331 | free(path_manual); |
306 | 340 | } |
307 | 341 | } |
308 | 342 | |
309 | if (!fans_found > 0){ | |
343 | if (fans_found == 0){ | |
310 | 344 | syslog(LOG_CRIT, "mbpfan could not detect any fan. Please contact the developer.\n"); |
311 | 345 | printf("mbpfan could not detect any fan. Please contact the developer.\n"); |
312 | 346 | exit(EXIT_FAILURE); |
313 | 347 | } |
314 | 348 | |
315 | ||
316 | 349 | return fans_head; |
317 | 350 | } |
318 | 351 | |
319 | ||
320 | 352 | static void set_fans_mode(t_fans *fans, int mode) |
321 | 353 | { |
322 | ||
323 | 354 | t_fans *tmp = fans; |
324 | 355 | FILE *file; |
325 | 356 | |
349 | 380 | |
350 | 381 | t_sensors *refresh_sensors(t_sensors *sensors) |
351 | 382 | { |
352 | ||
353 | 383 | t_sensors *tmp = sensors; |
354 | 384 | |
355 | 385 | while(tmp != NULL) { |
366 | 396 | return sensors; |
367 | 397 | } |
368 | 398 | |
369 | ||
370 | /* Controls the speed of the fan */ | |
371 | void set_fan_speed(t_fans* fans, int speed) | |
372 | { | |
373 | t_fans *tmp = fans; | |
374 | ||
375 | while(tmp != NULL) { | |
376 | if(tmp->file != NULL) { | |
377 | char buf[16]; | |
378 | int len = snprintf(buf, sizeof(buf), "%d", speed); | |
379 | pwrite(fileno(tmp->file), buf, len, /*offset=*/ 0); | |
380 | } | |
381 | ||
382 | tmp = tmp->next; | |
383 | } | |
384 | ||
385 | } | |
386 | ||
387 | ||
399 | /* Controls the speed of a fan */ | |
400 | void set_fan_speed(t_fans* fan, int speed) | |
401 | { | |
402 | if(fan != NULL && fan->file != NULL && fan->old_speed != speed) { | |
403 | char buf[16]; | |
404 | int len = snprintf(buf, sizeof(buf), "%d", speed); | |
405 | int res = pwrite(fileno(fan->file), buf, len, /*offset=*/ 0); | |
406 | if (res == -1) { | |
407 | perror("Could not set fan speed"); | |
408 | } | |
409 | fan->old_speed = speed; | |
410 | } | |
411 | } | |
412 | ||
413 | void set_fan_minimum_speed(t_fans* fans) | |
414 | { | |
415 | t_fans *tmp = fans; | |
416 | ||
417 | while(tmp != NULL) { | |
418 | set_fan_speed(tmp,tmp->fan_min_speed); | |
419 | tmp = tmp->next; | |
420 | } | |
421 | } | |
388 | 422 | unsigned short get_temp(t_sensors* sensors) |
389 | 423 | { |
390 | 424 | sensors = refresh_sensors(sensors); |
410 | 444 | return temp; |
411 | 445 | } |
412 | 446 | |
413 | ||
414 | void retrieve_settings(const char* settings_path) | |
447 | void retrieve_settings(const char* settings_path, t_fans* fans) | |
415 | 448 | { |
416 | 449 | Settings *settings = NULL; |
417 | 450 | int result = 0; |
450 | 483 | } |
451 | 484 | |
452 | 485 | } else { |
453 | /* Read configfile values */ | |
454 | result = settings_get_int(settings, "general", "min_fan_speed"); | |
455 | ||
456 | if (result != 0) { | |
457 | min_fan_speed = result; | |
458 | } | |
459 | ||
460 | result = settings_get_int(settings, "general", "max_fan_speed"); | |
461 | ||
462 | if (result != 0) { | |
463 | max_fan_speed = result; | |
464 | } | |
465 | ||
486 | ||
487 | t_fans *fan = fans; | |
488 | ||
489 | while(fan != NULL) { | |
490 | ||
491 | char* config_key; | |
492 | config_key = smprintf("min_fan%d_speed", fan->fan_id); | |
493 | /* Read configfile values */ | |
494 | result = settings_get_int(settings, "general", config_key); | |
495 | if (result != 0) { | |
496 | fan->fan_min_speed = result; | |
497 | } | |
498 | free(config_key); | |
499 | ||
500 | config_key = smprintf("max_fan%d_speed", fan->fan_id); | |
501 | result = settings_get_int(settings, "general", config_key); | |
502 | ||
503 | if (result != 0) { | |
504 | fan->fan_max_speed = result; | |
505 | } | |
506 | free(config_key); | |
507 | fan = fan->next; | |
508 | } | |
466 | 509 | result = settings_get_int(settings, "general", "low_temp"); |
467 | 510 | |
468 | 511 | if (result != 0) { |
493 | 536 | } |
494 | 537 | } |
495 | 538 | |
496 | ||
497 | 539 | void mbpfan() |
498 | 540 | { |
499 | 541 | int old_temp, new_temp, fan_speed, steps; |
500 | 542 | int temp_change; |
501 | int step_up, step_down; | |
502 | ||
503 | retrieve_settings(NULL); | |
504 | ||
543 | ||
505 | 544 | sensors = retrieve_sensors(); |
506 | 545 | fans = retrieve_fans(); |
546 | ||
547 | retrieve_settings(NULL, fans); | |
548 | ||
549 | t_fans* fan = fans; | |
550 | while(fan != NULL) { | |
551 | ||
552 | if (fan->fan_min_speed > fan->fan_max_speed) { | |
553 | syslog(LOG_INFO, "Invalid fan speeds: %d %d", fan->fan_min_speed, fan->fan_max_speed); | |
554 | printf("Invalid fan speeds: %d %d\n", fan->fan_min_speed, fan->fan_max_speed); | |
555 | exit(EXIT_FAILURE); | |
556 | } | |
557 | fan = fan->next; | |
558 | } | |
559 | ||
560 | if (low_temp > high_temp || high_temp > max_temp) { | |
561 | syslog(LOG_INFO, "Invalid temperatures: %d %d %d", low_temp, high_temp, max_temp); | |
562 | printf("Invalid temperatures: %d %d %d\n", low_temp, high_temp, max_temp); | |
563 | exit(EXIT_FAILURE); | |
564 | } | |
565 | ||
507 | 566 | set_fans_man(fans); |
508 | 567 | |
509 | 568 | new_temp = get_temp(sensors); |
510 | ||
511 | fan_speed = min_fan_speed; | |
512 | set_fan_speed(fans, fan_speed); | |
569 | set_fan_minimum_speed(fans); | |
570 | ||
571 | fan = fans; | |
572 | while(fan != NULL) { | |
573 | ||
574 | fan->step_up = (float)( fan->fan_max_speed - fan->fan_min_speed ) / | |
575 | (float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 ); | |
576 | ||
577 | fan->step_down = (float)( fan->fan_max_speed - fan->fan_min_speed ) / | |
578 | (float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 ); | |
579 | fan = fan->next; | |
580 | } | |
513 | 581 | |
514 | 582 | if(verbose) { |
515 | 583 | printf("Sleeping for 2 seconds to get first temp delta\n"); |
519 | 587 | } |
520 | 588 | } |
521 | 589 | sleep(2); |
522 | ||
523 | step_up = (float)( max_fan_speed - min_fan_speed ) / | |
524 | (float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 ); | |
525 | ||
526 | step_down = (float)( max_fan_speed - min_fan_speed ) / | |
527 | (float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 ); | |
528 | 590 | |
529 | 591 | while(1) { |
530 | 592 | old_temp = new_temp; |
531 | 593 | new_temp = get_temp(sensors); |
532 | 594 | |
533 | if(new_temp >= max_temp && fan_speed != max_fan_speed) { | |
534 | fan_speed = max_fan_speed; | |
535 | } | |
536 | ||
537 | if(new_temp <= low_temp && fan_speed != min_fan_speed) { | |
538 | fan_speed = min_fan_speed; | |
539 | } | |
540 | ||
541 | temp_change = new_temp - old_temp; | |
542 | ||
543 | if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) { | |
544 | steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2; | |
545 | fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) ); | |
546 | } | |
547 | ||
548 | if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) { | |
549 | steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2; | |
550 | fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) ); | |
551 | } | |
552 | ||
553 | if(verbose) { | |
554 | printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed); | |
555 | ||
556 | if(daemonize) { | |
557 | syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed); | |
558 | } | |
559 | } | |
560 | ||
561 | set_fan_speed(fans, fan_speed); | |
595 | fan = fans; | |
596 | ||
597 | while(fan != NULL) { | |
598 | fan_speed = fan->old_speed; | |
599 | ||
600 | if(new_temp >= max_temp && fan->old_speed != fan->fan_max_speed) { | |
601 | fan_speed = fan->fan_max_speed; | |
602 | } | |
603 | ||
604 | if(new_temp <= low_temp && fan_speed != fan->fan_min_speed) { | |
605 | fan_speed = fan->fan_min_speed; | |
606 | } | |
607 | ||
608 | temp_change = new_temp - old_temp; | |
609 | ||
610 | if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) { | |
611 | steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2; | |
612 | fan_speed = max( fan_speed, ceil(fan->fan_min_speed + steps * fan->step_up) ); | |
613 | } | |
614 | ||
615 | if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) { | |
616 | steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2; | |
617 | fan_speed = min( fan_speed, floor(fan->fan_max_speed - steps * fan->step_down) ); | |
618 | } | |
619 | ||
620 | if(verbose) { | |
621 | printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed); | |
622 | ||
623 | if(daemonize) { | |
624 | syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d", old_temp, new_temp, fan_speed); | |
625 | } | |
626 | } | |
627 | ||
628 | set_fan_speed(fan, fan_speed); | |
629 | fan = fan->next; | |
630 | } | |
562 | 631 | |
563 | 632 | if(verbose) { |
564 | 633 | printf("Sleeping for %d seconds\n", polling_interval); |
568 | 637 | syslog(LOG_INFO, "Sleeping for %d seconds", polling_interval); |
569 | 638 | } |
570 | 639 | } |
571 | ||
572 | sleep(polling_interval); | |
573 | } | |
574 | } | |
640 | ||
641 | // call nanosleep instead of sleep to avoid rt_sigprocmask and | |
642 | // rt_sigaction | |
643 | struct timespec ts; | |
644 | ts.tv_sec = polling_interval; | |
645 | ts.tv_nsec = 0; | |
646 | nanosleep(&ts, NULL); | |
647 | } | |
648 | } |
15 | 15 | |
16 | 16 | #ifndef _MBPFAN_H_ |
17 | 17 | #define _MBPFAN_H_ |
18 | ||
19 | /** Basic fan speed parameters | |
20 | */ | |
21 | extern int min_fan_speed; | |
22 | extern int max_fan_speed; | |
23 | 18 | |
24 | 19 | /** Temperature Thresholds |
25 | 20 | * low_temp - temperature below which fan speed will be at minimum |
42 | 37 | struct s_fans; |
43 | 38 | typedef struct s_fans t_fans; |
44 | 39 | |
40 | char *smprintf(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | |
41 | ||
45 | 42 | /** |
46 | 43 | * Return true if the kernel is < 3.15.0 |
47 | 44 | */ |
52 | 49 | * /etc/mbpfan.conf |
53 | 50 | * If it fails, the default hardcoded settings are used |
54 | 51 | */ |
55 | void retrieve_settings(const char* settings_path); | |
52 | void retrieve_settings(const char* settings_path, t_fans *fans); | |
56 | 53 | |
57 | 54 | /** |
58 | 55 | * Detect the sensors in /sys/devices/platform/coretemp.0/temp |
56 | * and /sys/devices/platform/coretemp.1/temp etc | |
59 | 57 | * Return a linked list of t_sensors (first temperature detected) |
60 | 58 | */ |
61 | 59 | t_sensors *retrieve_sensors(); |
85 | 83 | void set_fans_auto(t_fans *fans); |
86 | 84 | |
87 | 85 | /** |
88 | * Given a list of sensors with associated fans | |
86 | * Given a sensors with associated fans | |
89 | 87 | * Change their speed |
90 | 88 | */ |
91 | void set_fan_speed(t_fans* fans, int speed); | |
89 | void set_fan_speed(t_fans* fan, int speed); | |
92 | 90 | |
91 | /** | |
92 | * Given a list of fans set their minumum fan speed | |
93 | */ | |
94 | void set_fan_minimum_speed(t_fans* fans); | |
93 | 95 | /** |
94 | 96 | * Return average CPU temp in degrees (ceiling) |
95 | 97 | */ |
100 | 102 | */ |
101 | 103 | void mbpfan(); |
102 | 104 | |
103 | #endif⏎ | |
105 | #endif |
8 | 8 | #include "global.h" |
9 | 9 | #include "mbpfan.h" |
10 | 10 | #include "settings.h" |
11 | #include "main.h" | |
11 | 12 | #include "minunit.h" |
12 | 13 | |
13 | 14 | int tests_run = 0; |
115 | 116 | return 0; |
116 | 117 | } |
117 | 118 | |
118 | mu_assert("Could not read min_fan_speed from config file",settings_get_int(settings, "general", "min_fan_speed") != 0); | |
119 | mu_assert("Could not read max_fan_speed from config file",settings_get_int(settings, "general", "max_fan_speed") != 0); | |
120 | 119 | mu_assert("Could not read low_temp from config file",settings_get_int(settings, "general", "low_temp") != 0); |
121 | 120 | mu_assert("Could not read high_temp from config file",settings_get_int(settings, "general", "high_temp") != 0); |
122 | 121 | mu_assert("Could not read max_temp from config file",settings_get_int(settings, "general", "max_temp") != 0); |
129 | 128 | |
130 | 129 | static const char *test_settings() |
131 | 130 | { |
132 | retrieve_settings("./mbpfan.conf.test1"); | |
133 | mu_assert("max_fan_speed value is not 6200", max_fan_speed == 6200); | |
134 | mu_assert("polling_interval is not 1", polling_interval == 1); | |
135 | retrieve_settings("./mbpfan.conf"); | |
136 | mu_assert("min_fan_speed value is not 2000", min_fan_speed == 2000); | |
131 | t_fans* fan = (t_fans *) malloc( sizeof( t_fans ) ); | |
132 | fan->fan_id = 1; | |
133 | fan->fan_max_speed = -1; | |
134 | fan->next = NULL; | |
135 | ||
136 | retrieve_settings("./mbpfan.conf.test1", fan); | |
137 | mu_assert("max_fan_speed value is not 6200", fan->fan_max_speed == 6200); | |
138 | mu_assert("polling_interval is not 2", polling_interval == 2); | |
139 | ||
140 | fan->fan_min_speed = -1; | |
141 | retrieve_settings("./mbpfan.conf.test0", fan); | |
142 | mu_assert("min_fan_speed value is not 2000", fan->fan_min_speed == 2000); | |
137 | 143 | mu_assert("polling_interval is not 7", polling_interval == 7); |
138 | return 0; | |
139 | } | |
140 | ||
144 | ||
145 | t_fans* fan2 = (t_fans *)malloc(sizeof(t_fans)); | |
146 | fan2->fan_id = 2; | |
147 | fan2->fan_max_speed = -1; | |
148 | fan->next = fan2; | |
149 | ||
150 | retrieve_settings("./mbpfan.conf.test2", fan); | |
151 | mu_assert("min_fan1_speed value is not 2000", fan->fan_min_speed == 2000); | |
152 | mu_assert("min_fan2_speed value is not 2000", fan->next->fan_min_speed == 2000); | |
153 | ||
154 | free(fan2); | |
155 | fan->next = NULL; | |
156 | free(fan); | |
157 | ||
158 | return 0; | |
159 | ||
160 | } | |
141 | 161 | int received = 0; |
142 | 162 | |
143 | 163 | static void handler(int signal) |
144 | 164 | { |
165 | t_fans* fan = (t_fans *) malloc( sizeof( t_fans ) ); | |
166 | fan->fan_id = 1; | |
167 | fan->next = NULL; | |
168 | ||
145 | 169 | |
146 | 170 | switch(signal) { |
147 | 171 | case SIGHUP: |
148 | 172 | received = 1; |
149 | retrieve_settings("./mbpfan.conf.test1"); | |
173 | retrieve_settings("./mbpfan.conf.test1", fan); | |
174 | free(fan); | |
150 | 175 | break; |
151 | 176 | |
152 | 177 | default: |
153 | 178 | received = 0; |
179 | free(fan); | |
154 | 180 | break; |
155 | 181 | } |
156 | 182 | } |
165 | 191 | |
166 | 192 | static const char *test_settings_reload() |
167 | 193 | { |
194 | t_fans* fan = (t_fans *) malloc( sizeof( t_fans ) ); | |
195 | fan->fan_id = 1; | |
196 | fan->next = NULL; | |
197 | ||
168 | 198 | signal(SIGHUP, handler); |
169 | retrieve_settings("./mbpfan.conf"); | |
199 | retrieve_settings("./mbpfan.conf", fan); | |
170 | 200 | printf("Testing the _supplied_ mbpfan.conf (not the one you are using)..\n"); |
171 | mu_assert("min_fan_speed value is not 2000 before SIGHUP", min_fan_speed == 2000); | |
172 | mu_assert("polling_interval is not 7 before SIHUP", polling_interval == 7); | |
201 | // cannot tests min_fan_speed since it is not set and thus auto-detected | |
202 | mu_assert("polling_interval is not 1 before SIGHUP", polling_interval == 1); | |
173 | 203 | raise(SIGHUP); |
174 | mu_assert("min_fan_speed value is not 6200 after SIGHUP", min_fan_speed == 6200); | |
175 | mu_assert("polling_interval is not 1 after SIHUP", polling_interval == 1); | |
176 | retrieve_settings("./mbpfan.conf"); | |
204 | mu_assert("min_fan_speed value is not 6200 after SIGHUP", fan->fan_min_speed == 6200); | |
205 | mu_assert("polling_interval is not 2 after SIGHUP", polling_interval == 2); | |
206 | retrieve_settings("./mbpfan.conf", fan); | |
207 | free(fan); | |
177 | 208 | return 0; |
178 | 209 | } |
179 | 210 | |
192 | 223 | |
193 | 224 | int tests() |
194 | 225 | { |
226 | check_requirements(); | |
227 | ||
195 | 228 | printf("Starting the tests..\n"); |
196 | 229 | printf("It is normal for them to take a bit to finish.\n"); |
197 | 230 | |
198 | 231 | const char *result = all_tests(); |
199 | 232 | |
200 | 233 | if (result != 0) { |
201 | printf("%s \n", result); | |
234 | printf("Error: %s \n", result); | |
202 | 235 | |
203 | 236 | } else { |
204 | 237 | printf("ALL TESTS PASSED\n"); |