| | 1 | = Programmieren eines daemon in C unter Linux = |
| | 2 | |
| | 3 | Quellen: |
| | 4 | * http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap07-011.htm |
| | 5 | * http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html |
| | 6 | |
| | 7 | Gerüst: |
| | 8 | {{{ |
| | 9 | /* Secumod_Server - daemon.c */ |
| | 10 | #include <stdio.h> |
| | 11 | #include <unistd.h> |
| | 12 | #include <syslog.h> |
| | 13 | #include <sys/types.h> |
| | 14 | #include <sys/stat.h> |
| | 15 | #include <signal.h> |
| | 16 | #include <stdlib.h> |
| | 17 | |
| | 18 | typedef void (*sighandler_t)(int); |
| | 19 | volatile sig_atomic_t sigint = 1; |
| | 20 | static sighandler_t |
| | 21 | |
| | 22 | |
| | 23 | /* Signalhandler (auch ignorieren von Signalen) hinzufügen */ |
| | 24 | handle_signal (int sig_nr, sighandler_t signalhandler) { |
| | 25 | struct sigaction neu_sig, alt_sig; |
| | 26 | neu_sig.sa_handler = signalhandler; |
| | 27 | sigemptyset (&neu_sig.sa_mask); |
| | 28 | neu_sig.sa_flags = SA_RESTART; |
| | 29 | if (sigaction (sig_nr, &neu_sig, &alt_sig) < 0) |
| | 30 | return SIG_ERR; |
| | 31 | return alt_sig.sa_handler; |
| | 32 | } |
| | 33 | |
| | 34 | /* Der Signalhandler für SIGINT/SIGHUP */ |
| | 35 | static void catch_sig (int sig_nr) { |
| | 36 | sigint--; |
| | 37 | } |
| | 38 | |
| | 39 | |
| | 40 | static void start_daemon (const char *log_name, int facility) { |
| | 41 | int i; |
| | 42 | pid_t pid; |
| | 43 | /* Elternprozess beenden, somit haben wir einen Waisen */ |
| | 44 | /* dessen sich jetzt vorerst init annimmt */ |
| | 45 | if ((pid = fork ()) != 0) |
| | 46 | exit (EXIT_FAILURE); |
| | 47 | /* Kindprozess wird zum Sessionführer. Misslingt */ |
| | 48 | /* dies, kann der Fehler daran liegen, dass der */ |
| | 49 | /* Prozess bereits Sessionführer ist */ |
| | 50 | if (setsid() < 0) { |
| | 51 | printf("%s kann nicht Sessionführer werden!\n", |
| | 52 | log_name); |
| | 53 | exit (EXIT_FAILURE); |
| | 54 | } |
| | 55 | /* Signal SIGHUP ignorieren */ |
| | 56 | handle_signal (SIGHUP, SIG_IGN); |
| | 57 | handle_signal (SIGTERM, catch_sig); |
| | 58 | /* Oder einfach: signal(SIGHUP, SIG_IGN) ... */ |
| | 59 | /* Das Kind terminieren */ |
| | 60 | if ((pid = fork ()) != 0) |
| | 61 | exit (EXIT_FAILURE); |
| | 62 | /* Gründe für das Arbeitsverzeichnis: |
| | 63 | * + core-Datei wird im aktuellen Arbeitsverzeichnis |
| | 64 | * hinterlegt. |
| | 65 | * + Damit bei Beendigung mit umount das Dateisystem |
| | 66 | * sicher abgehängt werden kann |
| | 67 | */ |
| | 68 | chdir ("/"); |
| | 69 | /* Damit wir nicht die Bitmaske vom Elternprozess */ |
| | 70 | /* erben bzw. diese bleibt, stellen wir diese auf 0 */ |
| | 71 | umask (0); |
| | 72 | /* Wir schließen alle geöffneten Filedeskriptoren ... */ |
| | 73 | for (i = sysconf (_SC_OPEN_MAX); i > 0; i--) |
| | 74 | close (i); |
| | 75 | /* Da unser Dämonprozess selbst kein Terminal für */ |
| | 76 | /* die Ausgabe hat.... */ |
| | 77 | openlog ( log_name, |
| | 78 | LOG_PID | LOG_CONS| LOG_NDELAY, facility ); |
| | 79 | } |
| | 80 | |
| | 81 | |
| | 82 | int main (int argc, char **argv) { |
| | 83 | int time = 10; |
| | 84 | start_daemon ("kidstimerDaemon", LOG_LOCAL0); |
| | 85 | syslog( LOG_NOTICE, "kidstimer - Daemon gestartet ...\n"); |
| | 86 | while (sigint) { |
| | 87 | /* Enlosschleifen: Hier sollte nun der Code für den |
| | 88 | * Daemon stehen, was immer er auch tun soll. |
| | 89 | * Bspw. E-Mails abholen, versenden (was kein |
| | 90 | * Verweis sein soll, um mit dem Spammen anzufangen); |
| | 91 | * Bei Fehlermeldungen beispielsweise: |
| | 92 | * if(dies_ist_passiert) |
| | 93 | * syslog(LOG_WARNING, "dies_ist_Passiert"); |
| | 94 | * else if(das_ist_Passiert) |
| | 95 | * syslog(LOG_INFO, "das_ist_Passiert"); |
| | 96 | */ |
| | 97 | sleep(time); |
| | 98 | syslog( LOG_NOTICE, "kidstimer - Daemon läuft bereits %d Sekunden\n", time ); |
| | 99 | syslog( LOG_NOTICE, "kidstimer - sigint: %d\n", sigint ); |
| | 100 | //break; |
| | 101 | } |
| | 102 | syslog( LOG_NOTICE, "kidstimer - Daemon hat sich beendet\n"); |
| | 103 | closelog(); |
| | 104 | return EXIT_SUCCESS; |
| | 105 | } |
| | 106 | }}} |