[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 4/5] libc: POSIX: Mehr Signale
+ libc: POSIX: Signale blockieren mit sigprocmask()
! libc: POSIX: raise() setzt errno, wenn es -1 zurueckgibt
---
src/modules/include/signal.h | 20 +++++++++++++-
src/modules/lib/posix/signal.c | 59 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletions(-)
diff --git a/src/modules/include/signal.h b/src/modules/include/signal.h
index 364cd67..ab67d88 100644
--- a/src/modules/include/signal.h
+++ b/src/modules/include/signal.h
@@ -146,6 +146,12 @@ struct sigaction {
int sa_flags;
};
+enum {
+ SIG_BLOCK,
+ SIG_UNBLOCK,
+ SIG_SETMASK,
+};
+
/**
* Aendert die auszufuehrende Aktion fuer ein Signal und gibt die alte Aktion
@@ -158,9 +164,21 @@ struct sigaction {
*/
int sigaction(int sig, const struct sigaction* action, struct sigaction* old);
-/// Einen Signal-Hander aendern
+/// Einen Signal-Handler aendern
sighandler_t signal(int signum, sighandler_t handler);
+/**
+ * Verwaltung von blockierten Signalen
+ *
+ * @param mode SIG_BLOCK: Alle Signale aus sigset blockieren
+ * SIG_UNBLOCK: Alle Signale aus sigset wieder aktivieren
+ * SIG_SETMASK: sigset als neue Signal-Maske benutzen
+ *
+ * @return 0 bei Erfolg. -1 und errno = EINVAL, wenn mode einen unerlaubten
+ * Wert hat.
+ */
+int sigprocmask(int mode, const sigset_t* sigset, sigset_t* oldset);
+
/// Ein Signal zum aktuellen Prozess senden
int raise(int signal);
diff --git a/src/modules/lib/posix/signal.c b/src/modules/lib/posix/signal.c
index 03cfb56..e35064d 100644
--- a/src/modules/lib/posix/signal.c
+++ b/src/modules/lib/posix/signal.c
@@ -38,6 +38,7 @@
/// Array mit Pointern auf die Signal-Handler
static struct sigaction sigactions[_SIGNO_MAX];
+static sigset_t sigmask;
static bool initialized = FALSE;
/**
@@ -46,7 +47,10 @@ static bool initialized = FALSE;
static void init_signals(void)
{
int i;
+
memset(sigactions, 0, sizeof(sigactions));
+ memset(&sigmask, 0, sizeof(sigmask));
+
for (i = 0; i < _SIGNO_MAX; i++) {
sigactions[i].sa_handler = SIG_DFL;
}
@@ -71,9 +75,16 @@ int raise(int signum)
// Wenn das Signal Groesser ist als die Groesste gueltige wird sofort
// abgebrochen.
if (signum >= _SIGNO_MAX) {
+ errno = EINVAL;
return -1;
}
+ // Pruefen, ob das Signal nicht blockiert ist
+ if (sigismember(&sigmask, signum)) {
+ return 0;
+ }
+
+ // Handler aufrufen
sighandler_t handler = sigactions[signum].sa_handler;
if (handler != NULL) {
handler(signum);
@@ -290,6 +301,54 @@ int sigismember(const sigset_t *sigset, int signum)
}
/**
+ * Verwaltung von blockierten Signalen
+ *
+ * @param mode SIG_BLOCK: Alle Signale aus sigset blockieren
+ * SIG_UNBLOCK: Alle Signale aus sigset wieder aktivieren
+ * SIG_SETMASK: sigset als neue Signal-Maske benutzen
+ *
+ * @return 0 bei Erfolg. -1 und errno = EINVAL, wenn mode einen unerlaubten
+ * Wert hat.
+ */
+int sigprocmask(int mode, const sigset_t* sigset, sigset_t* oldset)
+{
+ int i;
+
+ if (oldset != NULL) {
+ memcpy(oldset, &sigmask, sizeof(sigset_t));
+ }
+
+ switch (mode) {
+ case SIG_BLOCK:
+ for (i = 0; i < _SIGNO_MAX; i++) {
+ if (sigismember(sigset, i)) {
+ sigaddset(&sigmask, i);
+ }
+ }
+ break;
+
+ case SIG_UNBLOCK:
+ for (i = 0; i < _SIGNO_MAX; i++) {
+ if (sigismember(sigset, i)) {
+ sigdelset(&sigmask, i);
+ }
+ }
+ break;
+
+ case SIG_SETMASK:
+ memcpy(&sigmask, sigset, sizeof(sigset_t));
+ break;
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/**
* Callbackfunktion fuer alarm()
*/
static void do_alarm(void)
--
1.6.0.2