On Wed, Apr 22 20:18, Kevin Wolf wrote: > + 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 Mit ein bisschen Einrückung wäre das doch viel lesbarer. ;-) > + * > + * @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)); Hm könnte man da nicht direkt zuweisen? > + } > + > + 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) Sieht sonst vernünftig aus. -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgp3fHISMRPWN.pgp
Description: PGP signature