root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensord/sensord.c @ 5163

Revision 5163, 5.2 KB (checked in by khali, 7 years ago)

Patch from Aurelien Jarno:

I have just noticed that the FSF address is the old one in all files
except COPYING. Please find a patch below to fix that.

  • 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 "sensord.h"
37
38static int logOpened = 0;
39
40static volatile sig_atomic_t done = 0;
41static volatile sig_atomic_t reload = 0;
42
43#define LOG_BUFFER 4096
44
45#include <stdarg.h>
46
47void
48sensorLog
49(int priority, const char *fmt, ...) {
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 (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
67signalHandler
68(int sig) {
69  signal (sig, signalHandler);
70  switch (sig) {
71    case SIGTERM:
72      done = 1;
73      break;
74    case SIGHUP:
75      reload = 1;
76      break;
77  }
78}
79
80static int
81sensord
82(void) {
83  int ret = 0;
84  int scanValue = 0, logValue = 0;
85  /*
86   * First RRD update at next RRD timeslot to prevent failures due
87   * one timeslot updated twice on restart for example.
88   */
89  int rrdValue = rrdTime - time(NULL) % rrdTime;
90
91  sensorLog (LOG_INFO, "sensord started");
92
93  while (!done && (ret == 0)) {
94    if (reload) {
95      ret = reloadLib (sensorsCfgFile);
96      reload = 0;
97    }
98    if ((ret == 0) && scanTime) { /* should I scan on the read cycle? */
99      ret = scanChips ();
100      if (scanValue <= 0)
101        scanValue += scanTime;
102    }
103    if ((ret == 0) && logTime && (logValue <= 0)) {
104      ret = readChips ();
105      logValue += logTime;
106    }
107    if ((ret == 0) && rrdTime && rrdFile && (rrdValue <= 0)) {
108      ret = rrdUpdate ();
109      /*
110       * The amount of time to wait is computed using the same method as
111       * in RRD instead of simply adding the interval.
112       */
113      rrdValue = rrdTime - time(NULL) % rrdTime;
114    }
115    if (!done && (ret == 0)) {
116      int a = logTime ? logValue : INT_MAX;
117      int b = scanTime ? scanValue : INT_MAX;
118      int c = (rrdTime && rrdFile) ? rrdValue : INT_MAX;
119      int sleepTime = (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
120      sleep (sleepTime);
121      scanValue -= sleepTime;
122      logValue -= sleepTime;
123      rrdValue -= sleepTime;
124    }
125  }
126
127  if (ret)
128    sensorLog (LOG_INFO, "sensord failed (%d)", ret);
129  else
130    sensorLog (LOG_INFO, "sensord stopped");
131
132  return ret;
133}
134
135static void
136openLog
137(void) {
138  openlog ("sensord", 0, syslogFacility);
139  logOpened = 1; 
140}
141
142static void
143daemonize
144(void) {
145  int pid;
146  struct stat fileStat;
147  FILE *file;
148
149  if (chdir ("/") < 0) {
150    perror ("chdir()");
151    exit (EXIT_FAILURE);
152  }
153
154  if (!(stat (pidFile, &fileStat)) &&
155      ((!S_ISREG (fileStat.st_mode)) || (fileStat.st_size > 11))) {
156    fprintf (stderr, "Error: PID file `%s' already exists and looks suspicious.\n", pidFile);
157    exit (EXIT_FAILURE);
158  }
159 
160  if (!(file = fopen (pidFile, "w"))) {
161    fprintf (stderr, "fopen(\"%s\"): %s\n", pidFile, strerror (errno));
162    exit (EXIT_FAILURE);
163  }
164 
165  /* I should use sigaction but... */
166  if (signal (SIGTERM, signalHandler) == SIG_ERR ||
167      signal (SIGHUP, signalHandler) == SIG_ERR) {
168    perror ("signal");
169    exit (EXIT_FAILURE);
170  }
171
172  if ((pid = fork ()) == -1) {
173    perror ("fork()");
174    exit (EXIT_FAILURE);
175  } else if (pid != 0) {
176    fprintf (file, "%d\n", pid);
177    fclose (file);
178    unloadLib ();
179    exit (EXIT_SUCCESS);
180  }
181
182  if (setsid () < 0) {
183    perror ("setsid()");
184    exit (EXIT_FAILURE);
185  }
186
187  fclose (file);
188  close (STDIN_FILENO);
189  close (STDOUT_FILENO);
190  close (STDERR_FILENO);
191}
192
193static void 
194undaemonize
195(void) {
196  unlink (pidFile);
197  closelog ();
198}
199
200int
201main
202(int argc, char **argv) {
203  int ret = 0;
204 
205  if (parseArgs (argc, argv) ||
206      parseChips (argc, argv))
207    exit (EXIT_FAILURE);
208 
209  if (loadLib (sensorsCfgFile))
210    exit (EXIT_FAILURE);
211
212  if (isDaemon)
213    openLog ();
214  if (rrdFile)
215    ret = rrdInit ();
216 
217  if (ret) {
218  } else if (doCGI) {
219    ret = rrdCGI ();
220  } else if (isDaemon) {
221    daemonize ();
222    ret = sensord ();
223    undaemonize ();
224  } else {
225    if (doSet)
226      ret = setChips ();
227    else if (doScan)
228      ret = scanChips ();
229    else if (rrdFile)
230      ret = rrdUpdate ();
231    else
232      ret = readChips ();
233  }
234 
235  if (unloadLib ())
236    exit (EXIT_FAILURE);
237 
238  return ret;
239}
Note: See TracBrowser for help on using the browser.