[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 1/5] libc: POSIX: sigaction



+ libc: POSIX: Signale von reinen Handler auf sigactions umgestellt (die
  aber alles ausser dem Handler ignorieren). sigaction() hinzugefuegt.
---
 src/modules/include/signal.h   |   56 +++++++++++++++++++++++++++------------
 src/modules/lib/posix/signal.c |   47 ++++++++++++++++++++++++++++++---
 2 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/src/modules/include/signal.h b/src/modules/include/signal.h
index 0571c08..364cd67 100644
--- a/src/modules/include/signal.h
+++ b/src/modules/include/signal.h
@@ -75,7 +75,7 @@ typedef uint32_t sig_atomic_t;
 /// Pipe-Fehler
 #define SIGPIPE 13
 
-/// TODO
+/// alarm()-Timer ist abgelaufen
 #define SIGALRM 14
 
 /// Prozess terminieren (kann abgefangen werden)
@@ -110,22 +110,6 @@ void _signal_default_handler(int signal);
 #define SIG_IGN (NULL)
 
 
-
-/// Typ fuer einen Pointer auf einen Signal-Handler
-typedef void (*sighandler_t)(int);
-
-/// Einen Signal-Hander aendern
-sighandler_t signal(int signum, sighandler_t handler);
-
-/// Ein Signal zum aktuellen Prozess senden
-int raise(int signal);
-
-/// Ein Signal an einen anderen Prozess senden
-int kill(pid_t pid, int signal);
-
-
-
-
 // Verwaltung von sigsets
 
 /// Typ fuer eine Sammlung von Signalen
@@ -149,5 +133,43 @@ int sigdelset(sigset_t *sigset, int signal);
 int sigismember(const sigset_t *sigset, int signal);
 
 
+
+// Signal-Handler
+
+/// Typ fuer einen Pointer auf einen Signal-Handler
+typedef void (*sighandler_t)(int);
+
+/// Bei einem Signal auszufuehrende Aktion
+struct sigaction {
+    sighandler_t    sa_handler;
+    sigset_t        sa_mask;
+    int             sa_flags;
+};
+
+
+/**
+ * Aendert die auszufuehrende Aktion fuer ein Signal und gibt die alte Aktion
+ * zurueck.
+ *
+ * @param sig Nummer des Signals, fuer das die Aktion geaendert wird
+ * @param action Neue Aktion. Wenn NULL, wird nur die aktuelle Aktion
+ * zurueckgegeben, aber keine Aenderung vorgenommen
+ * @param old Wenn nicht NULL, wird hier die alte Aktion gespeichert
+ */
+int sigaction(int sig, const struct sigaction* action, struct sigaction* old);
+
+/// Einen Signal-Hander aendern
+sighandler_t signal(int signum, sighandler_t handler);
+
+/// Ein Signal zum aktuellen Prozess senden
+int raise(int signal);
+
+/// Ein Signal an einen anderen Prozess senden
+int kill(pid_t pid, int signal);
+
+
+
+
+
 #endif // ifndef _SIGNAL_H_
 
diff --git a/src/modules/lib/posix/signal.c b/src/modules/lib/posix/signal.c
index 4d70a61..03cfb56 100644
--- a/src/modules/lib/posix/signal.c
+++ b/src/modules/lib/posix/signal.c
@@ -37,7 +37,7 @@
 #include <sleep.h>
 
 /// Array mit Pointern auf die Signal-Handler
-static sighandler_t signal_handlers [_SIGNO_MAX];
+static struct sigaction sigactions[_SIGNO_MAX];
 static bool initialized = FALSE;
 
 /**
@@ -46,8 +46,9 @@ static bool initialized = FALSE;
 static void init_signals(void)
 {
     int i;
+    memset(sigactions, 0, sizeof(sigactions));
     for (i = 0; i < _SIGNO_MAX; i++) {
-        signal_handlers[i] = SIG_DFL;
+        sigactions[i].sa_handler = SIG_DFL;
     }
 
     initialized = TRUE;
@@ -73,7 +74,7 @@ int raise(int signum)
         return -1;
     }
 
-    sighandler_t handler = signal_handlers[signum];
+    sighandler_t handler = sigactions[signum].sa_handler;
     if (handler != NULL) {
         handler(signum);
     }
@@ -150,14 +151,50 @@ sighandler_t signal(int signum, sighandler_t handler)
     }    
 
     // Alter Handler Speichern, weil er zurueck gegeben wird
-    sighandler_t old_handler = signal_handlers[signum];
+    sighandler_t old_handler = sigactions[signum].sa_handler;
     
     // Neuer setzen
-    signal_handlers[signum] = handler;
+    sigactions[signum].sa_handler = handler;
 
     return old_handler;
 }
 
+/**
+ * Aendert die auszufuehrende Aktion fuer ein Signal und gibt die alte Aktion
+ * zurueck.
+ * TODO Momentan nur Handler, POSIX sieht da mehr vor
+ *
+ * @param sig Nummer des Signals, fuer das die Aktion geaendert wird
+ * @param action Neue Aktion. Wenn NULL, wird nur die aktuelle Aktion
+ * zurueckgegeben, aber keine Aenderung vorgenommen
+ * @param old Wenn nicht NULL, wird hier die alte Aktion gespeichert
+ */
+int sigaction(int sig, const struct sigaction* action, struct sigaction* old)
+{
+    // Initialisieren falls das noch nicht gemacht ist
+    if (initialized == FALSE) {
+        init_signals();
+    }
+
+    // Ungueltige Signale und SIGKILL koennen nicht gesetzt werden
+    if ((sig >= _SIGNO_MAX) || (sig == SIGKILL)) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    // Alte Werte zurueckgeben
+    if (old != NULL) {
+        memcpy(old, &sigactions[sig], sizeof(*old));
+    }
+
+    // Neue Werte setzen
+    if (action != NULL) {
+        memcpy(&sigactions[sig], action, sizeof(*action));
+    }
+
+    return 0;
+}
+
 
 /**
  * Sigset initialisieren und/oder leeren.
-- 
1.6.0.2