Das Signal wird unblocked- Der Prozess fägt da an, wo er aufgehört hat (als das Signal kam).
==Besonderheit==: Systemaufrufe
Manche System Calls (z. B. read, write, open) werden automatisch ==neu gestartet==, falls sie unterbrochen wurden.
Falls schon ein Teil der Daten übertragen wurde, liefern sie Partial Success zurück.
==Verhalten ändern==
Mit siginterrupt() kannst du festlegen, dass ein System Call nicht automatisch neu gestartet wird, sondern stattdessen mit einem Fehler (EINTR) abbricht.
Important
Beispiel:
Dein Programm wartet mit read() auf Eingabe.
Ctrl+C sendet SIGINT.
Dein Handler läuft → read() wird automatisch neu gestartet, außer du hast es mit siginterrupt() verboten.
Was passiert mit Signalen beim Kindprozess ? 🧑🧒
Nach dem fork() Kommando erbt der Kindprozess alle vom ElternP. installierten Signal Handler.
Nach [[15-05-2025]] werden alle Handler auf die default Aktion gesetzt.
Falls der ELternprozess ein Signal ignoriert, dann ignoriert das Kind diesen ebenfalls.
**SIGCHLD**bei Kind-Ende
Wenn ein Kindprozess beendet wird, bekommt der Elternprozess SIGCHLD.
Standardmäßig muss der Elternprozess dann wait() aufrufen, um den Zombie zu beseitigen.
Sonderfall: Wenn der Elternprozess SIGCHLD ignoriert, werden keine Zombies erstellt.
Jetzt sigaction() anstatt von signal() - Warum ?
Speichern der ursprünglichen Signalbehandlung → Saven wie es davor behandelt wurde, und anschließend zurücksetzen.
In der Lage, andere Signale zu blockieren, während der Signal Handler läuft. → Verhindern, dass Code inmnerhalb einer kritischen Operation unterbrochen wird.
Definition von sigaction()
Funktionsprototyp
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
sig: Welche Signalnummer (z. B. SIGINT, SIGTERM).
act: Neue Behandlung für dieses Signal (zeigt auf eine befüllte struct sigaction).
oact: (optional) OLD ACT - Hierhin schreibt der Kernel die alte Behandlung zurück. NULL, wenn du sie nicht brauchst.
Rückgabe: 0 bei Erfolg, -1 bei Fehler (Details in errno).
DatenStruktur
struct sigaction { union { void (*sa_handler)(int); // einfacher Handler void (*sa_sigaction)(int, siginfo_t *, void *); // erweiterte Infos } __sigaction_u; sigset_t sa_mask; // blockierte Signale während Handler läuft int sa_flags; // Optionen (z. B. SA_RESTART)};
sa_handler: Zeiger auf deinen einfachen Handler void handler(int sig).
sa_sigaction: Alternative erweiterte Handler-Signatur mit Zusatzinfos (siginfo_t), wenn du SA_SIGINFO nutzt.
sa_mask: Eine Signalmaske. Alles, was du hier einträgst, wird zusätzlich blockiert, während der Handler läuft.
sa_flags : Zusätzlich setzbare Flags
GrundIdee der Nutzung
struct sigaction action;sigset_t signal_mask;/* 1) Maske vorbereiten: Was soll während des Handlers blockiert sein? */sigfillset(&signal_mask);// Praxis: oft gezielt mit sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGINT);/* 2) Struktur befüllen */action.sa_handler = handler; // deine Handler-Funktionaction.sa_mask = signal_mask; // blockierte Signale während Handleraction.sa_flags = 0; // keine Spezialoptionen/* Handler installieren */sigaction(SIGTERM, &action, NULL);
Code Example eines Signal Handlers
\#include <stdio.h>\#include <stdlib.h>\#include <signal.h>\#include <unistd.h>/* Global flag to tell the main loop to exit */volatile sig_atomic_t stop = 0;/* Signal handler function */void handle_sigint(int sig) { (void)sig; // unused parameter write(STDOUT_FILENO, "\nCaught SIGINT, cleaning up...\n", 31); stop = 1; // set flag to stop main loop}int main() { struct sigaction action; /* Configure handler */ action.sa_handler = handle_sigint; sigemptyset(&action.sa_mask); // don't block any other signals action.sa_flags = SA_RESTART; // restart interrupted syscalls /* Install handler for SIGINT */ if (sigaction(SIGINT, &action, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } printf("Running... press Ctrl+C to stop.\n"); /* Main loop */ while (!stop) { printf("Working...\n"); sleep(1); // simulate work } printf("Program exiting cleanly.\n"); return 0;}
print signal names
void psignal(unsigned sig, const char *s);print message according to signal number sigchar * strsignal(int sig);return pointer to message according to signal number sig
Beispiele für Signal Handler
SIGCHILD - Zombie Prozesse vermeiden
void reapchild(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0);}