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

Revision 1024, 4.2 KB (checked in by merlin, 13 years ago)

Added -p/--pid-file option to write a PID file for the daemon and
-d/--debug option to allow unwanted information to be more easily
suppressed. Kicked version to 0.5.0. -- merlin@…

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