Programmieren eines daemon in C unter Linux
Quellen:
- http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap07-011.htm
- http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
Gerüst:
/* Secumod_Server - daemon.c */
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdlib.h>
typedef void (*sighandler_t)(int);
volatile sig_atomic_t sigint = 1;
static sighandler_t
/* Signalhandler (auch ignorieren von Signalen) hinzufügen */
handle_signal (int sig_nr, sighandler_t signalhandler) {
struct sigaction neu_sig, alt_sig;
neu_sig.sa_handler = signalhandler;
sigemptyset (&neu_sig.sa_mask);
neu_sig.sa_flags = SA_RESTART;
if (sigaction (sig_nr, &neu_sig, &alt_sig) < 0)
return SIG_ERR;
return alt_sig.sa_handler;
}
/* Der Signalhandler für SIGINT/SIGHUP */
static void catch_sig (int sig_nr) {
sigint--;
}
static void start_daemon (const char *log_name, int facility) {
int i;
pid_t pid;
/* Elternprozess beenden, somit haben wir einen Waisen */
/* dessen sich jetzt vorerst init annimmt */
if ((pid = fork ()) != 0)
exit (EXIT_FAILURE);
/* Kindprozess wird zum Sessionführer. Misslingt */
/* dies, kann der Fehler daran liegen, dass der */
/* Prozess bereits Sessionführer ist */
if (setsid() < 0) {
printf("%s kann nicht Sessionführer werden!\n",
log_name);
exit (EXIT_FAILURE);
}
/* Signal SIGHUP ignorieren */
handle_signal (SIGHUP, SIG_IGN);
/* Signal SIGTERM beendet MainLOOP */
handle_signal (SIGTERM, catch_sig);
/* Das Kind terminieren */
if ((pid = fork ()) != 0)
exit (EXIT_FAILURE);
/* Gründe für das Arbeitsverzeichnis:
* + core-Datei wird im aktuellen Arbeitsverzeichnis
* hinterlegt.
* + Damit bei Beendigung mit umount das Dateisystem
* sicher abgehängt werden kann
*/
chdir ("/");
/* Damit wir nicht die Bitmaske vom Elternprozess */
/* erben bzw. diese bleibt, stellen wir diese auf 0 */
umask (0);
/* Wir schließen alle geöffneten Filedeskriptoren ... */
for (i = sysconf (_SC_OPEN_MAX); i > 0; i--)
close (i);
/* Da unser Dämonprozess selbst kein Terminal für */
/* die Ausgabe hat.... */
openlog ( log_name,
LOG_PID | LOG_CONS| LOG_NDELAY, facility );
}
int main (int argc, char **argv) {
int time = 10;
start_daemon ("SecuMod_ServerDaemon", LOG_LOCAL0);
syslog( LOG_NOTICE, "SecuMod_ServerDaemon gestartet ...\n");
while (sigint) {
/* Enlosschleifen: Hier sollte nun der Code für den
* Daemon stehen, was immer er auch tun soll.
* Bspw. E-Mails abholen, versenden (was kein
* Verweis sein soll, um mit dem Spammen anzufangen);
* Bei Fehlermeldungen beispielsweise:
* if(dies_ist_passiert)
* syslog(LOG_WARNING, "dies_ist_Passiert");
* else if(das_ist_Passiert)
* syslog(LOG_INFO, "das_ist_Passiert");
*/
sleep(time);
syslog( LOG_NOTICE, "SecuMod_ServerDaemon läuft\n");
//break;
}
syslog( LOG_NOTICE, "SecuMod_ServerDaemon hat sich beendet\n");
closelog();
return EXIT_SUCCESS;
}
Last modified
10 years ago
Last modified on Aug 28, 2016, 10:12:11 AM
Note:
See TracWiki
for help on using the wiki.