mbpfan/src/daemon.c

207 lines
4.8 KiB
C
Raw Normal View History

2012-06-11 19:43:53 +00:00
/**
2012-06-15 19:07:11 +00:00
* Copyright (C) 2012 Peter Lombardo <http://peterlombardo.wikidot.com/linux-daemon-in-c>
2014-06-21 17:35:56 +00:00
* Modifications (2012) by Daniel Graziotin <daniel@ineed.coffee>
* Modifications (2012) by Ismail Khatib <ikhatib@gmail.com>
2012-06-15 19:07:11 +00:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
2012-06-11 19:43:53 +00:00
*/
2012-06-15 19:07:11 +00:00
2012-06-11 19:43:53 +00:00
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include "mbpfan.h"
#include "global.h"
2012-11-18 21:16:49 +00:00
#include "daemon.h"
2012-06-11 19:43:53 +00:00
2012-06-16 09:02:48 +00:00
int write_pid(int pid)
{
FILE *file = NULL;
2012-11-12 10:48:05 +00:00
file = fopen(PROGRAM_PID, "w");
2012-08-23 20:32:49 +00:00
if(file != NULL) {
fprintf(file, "%d", pid);
fclose(file);
return 1;
2012-08-23 20:32:49 +00:00
} else {
return 0;
2012-06-16 09:02:48 +00:00
}
2012-06-15 19:07:11 +00:00
}
2012-06-16 09:02:48 +00:00
int read_pid()
{
FILE *file = NULL;
int pid = -1;
2012-11-12 10:48:05 +00:00
file = fopen(PROGRAM_PID, "r");
2012-08-23 20:32:49 +00:00
if(file != NULL) {
fscanf(file, "%d", &pid);
fclose(file);
return pid;
2012-06-16 09:02:48 +00:00
}
2012-08-23 20:32:49 +00:00
return -1;
2012-06-15 19:07:11 +00:00
}
2012-06-16 09:02:48 +00:00
int delete_pid()
{
2012-11-12 10:48:05 +00:00
return remove(PROGRAM_PID);
2012-06-15 19:07:11 +00:00
}
2012-06-11 19:43:53 +00:00
void signal_handler(int signal)
{
switch(signal) {
2012-06-16 09:02:48 +00:00
case SIGHUP:
syslog(LOG_WARNING, "Received SIGHUP signal.");
2012-11-18 21:16:49 +00:00
retrieve_settings(NULL);
break;
2014-06-22 14:48:44 +00:00
2012-06-16 09:02:48 +00:00
case SIGTERM:
syslog(LOG_WARNING, "Received SIGTERM signal.");
delete_pid();
//TODO: free resources
exit(EXIT_SUCCESS);
break;
2014-06-22 14:48:44 +00:00
2012-06-16 09:02:48 +00:00
case SIGINT:
syslog(LOG_WARNING, "Received SIGINT signal.");
delete_pid();
//TODO: free resources
exit(EXIT_SUCCESS);
2014-06-22 14:48:44 +00:00
2012-10-20 15:18:30 +00:00
case SIGSTOP:
syslog(LOG_WARNING, "Received SIGSTOP signal.");
delete_pid();
//TODO: free resources
exit(EXIT_SUCCESS);
2014-06-22 14:48:44 +00:00
2012-06-16 09:02:48 +00:00
default:
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
break;
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
}
2012-06-15 19:47:23 +00:00
void go_daemon(void (*fan_control)())
2012-06-11 19:43:53 +00:00
{
// Setup signal handling before we start
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
2012-11-18 21:16:49 +00:00
signal(SIGSTOP, signal_handler);
2012-06-11 19:43:53 +00:00
2012-11-12 10:48:05 +00:00
syslog(LOG_INFO, "%s starting up", PROGRAM_NAME);
2012-06-11 19:43:53 +00:00
// Setup syslog logging - see SETLOGMASK(3)
if(verbose) {
setlogmask(LOG_UPTO(LOG_DEBUG));
2012-11-12 10:48:05 +00:00
openlog(PROGRAM_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
2012-08-23 20:32:49 +00:00
} else {
setlogmask(LOG_UPTO(LOG_INFO));
2012-11-12 10:48:05 +00:00
openlog(PROGRAM_NAME, LOG_CONS, LOG_USER);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
pid_t pid_slave;
pid_t sid_slave;
2012-06-11 19:43:53 +00:00
if (daemonize) {
2012-06-11 19:43:53 +00:00
pid_slave = fork();
2012-08-23 20:32:49 +00:00
if (pid_slave < 0) {
exit(EXIT_FAILURE);
2012-06-16 09:02:48 +00:00
}
2012-08-23 20:32:49 +00:00
if (pid_slave > 0) {
2012-11-18 21:16:49 +00:00
signal(SIGCHLD, SIG_IGN);
// kill the father
exit(EXIT_SUCCESS);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
umask(0022);
2012-06-11 19:43:53 +00:00
// new sid_slave for the child process
sid_slave = setsid();
2012-08-23 20:32:49 +00:00
if (sid_slave < 0) {
exit(EXIT_FAILURE);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
if ((chdir("/")) < 0) {
exit(EXIT_FAILURE);
2012-06-16 09:02:48 +00:00
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
2012-06-15 19:07:11 +00:00
int current_pid = getpid();
2012-06-15 19:07:11 +00:00
if (read_pid() == -1) {
if (verbose) {
2012-11-12 10:48:05 +00:00
printf("Writing a new .pid file with value %d at: %s\n", current_pid, PROGRAM_PID);
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, PROGRAM_PID);
2012-06-11 19:43:53 +00:00
}
2012-08-23 20:32:49 +00:00
if (write_pid(current_pid) == 0) {
2012-11-12 10:48:05 +00:00
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", PROGRAM_PID);
2012-08-23 20:32:49 +00:00
if (verbose) {
2012-11-12 10:48:05 +00:00
printf("ERROR: Can not create a .pid file at: %s. Aborting\n", PROGRAM_PID);
2012-06-16 09:02:48 +00:00
}
2012-08-23 20:32:49 +00:00
exit(EXIT_FAILURE);
2012-08-23 20:32:49 +00:00
} else {
if (verbose) {
2012-11-12 10:48:05 +00:00
printf("Successfully written a new .pid file with value %d at: %s\n", current_pid, PROGRAM_PID);
syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, PROGRAM_PID);
2012-06-16 09:02:48 +00:00
}
}
2012-08-23 20:32:49 +00:00
} else {
2012-11-12 10:48:05 +00:00
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", PROGRAM_PID);
2012-08-23 20:32:49 +00:00
if (verbose) {
2012-11-12 10:48:05 +00:00
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", PROGRAM_PID);
2012-06-16 09:02:48 +00:00
}
2012-08-23 20:32:49 +00:00
exit(EXIT_FAILURE);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
fan_control();
2012-06-16 09:02:48 +00:00
if(daemonize) {
2012-11-12 10:48:05 +00:00
syslog(LOG_INFO, "%s daemon exiting", PROGRAM_NAME);
2012-06-16 09:02:48 +00:00
}
2012-06-11 19:43:53 +00:00
return;
2012-06-11 19:43:53 +00:00
}