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

Re: [tyndur-devel] [PATCH 4/5] libc: POSIX: Mehr Signale



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: pgpWRn4Ps1956.pgp
Description: PGP signature