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

Revision 1389, 4.6 KB (checked in by merlin, 11 years ago)

mh: initialize ret to 0, thanks to Christian Hammers <ch@…> for
noticing

  • 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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <errno.h>
26#include <limits.h>
27#include <string.h>
28#include <signal.h>
29#include <syslog.h>
30#include <unistd.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33
34#include "sensord.h"
35
36static int logOpened = 0;
37
38static volatile sig_atomic_t done = 0;
39
40#define LOG_BUFFER 4096
41
42#include <stdarg.h>
43
44void
45sensorLog
46(int priority, const char *fmt, ...) {
47  static char buffer[1 + LOG_BUFFER];
48  va_list ap;
49  va_start (ap, fmt);
50  vsnprintf (buffer, LOG_BUFFER, fmt, ap);
51  buffer[LOG_BUFFER] = '\0';
52  va_end (ap);
53  if (debug || (priority < LOG_DEBUG)) {
54    if (logOpened) {
55      syslog (priority, "%s", buffer);
56    } else {
57      fprintf (stderr, "%s\n", buffer);
58      fflush (stderr);
59    }
60  }
61}
62
63static void
64signalHandler
65(int sig) {
66  signal (sig, signalHandler);
67  switch (sig) {
68    case SIGTERM:
69      done = 1;
70      break;
71  }
72}
73
74static int
75sensord
76(void) {
77  int ret = 0;
78  int scanValue = 0, logValue = 0, rrdValue = 0;
79
80  sensorLog (LOG_INFO, "sensord started");
81
82  while (!done && (ret == 0)) {
83    if (ret == 0)
84      ret = reloadLib ();
85    if ((ret == 0) && scanTime) { /* should I scan on the read cycle? */
86      ret = scanChips ();
87      if (scanValue <= 0)
88        scanValue += scanTime;
89    }
90    if ((ret == 0) && logTime && (logValue <= 0)) {
91      ret = readChips ();
92      logValue += logTime;
93    }
94    if ((ret == 0) && rrdTime && rrdFile && (rrdValue <= 0)) {
95      ret = rrdUpdate ();
96      rrdValue += rrdTime;
97    }
98    if (!done && (ret == 0)) {
99      int a = logTime ? logValue : INT_MAX;
100      int b = scanTime ? scanValue : INT_MAX;
101      int c = (rrdTime && rrdFile) ? rrdValue : INT_MAX;
102      int sleepTime = (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
103      sleep (sleepTime);
104      scanValue -= sleepTime;
105      logValue -= sleepTime;
106      rrdValue -= sleepTime;
107    }
108  }
109
110  sensorLog (LOG_INFO, "sensord %s", ret ? "failed" : "stopped");
111
112  return ret;
113}
114
115static void
116openLog
117(void) {
118  openlog ("sensord", 0, syslogFacility);
119  logOpened = 1; 
120}
121
122static void
123daemonize
124(void) {
125  int pid;
126  struct stat fileStat;
127  FILE *file;
128
129  if (chdir ("/") < 0) {
130    perror ("chdir()");
131    exit (EXIT_FAILURE);
132  }
133
134  if (!(stat (pidFile, &fileStat)) &&
135      ((!S_ISREG (fileStat.st_mode)) || (fileStat.st_size > 11))) {
136    fprintf (stderr, "Error: PID file `%s' already exists and looks suspicious.\n", pidFile);
137    exit (EXIT_FAILURE);
138  }
139 
140  if (!(file = fopen (pidFile, "w"))) {
141    fprintf (stderr, "fopen(\"%s\"): %s\n", pidFile, strerror (errno));
142    exit (EXIT_FAILURE);
143  }
144 
145  /* I should use sigaction but... */
146  if (signal (SIGTERM, signalHandler) == SIG_ERR) {
147    perror ("signal(SIGTERM)");
148    exit (EXIT_FAILURE);
149  }
150
151  if ((pid = fork ()) == -1) {
152    perror ("fork()");
153    exit (EXIT_FAILURE);
154  } else if (pid != 0) {
155    fprintf (file, "%d\n", pid);
156    fclose (file);
157    exit (EXIT_SUCCESS);
158  }
159
160  if (setsid () < 0) {
161    perror ("setsid()");
162    exit (EXIT_FAILURE);
163  }
164
165  fclose (file);
166  close (STDIN_FILENO);
167  close (STDOUT_FILENO);
168  close (STDERR_FILENO);
169}
170
171static void 
172undaemonize
173(void) {
174  unlink (pidFile);
175  closelog ();
176}
177
178int
179main
180(int argc, char **argv) {
181  int ret = 0;
182 
183  if (parseArgs (argc, argv) ||
184      parseChips (argc, argv))
185    exit (EXIT_FAILURE);
186 
187  if (initLib () ||
188      loadLib ())
189    exit (EXIT_FAILURE);
190
191  if (isDaemon)
192    openLog ();
193  if (rrdFile)
194    ret = rrdInit ();
195 
196  if (ret) {
197  } else if (doCGI) {
198    ret = rrdCGI ();
199  } else if (isDaemon) {
200    daemonize ();
201    ret = sensord ();
202    undaemonize ();
203  } else {
204    if (doSet)
205      ret = setChips ();
206    else if (doScan)
207      ret = scanChips ();
208    else if (rrdFile)
209      ret = rrdUpdate ();
210    else
211      ret = readChips ();
212  }
213 
214  if (unloadLib ())
215    exit (EXIT_FAILURE);
216 
217  return ret;
218}
Note: See TracBrowser for help on using the browser.