root/lm-sensors/trunk/prog/sensord/sensord.c @ 5722

Revision 5722, 5.1 KB (checked in by andy, 4 years ago)

sensord: This patch does some refactoring of the loadConfig()
function.

* Simplifying the conditions makes code flow clearer and eliminates
long lines (> 80 chars).
* Removed useless stat() call.
* Return -1 in error case, instead of several positive values (never defined).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * sensord
3 *
4 * A daemon that periodically logs sensor information to syslog.
5 *
6 * Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <limits.h>
28#include <string.h>
29#include <signal.h>
30#include <syslog.h>
31#include <unistd.h>
32#include <time.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35
36#include "args.h"
37#include "sensord.h"
38
39static int logOpened = 0;
40
41static volatile sig_atomic_t done = 0;
42static volatile sig_atomic_t reload = 0;
43
44#define LOG_BUFFER 4096
45
46#include <stdarg.h>
47
48void sensorLog(int priority, const char *fmt, ...)
49{
50        static char buffer[1 + LOG_BUFFER];
51        va_list ap;
52        va_start(ap, fmt);
53        vsnprintf(buffer, LOG_BUFFER, fmt, ap);
54        buffer[LOG_BUFFER] = '\0';
55        va_end(ap);
56        if (sensord_args.debug || (priority < LOG_DEBUG)) {
57                if (logOpened) {
58                        syslog(priority, "%s", buffer);
59                } else {
60                        fprintf(stderr, "%s\n", buffer);
61                        fflush(stderr);
62                }
63        }
64}
65
66static void signalHandler(int sig)
67{
68        signal(sig, signalHandler);
69        switch (sig) {
70        case SIGTERM:
71                done = 1;
72                break;
73        case SIGHUP:
74                reload = 1;
75                break;
76        }
77}
78
79static int sensord(void)
80{
81        int ret = 0;
82        int scanValue = 0, logValue = 0;
83        /*
84         * First RRD update at next RRD timeslot to prevent failures due
85         * one timeslot updated twice on restart for example.
86         */
87        int rrdValue = sensord_args.rrdTime - time(NULL) %
88                sensord_args.rrdTime;
89
90        sensorLog(LOG_INFO, "sensord started");
91
92        while (!done) {
93                if (reload) {
94                        ret = reloadLib(sensord_args.cfgFile);
95                        if (ret)
96                                sensorLog(LOG_NOTICE, "configuration reload"
97                                          " error");
98                        reload = 0;
99                }
100                if (sensord_args.scanTime && (scanValue <= 0)) {
101                        if ((ret = scanChips()))
102                                sensorLog(LOG_NOTICE,
103                                          "sensor scan error (%d)", ret);
104                        scanValue += sensord_args.scanTime;
105                }
106                if (sensord_args.logTime && (logValue <= 0)) {
107                        if ((ret = readChips()))
108                                sensorLog(LOG_NOTICE,
109                                          "sensor read error (%d)", ret);
110                        logValue += sensord_args.logTime;
111                }
112                if (sensord_args.rrdTime && sensord_args.rrdFile &&
113                    (rrdValue <= 0)) {
114                        if ((ret = rrdUpdate()))
115                                sensorLog(LOG_NOTICE,
116                                          "rrd update error (%d)", ret);
117                        /*
118                         * The amount of time to wait is computed using the
119                         * same method as in RRD instead of simply adding the
120                         * interval.
121                         */
122                        rrdValue = sensord_args.rrdTime - time(NULL) %
123                                sensord_args.rrdTime;
124                }
125                if (!done) {
126                        int a = sensord_args.logTime ? logValue : INT_MAX;
127                        int b = sensord_args.scanTime ? scanValue : INT_MAX;
128                        int c = (sensord_args.rrdTime && sensord_args.rrdFile)
129                                ? rrdValue : INT_MAX;
130                        int sleepTime = (a < b) ? ((a < c) ? a : c) :
131                                ((b < c) ? b : c);
132                        sleep(sleepTime);
133                        scanValue -= sleepTime;
134                        logValue -= sleepTime;
135                        rrdValue -= sleepTime;
136                }
137        }
138
139        sensorLog(LOG_INFO, "sensord stopped");
140
141        return ret;
142}
143
144static void openLog(void)
145{
146        openlog("sensord", 0, sensord_args.syslogFacility);
147        logOpened = 1;
148}
149
150static void daemonize(void)
151{
152        int pid;
153        struct stat fileStat;
154        FILE *file;
155
156        if (chdir("/") < 0) {
157                perror("chdir()");
158                exit(EXIT_FAILURE);
159        }
160
161        if (!(stat(sensord_args.pidFile, &fileStat)) &&
162            ((!S_ISREG(fileStat.st_mode)) || (fileStat.st_size > 11))) {
163                fprintf(stderr,
164                        "Error: PID file `%s' already exists and looks suspicious.\n",
165                        sensord_args.pidFile);
166                exit(EXIT_FAILURE);
167        }
168
169        if (!(file = fopen(sensord_args.pidFile, "w"))) {
170                fprintf(stderr, "fopen(\"%s\"): %s\n", sensord_args.pidFile,
171                        strerror(errno));
172                exit(EXIT_FAILURE);
173        }
174
175        /* I should use sigaction but... */
176        if (signal(SIGTERM, signalHandler) == SIG_ERR ||
177            signal (SIGHUP, signalHandler) == SIG_ERR) {
178                perror("signal");
179                exit(EXIT_FAILURE);
180        }
181
182        if ((pid = fork()) == -1) {
183                perror("fork()");
184                exit(EXIT_FAILURE);
185        } else if (pid != 0) {
186                fprintf(file, "%d\n", pid);
187                fclose(file);
188                unloadLib();
189                exit(EXIT_SUCCESS);
190        }
191
192        if (setsid() < 0) {
193                perror("setsid()");
194                exit(EXIT_FAILURE);
195        }
196
197        fclose(file);
198        close(STDIN_FILENO);
199        close(STDOUT_FILENO);
200        close(STDERR_FILENO);
201}
202
203static void undaemonize(void)
204{
205        unlink(sensord_args.pidFile);
206        closelog();
207}
208
209int main(int argc, char **argv)
210{
211        int ret = 0;
212
213        if (parseArgs(argc, argv) ||
214            parseChips(argc, argv))
215                exit(EXIT_FAILURE);
216
217        if (loadLib(sensord_args.cfgFile))
218                exit(EXIT_FAILURE);
219
220        openLog();
221
222        if (sensord_args.rrdFile) {
223                ret = rrdInit();
224                if (ret)
225                        exit(EXIT_FAILURE);
226        }
227
228        if (sensord_args.doCGI) {
229                ret = rrdCGI();
230        } else {
231                daemonize();
232                ret = sensord();
233                undaemonize();
234        }
235
236        if (unloadLib())
237                exit(EXIT_FAILURE);
238
239        return ret;
240}
Note: See TracBrowser for help on using the browser.