guix-commits
[Top][All Lists]
Advanced

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

[shepherd] 01/04: system: 'sigprocmask' returns the previous set of bloc


From: Ludovic Courtès
Subject: [shepherd] 01/04: system: 'sigprocmask' returns the previous set of blocked signals.
Date: Tue, 2 Jun 2020 17:36:48 -0400 (EDT)

civodul pushed a commit to branch master
in repository shepherd.

commit bc74b5e33625a082ad0d44fe4409d459222aa295
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Sat May 30 17:44:07 2020 +0200

    system: 'sigprocmask' returns the previous set of blocked signals.
    
    * modules/shepherd/system.scm.in (sigismember, sigset->list): New
    procedures.
    (sigprocmask): Return the old set of signals.
---
 modules/shepherd/system.scm.in | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/modules/shepherd/system.scm.in b/modules/shepherd/system.scm.in
index ac822f8..9c55c69 100644
--- a/modules/shepherd/system.scm.in
+++ b/modules/shepherd/system.scm.in
@@ -148,6 +148,11 @@ ctrlaltdel(8) and see kernel/reboot.c in Linux."
 (define sigaddset
   (syscall->procedure int "sigaddset" `(* ,int)))
 
+(define sigismember
+  (let ((proc (syscall->procedure int "sigismember" `(* ,int))))
+    (lambda (set signal)
+      (not (zero? (proc set signal))))))
+
 (define (sigset signals)
   "Return a pointer to a fresh 'sigset_t' for SIGNALS."
   (let ((set (allocate-sigset)))
@@ -155,6 +160,20 @@ ctrlaltdel(8) and see kernel/reboot.c in Linux."
     (for-each (cut sigaddset set <>) signals)
     set))
 
+(define sigset->list
+  (let ((all-signals
+         (filter integer?
+                 (module-map (lambda (symbol variable)
+                               (let ((str (symbol->string symbol)))
+                                 (and (string-prefix? "SIG" str)
+                                      (not (string-prefix? "SIG_" str))
+                                      (variable-ref variable))))
+                             (resolve-interface '(guile))))))
+    (lambda (set)
+      "Return the list of integers (signal numbers) corresponding to SET, a
+sigset pointer."
+      (filter (cut sigismember set <>) all-signals))))
+
 (define %sizeof-struct-signalfd-siginfo
   ;; Size of 'struct signalfd_siginfo' or zero if it doesn't exist, as is the
   ;; case on GNU/Hurd.
@@ -186,13 +205,17 @@ number of the signal received."
   (let ((proc (syscall->procedure int "pthread_sigmask" `(,int * *))))
     (lambda (how signals)
       "Add SIGNALS, a list of SIG* values, to the set of blocked signals if
-HOW is SIG_BLOCK, or unblock them if HOW is SIG_UNBLOCK."
+HOW is SIG_BLOCK, or unblock them if HOW is SIG_UNBLOCK.  Return the previous
+set of blocked signals as a list of SIG* values."
+      (define old
+        (allocate-sigset))
+
       (let-values (((result err)
-                    (proc how (sigset signals) %null-pointer)))
+                    (proc how (sigset signals) old)))
         (if (= -1 result)
             (throw 'system-error "sigprocmask" "~A"
                    (list (strerror err)) (list err))
-            result)))))
+            (sigset->list old))))))
 
 (define (block-signals signals)
   "Block SIGNALS, a list of SIG* values, in the current thread."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]