unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: 41507@debbugs.gnu.org
Cc: othacehe@gnu.org, "Ludovic Courtès" <ludo@gnu.org>
Subject: [bug#41507] [PATCH Shepherd 1/2] system: Add support for 'signalfd'.
Date: Sun, 24 May 2020 16:36:59 +0200	[thread overview]
Message-ID: <20200524143700.6378-1-ludo@gnu.org> (raw)
In-Reply-To: <20200524142700.6151-1-ludo@gnu.org>

* configure.ac: Add 'AC_CHECK_SIZEOF' calls for 'struct
signalfd_siginfo' and 'sigset_t'.  Add 'AC_COMPUTE_INT' for
'SFD_CLOEXEC', 'SIG_BLOCK', and 'SIG_UNBLOCK'.  Substitute the results.
* modules/shepherd/system.scm.in (allocate-sigset, sigemptyset)
(sigaddset, sigset): New procedures.
(%sizeof-struct-signalfd-siginfo, SFD_CLOEXEC): New variables.
(signalfd, consume-signalfd-siginfo): New procedures.
(SIG_BLOCK, SIG_UNBLOCK): New variables.
(sigprocmask, block-signals, unblock-signals): New procedures.
---
 configure.ac                   | 18 ++++++++++
 modules/shepherd/system.scm.in | 65 ++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/configure.ac b/configure.ac
index 5d11846..052a826 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,24 @@ AC_COMPUTE_INT([PR_SET_CHILD_SUBREAPER], [PR_SET_CHILD_SUBREAPER], [#include <sy
 AC_SUBST([PR_SET_CHILD_SUBREAPER])
 AC_MSG_RESULT([done])
 
+dnl Check the size of 'signalfd_siginfo'.  If it's undefined, returns zero.
+AC_CHECK_SIZEOF([struct signalfd_siginfo], [], [#include <sys/signalfd.h>])
+AC_CHECK_SIZEOF([sigset_t], [], [#include <signal.h>])
+
+AC_MSG_CHECKING([<sys/signalfd.h> and <sys/signal.h> constants])
+AC_COMPUTE_INT([SFD_CLOEXEC], [SFD_CLOEXEC], [#include <sys/signalfd.h>])
+AC_COMPUTE_INT([SIG_BLOCK], [SIG_BLOCK], [#include <sys/signal.h>])
+AC_COMPUTE_INT([SIG_UNBLOCK], [SIG_UNBLOCK], [#include <sys/signal.h>])
+AC_MSG_RESULT([done])
+
+SIZEOF_STRUCT_SIGNALFD_SIGINFO="$ac_cv_sizeof_struct_signalfd_siginfo"
+SIZEOF_SIGSET_T="$ac_cv_sizeof_sigset_t"
+AC_SUBST([SIZEOF_STRUCT_SIGNALFD_SIGINFO])
+AC_SUBST([SIZEOF_SIGSET_T])
+AC_SUBST([SFD_CLOEXEC])
+AC_SUBST([SIG_BLOCK])
+AC_SUBST([SIG_UNBLOCK])
+
 AC_MSG_CHECKING([whether to build crash handler])
 case "$host_os" in
   linux-gnu*)  build_crash_handler=yes;;
diff --git a/modules/shepherd/system.scm.in b/modules/shepherd/system.scm.in
index e5ecd1f..872fad4 100644
--- a/modules/shepherd/system.scm.in
+++ b/modules/shepherd/system.scm.in
@@ -20,8 +20,10 @@
 
 (define-module (shepherd system)
   #:use-module (system foreign)
+  #:use-module (ice-9 binary-ports)
   #:use-module (rnrs bytevectors)
   #:use-module (srfi srfi-11)
+  #:use-module (srfi srfi-26)
   #:export (disable-reboot-on-ctrl-alt-del
             reboot
             halt
@@ -30,6 +32,11 @@
             prctl
             PR_SET_CHILD_SUBREAPER
             getpgid
+            SFD_CLOEXEC
+            signalfd
+            consume-signalfd-siginfo
+            block-signals
+            unblock-signals
             without-automatic-finalization))
 
 ;; The <sys/reboot.h> constants.
@@ -132,6 +139,64 @@ ctrlaltdel(8) and see kernel/reboot.c in Linux."
                    (list err))
             result)))))
 
+(define (allocate-sigset)
+  (bytevector->pointer (make-bytevector @SIZEOF_SIGSET_T@)))
+
+(define sigemptyset
+  (syscall->procedure int "sigemptyset" '(*)))
+
+(define sigaddset
+  (syscall->procedure int "sigaddset" `(* ,int)))
+
+(define (sigset signals)
+  "Return a pointer to a fresh 'sigset_t' for SIGNALS."
+  (let ((set (allocate-sigset)))
+    (sigemptyset set)
+    (for-each (cut sigaddset set <>) signals)
+    set))
+
+(define %sizeof-struct-signalfd-siginfo
+  ;; Size of 'struct signalfd_siginfo' or zero if it doesn't exist, as is the
+  ;; case on GNU/Hurd.
+  @SIZEOF_STRUCT_SIGNALFD_SIGINFO@)
+
+(define SFD_CLOEXEC @SFD_CLOEXEC@)
+
+(define signalfd
+  (let ((proc (syscall->procedure int "signalfd" `(,int * ,int))))
+    (lambda* (fd signals #:optional (flags SFD_CLOEXEC))
+      "Return an open input port over a signal file descriptor for SIGNALS, a
+list of signal constants; if FD is -1, a new file descriptor is allocated,
+otherwise FD is returned and its associated state is updated.  FLAGS must be a
+bitmask of SFD_CLOEXEC or SFD_NONBLOCK."
+      (fdopen (proc fd (sigset signals) flags) "r0"))))
+
+(define (consume-signalfd-siginfo port)
+  "Read a 'signalfd_siginfo' structure from PORT and discard it.  Return the
+number of the signal received."
+  (let ((bv (get-bytevector-n port %sizeof-struct-signalfd-siginfo)))
+    ;; The first 'uint32_t' field of 'struct signalfd_siginfo' is the signal
+    ;; number.
+    (bytevector-u32-native-ref bv 0)))
+
+(define SIG_BLOCK @SIG_BLOCK@)
+(define SIG_UNBLOCK @SIG_UNBLOCK@)
+
+(define sigprocmask
+  (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."
+      (proc how (sigset signals) %null-pointer))))
+
+(define (block-signals signals)
+  "Block SIGNALS, a list of SIG* values, in the current thread."
+  (sigprocmask SIG_BLOCK signals))
+
+(define (unblock-signals signals)
+  "Unblock SIGNALS, a list of SIG* values, in the current thread."
+  (sigprocmask SIG_UNBLOCK signals))
+
 \f
 ;;;
 ;;; Guile shenanigans.
-- 
2.26.2





  reply	other threads:[~2020-05-24 14:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-24 14:27 [bug#41507] [PATCH Shepherd 0/2] Use 'signalfd' on GNU/Linux Ludovic Courtès
2020-05-24 14:36 ` Ludovic Courtès [this message]
2020-05-24 14:37   ` [bug#41507] [PATCH Shepherd 2/2] shepherd: Use 'signalfd' when possible Ludovic Courtès
2020-05-25 12:31     ` Mathieu Othacehe
2020-05-26 22:13       ` bug#41507: " Ludovic Courtès
2020-05-27  5:45         ` [bug#41507] " Jan Nieuwenhuizen
2020-05-27  9:23           ` Ludovic Courtès
2020-05-30 17:44       ` Ludovic Courtès
2020-06-02  7:00         ` Mathieu Othacehe
2020-06-02 21:38           ` Ludovic Courtès
2020-05-24 15:13 ` [bug#41507] [PATCH Shepherd 0/2] Use 'signalfd' on GNU/Linux Jelle Licht
2020-05-25  7:37   ` Ludovic Courtès
2020-05-25  8:02     ` Jelle Licht
2020-05-26 21:32       ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200524143700.6378-1-ludo@gnu.org \
    --to=ludo@gnu.org \
    --cc=41507@debbugs.gnu.org \
    --cc=othacehe@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).