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>
|
|
|
|
* Modifications (2012) by Daniel Graziotin <dgraziotin@task3.cc>
|
2012-07-04 23:22:48 +00:00
|
|
|
* 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-06-16 09:02:48 +00:00
|
|
|
int write_pid(int pid)
|
|
|
|
{
|
2012-08-22 13:05:52 +00:00
|
|
|
FILE *file = NULL;
|
|
|
|
file = fopen(program_pid, "w");
|
|
|
|
if(file != NULL) {
|
|
|
|
fprintf(file, "%d", pid);
|
|
|
|
fclose(file);
|
|
|
|
return 1;
|
|
|
|
} 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()
|
|
|
|
{
|
2012-08-22 13:05:52 +00:00
|
|
|
FILE *file = NULL;
|
|
|
|
int pid = -1;
|
|
|
|
file = fopen(program_pid, "r");
|
|
|
|
if(file != NULL) {
|
|
|
|
fscanf(file, "%d", &pid);
|
|
|
|
fclose(file);
|
|
|
|
return pid;
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-22 13:05:52 +00:00
|
|
|
return -1;
|
2012-06-15 19:07:11 +00:00
|
|
|
}
|
|
|
|
|
2012-06-16 09:02:48 +00:00
|
|
|
int delete_pid()
|
|
|
|
{
|
2012-08-22 13:05:52 +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)
|
|
|
|
{
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
switch(signal) {
|
2012-06-16 09:02:48 +00:00
|
|
|
case SIGHUP:
|
2012-08-22 13:05:52 +00:00
|
|
|
//TODO: restart myself
|
|
|
|
syslog(LOG_WARNING, "Received SIGHUP signal.");
|
|
|
|
delete_pid();
|
|
|
|
exit(0);
|
|
|
|
break;
|
2012-06-16 09:02:48 +00:00
|
|
|
case SIGTERM:
|
2012-08-22 13:05:52 +00:00
|
|
|
syslog(LOG_WARNING, "Received SIGTERM signal.");
|
|
|
|
delete_pid();
|
|
|
|
//TODO: free resources
|
|
|
|
exit(0);
|
|
|
|
break;
|
2012-06-16 09:02:48 +00:00
|
|
|
case SIGINT:
|
2012-08-22 13:05:52 +00:00
|
|
|
syslog(LOG_WARNING, "Received SIGINT signal.");
|
|
|
|
delete_pid();
|
|
|
|
//TODO: free resources
|
|
|
|
exit(0);
|
2012-06-16 09:02:48 +00:00
|
|
|
default:
|
2012-08-22 13:05:52 +00:00
|
|
|
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
|
|
|
{
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
// Setup signal handling before we start
|
|
|
|
signal(SIGHUP, signal_handler);
|
|
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
signal(SIGINT, signal_handler);
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
syslog(LOG_INFO, "%s starting up", program_name);
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
// Setup syslog logging - see SETLOGMASK(3)
|
|
|
|
if(verbose) {
|
|
|
|
setlogmask(LOG_UPTO(LOG_DEBUG));
|
|
|
|
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
|
|
|
|
} else {
|
|
|
|
setlogmask(LOG_UPTO(LOG_INFO));
|
|
|
|
openlog(program_name, LOG_CONS, LOG_USER);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
pid_t pid_slave;
|
|
|
|
pid_t sid_slave;
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if (daemonize) {
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
pid_slave = fork();
|
|
|
|
if (pid_slave < 0) {
|
|
|
|
exit(EXIT_FAILURE);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-22 13:05:52 +00:00
|
|
|
if (pid_slave > 0) {
|
|
|
|
// kill the father
|
|
|
|
exit(EXIT_SUCCESS);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
umask(0022);
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
// new sid_slave for the child process
|
|
|
|
sid_slave = setsid();
|
|
|
|
if (sid_slave < 0) {
|
|
|
|
exit(EXIT_FAILURE);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if ((chdir("/")) < 0) {
|
|
|
|
exit(EXIT_FAILURE);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-08-22 13:05:52 +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
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
int current_pid = getpid();
|
2012-06-15 19:07:11 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if (read_pid() == -1) {
|
|
|
|
if (verbose) {
|
|
|
|
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-22 13:05:52 +00:00
|
|
|
if (write_pid(current_pid) == 0) {
|
|
|
|
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
|
|
|
|
if (verbose) {
|
|
|
|
printf("ERROR: Can not create a .pid file at: %s. Aborting\n", program_pid);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-08-22 13:05:52 +00:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
} else {
|
|
|
|
if (verbose) {
|
|
|
|
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-22 13:05:52 +00:00
|
|
|
} else {
|
|
|
|
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
|
|
|
|
if (verbose) {
|
|
|
|
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-22 13:05:52 +00:00
|
|
|
exit(EXIT_FAILURE);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
fan_control();
|
2012-06-16 09:02:48 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
if(daemonize) {
|
|
|
|
syslog(LOG_INFO, "%s daemon exiting", program_name);
|
2012-06-16 09:02:48 +00:00
|
|
|
}
|
2012-06-11 19:43:53 +00:00
|
|
|
|
2012-08-22 13:05:52 +00:00
|
|
|
return;
|
2012-06-11 19:43:53 +00:00
|
|
|
}
|