Last active
December 6, 2017 10:43
-
-
Save frankharvey/252827c2974b12ec716e869f22e27d09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// rrd_temp.c | |
// Modified for sysctl OneWire data collection | |
// Created by Dr. Rolf Jansen on 2016-08-24. | |
// Copyright 2016 Dr. Rolf Jansen. All rights reserved. | |
// sudo cc rrd_temp.c -Wno-empty-body -Ofast -g0 -o rdd_temp | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <fcntl.h> | |
#include <signal.h> | |
#include <string.h> | |
#include <syslog.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/sysctl.h> | |
#define DAEMON_NAME "rrd_temp" | |
const char *pidfname = "/var/run/rrd_temp.pid"; | |
const char *tmplccfn = "/tmp/rrd_temp.dummy"; | |
void usage(const char *executable) | |
{ | |
const char *r = executable + strlen(executable); | |
while (--r >= executable && *r != '/'); | |
r++; | |
printf("\nusage: %s [-p file] [-f] [-n] [-t] [-h]\n", r); | |
printf(" -p file the path to the pid file [default: /var/run/rrd_temp.pid]\n"); | |
printf(" -f foreground mode, don't fork off as a daemon.\n"); | |
printf(" -n no console, don't fork off as a daemon - started/managed by launchd.\n"); | |
printf(" -t idle time in seconds, [default: 4 s].\n"); | |
printf(" -h shows these usage instructions.\n\n"); | |
} | |
static void signals(int sig) | |
{ | |
switch (sig) | |
{ | |
case SIGHUP: | |
syslog(LOG_ERR, "Received SIGHUP signal."); | |
kill(0, SIGHUP); | |
unlink(tmplccfn); | |
unlink(pidfname); | |
exit(0); | |
break; | |
case SIGINT: | |
syslog(LOG_ERR, "Received SIGINT signal."); | |
kill(0, SIGINT); | |
unlink(pidfname); | |
exit(0); | |
break; | |
case SIGQUIT: | |
syslog(LOG_ERR, "Received SIGQUIT signal."); | |
kill(0, SIGQUIT); | |
unlink(pidfname); | |
exit(0); | |
break; | |
case SIGTERM: | |
syslog(LOG_ERR, "Received SIGTERM signal."); | |
kill(0, SIGTERM); | |
unlink(pidfname); | |
exit(0); | |
break; | |
default: | |
syslog(LOG_ERR, "Unhandled signal (%d) %s", sig, strsignal(sig)); | |
break; | |
} | |
} | |
typedef enum | |
{ | |
noDaemon, | |
launchdDaemon, | |
discreteDaemon | |
} DaemonKind; | |
void daemonize(DaemonKind kind) | |
{ | |
switch (kind) | |
{ | |
case noDaemon: | |
openlog(DAEMON_NAME, LOG_NDELAY | LOG_PID | LOG_CONS, LOG_USER); | |
break; | |
case launchdDaemon: | |
signal(SIGTERM, signals); | |
openlog(DAEMON_NAME, LOG_NDELAY | LOG_PID, LOG_USER); | |
break; | |
case discreteDaemon: | |
{ | |
// fork off the parent process | |
pid_t pid = fork(); | |
if (pid < 0) | |
exit(EXIT_FAILURE); | |
// if we got a good PID, then we can exit the parent process. | |
if (pid > 0) | |
exit(EXIT_SUCCESS); | |
// The child process continues here. | |
// first close all open descriptors | |
for (int i = getdtablesize(); i >= 0; --i) | |
close(i); | |
// re-open stdin, stdout, stderr connected to /dev/null | |
int inouterr = open("/dev/null", O_RDWR); // stdin | |
dup(inouterr); // stdout | |
dup(inouterr); // stderr | |
// Change the file mode mask, 027 = complement of 750 | |
umask(027); | |
pid_t sid = setsid(); | |
if (sid < 0) | |
exit(EXIT_FAILURE); // should log the failure before exiting? | |
// Check and write our pid lock file | |
// and mutually exclude other instances from running | |
int pidfile = open(pidfname, O_RDWR|O_CREAT, 0640); | |
if (pidfile < 0) | |
exit(1); // can not open our pid file | |
if (lockf(pidfile, F_TLOCK, 0) < 0) | |
exit(0); // can not lock our pid file -- was locked already | |
// only first instance continues beyound this | |
char s[256]; | |
int l = snprintf(s, 256, "%d\n", getpid()); | |
write(pidfile, s, l); // record pid to our pid file | |
signal(SIGHUP, signals); | |
signal(SIGINT, signals); | |
signal(SIGQUIT, signals); | |
signal(SIGTERM, signals); | |
signal(SIGCHLD, SIG_IGN); // ignore child | |
signal(SIGTSTP, SIG_IGN); // ignore tty signals | |
signal(SIGTTOU, SIG_IGN); | |
signal(SIGTTIN, SIG_IGN); | |
openlog(DAEMON_NAME, LOG_NDELAY | LOG_PID, LOG_USER); | |
break; | |
} | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
char ch, *p; | |
int64_t idle = 4; | |
const char *cmd = argv[0]; | |
DaemonKind dKind = discreteDaemon; | |
while ((ch = getopt(argc, argv, "p:fnt:h")) != -1) | |
{ | |
switch (ch) | |
{ | |
case 'p': | |
pidfname = optarg; | |
break; | |
case 'f': | |
dKind = noDaemon; | |
break; | |
case 'n': | |
dKind = launchdDaemon; | |
break; | |
case 't': | |
if ((idle = strtol(optarg, &p, 10)) <= 0) | |
{ | |
usage(cmd); | |
exit(0); | |
} | |
break; | |
case 'h': | |
default: | |
usage(cmd); | |
exit(0); | |
break; | |
} | |
} | |
daemonize(dKind); | |
FILE *outfile = fopen("/rrdtemp/testfile", "w"); | |
size_t size; | |
int buf; | |
size = sizeof buf; | |
for (;;) | |
{ | |
sleep(idle); | |
sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0); | |
buf -=273150; | |
buf *= 1e-3;// convert Celsius to Fahreneit // | |
buf *= 9; | |
buf /= 5; | |
buf += 32; | |
fprintf(outfile, "%d F \n" , buf); | |
fclose(outfile); | |
return 0; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment