Skip to content
Snippets Groups Projects
Commit 8184a62a authored by Zámolyi Csaba Ferenc's avatar Zámolyi Csaba Ferenc
Browse files

Created skeleton daemon and added PIDfile

parent 08f20cc3
No related branches found
Tags 1.4.3
No related merge requests found
cmake_minimum_required(VERSION 3.25)
project(batteryd)
set(CMAKE_CXX_STANDARD 20)
add_executable(batteryd src/main.cpp src/daemonutils.cpp)
if (USE_SYSLOG)
add_definitions(-DUSE_SYSLOG)
endif ()
add_executable(batteryd src/daemonutils.h src/daemonutils.cpp src/main.cpp)
......@@ -14,7 +14,7 @@ The tresholds and the actions to take are both configurable in `/etc/systemcshee
### Why?
Why not? It was a long and rough day and around 2AM, after 5-6 beers, it seemed to be a good idea to
write a daemon for a task I wanted, but mostly for my personal amusement.
This is generally intended as a joke, although for me it serves real purpose.
This is generally intended as a joke, although for me, it serves real purpose.
I didn't want to use any 3rd party service for monitoring my battery level(s),
because I know exactly what I want and how I want to do it and what configuration options I wish.
Obviously this could have been done with a shell script in a cronjob, but it's not that fun.
......@@ -33,6 +33,10 @@ You can also monitor your wireless keyboard and/or mouse. At this time, only one
An example can be found in [batteryd.conf.example](batteryd.conf.example)
### Building
You can build this project with CMake or technically anything else you can make it work with.
If you want to use `syslog` instead of a logfile in `/var/log/systemcshee/batteryd.log` then add `-DUSE_SYSLOG=1` to cmake parameters or define `USE_SYSLOG` any other way.
### License
This project is under the [GNU General Public License v3.0](COPYING)
......@@ -4,15 +4,30 @@
* License: GNU GPL v3.0
*/
#include "daemonutils.h"
#ifdef USE_SYSLOG
#include <syslog.h>
#endif
#include <cstdlib>
#include <unistd.h>
#include <csignal>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <cstdio>
#include <fstream>
#include <fcntl.h>
#include <cstring>
static void daemonize() {
#define DEFAULT_PIDFILE_LOCATION "/var/run/systemcshee/batteryd.pid"
static int pidfile = -1;
std::ofstream *logfile_stream;
void daemonize() {
// First fork to lose parent to PID1, then create own session
pid_t pid;
pid = fork();
......@@ -40,12 +55,59 @@ static void daemonize() {
stdin = fopen("/dev/null", "r");
stdout = fopen("/dev/null", "w+");
stderr = fopen("/dev/null", "w+");
// Create PIDfile
// TODO: make pidfile configurable from cli options
char tmpstr[32];
pidfile = open(DEFAULT_PIDFILE_LOCATION, O_RDWR | O_CREAT, 0640);
if (pidfile < 0) {
// Cannot open pidfile, exiting
exit(EXIT_FAILURE);
}
// Try to acquire a lock
if (lockf(pidfile, F_TEST, 0) < 0) {
if (errno == EACCES || errno == EAGAIN) {
// Locked by probably another batteryd instance, exiting for now
// TODO: decide what to do when another instance is running
exit(EXIT_FAILURE);
}
// Something else went wrong, exiting
exit(EXIT_FAILURE);
}
// Save the PID
sprintf(tmpstr, "%d\n", getpid());
write(pidfile, tmpstr, strlen(tmpstr));
}
void setup_logging() {
#ifdef USE_SYSLOG
openlog("systemcshee-batteryd", LOG_PID, LOG_DAEMON);
//#else
logfile_stream = new std::ofstream();
logfile_stream->open("/var/log/systemcshee/batteryd.log", std::ios_base::out | std::ios_base::app);
logfile_stream->write("Batteryd started", 100);
logfile_stream->close();
#endif
}
static void signal_handler(int signal) {
if (signal == SIGINT || signal == SIGTERM) {
}
}
void shutdown() {
logfile_stream->close();
delete logfile_stream;
close(pidfile);
}
static void setup() {
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN);
/* Open the log file */
openlog("systemcshee-batteryd", LOG_PID, LOG_DAEMON);
}
\ No newline at end of file
/*
* Created by: Cshee, 2023-02-09
* Project: SystemCshee / batteryd
* License: GNU GPL v3.0
*/
#ifndef BATTERYD_DAEMONUTILS_H
#define BATTERYD_DAEMONUTILS_H
void daemonize();
void setup_logging();
void shutdown();
#endif //BATTERYD_DAEMONUTILS_H
#include <iostream>
#include <csignal>
#include "daemonutils.h"
int main() {
std::cout << "Hello, World!" << std::endl;
daemonize();
setup_logging();
while (true) {
sleep(20);
break;
}
shutdown();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment