public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Adhemerval Zanella <azanella@sourceware.org>
To: glibc-cvs@sourceware.org
Subject: [glibc] linux: Use pthread_sigmask on sigprocmask
Date: Tue, 21 Apr 2020 18:12:17 +0000 (GMT)	[thread overview]
Message-ID: <20200421181217.11A39384B0C1@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2f6fa80147f0cf74c0d411a0e07c5655deb436b3

commit 2f6fa80147f0cf74c0d411a0e07c5655deb436b3
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Mar 11 15:21:59 2020 -0300

    linux: Use pthread_sigmask on sigprocmask
    
    With pthread_sigmask on libc.so, it allows implement sigprocmask
    on top of pthread_sigmask.
    
    Checked on x86_64-linux-gnu.

Diff:
---
 nptl/pthreadP.h                            |  2 ++
 nptl/pthread_sigmask.c                     |  1 +
 sysdeps/unix/sysv/linux/sigprocmask.c      | 20 +++++---------------
 sysdeps/unix/sysv/linux/test-errno-linux.c | 19 +++++++++++++++++++
 4 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 06fb0d74c5..c4e72f57a9 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -482,6 +482,8 @@ extern void __pthread_testcancel (void);
 extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
 				   const struct timespec *, bool)
   attribute_hidden;
+extern int __pthread_sigmask (int, const sigset_t *, sigset_t *);
+libc_hidden_proto (__pthread_sigmask);
 
 
 #if IS_IN (libpthread)
diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
index 035104453f..c6c6e83c08 100644
--- a/nptl/pthread_sigmask.c
+++ b/nptl/pthread_sigmask.c
@@ -46,6 +46,7 @@ __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
 	  ? INTERNAL_SYSCALL_ERRNO (result)
 	  : 0);
 }
+libc_hidden_def (__pthread_sigmask)
 
 versioned_symbol (libc, __pthread_sigmask, pthread_sigmask, GLIBC_2_32);
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
diff --git a/sysdeps/unix/sysv/linux/sigprocmask.c b/sysdeps/unix/sysv/linux/sigprocmask.c
index eb9e4d5e83..59bf6fd660 100644
--- a/sysdeps/unix/sysv/linux/sigprocmask.c
+++ b/sysdeps/unix/sysv/linux/sigprocmask.c
@@ -22,21 +22,11 @@
 int
 __sigprocmask (int how, const sigset_t *set, sigset_t *oset)
 {
-  sigset_t local_newmask;
-
-  /* The only thing we have to make sure here is that SIGCANCEL and
-     SIGSETXID are not blocked.  */
-  if (set != NULL
-      && __glibc_unlikely (__sigismember (set, SIGCANCEL)
-	|| __glibc_unlikely (__sigismember (set, SIGSETXID))))
-    {
-      local_newmask = *set;
-      __sigdelset (&local_newmask, SIGCANCEL);
-      __sigdelset (&local_newmask, SIGSETXID);
-      set = &local_newmask;
-    }
-
-  return INLINE_SYSCALL_CALL (rt_sigprocmask, how, set, oset, _NSIG / 8);
+  int result = __pthread_sigmask (how, set, oset);
+  if (result == 0)
+    return 0;
+  __set_errno (result);
+  return -1;
 }
 libc_hidden_def (__sigprocmask)
 weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/test-errno-linux.c b/sysdeps/unix/sysv/linux/test-errno-linux.c
index b748f8f2a0..838ccf026f 100644
--- a/sysdeps/unix/sysv/linux/test-errno-linux.c
+++ b/sysdeps/unix/sysv/linux/test-errno-linux.c
@@ -120,6 +120,17 @@ check_error_in_list (int code, int *codes, size_t count)
 #define test_wrp2(experr, syscall, ...)		\
   test_wrp_rv(int, "%d", LIST_FORWARD (experr), syscall, __VA_ARGS__)
 
+static int
+invalid_sigprocmask_how (void)
+{
+  int n = 0;
+  const int how[] = { SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK };
+  for (int i = 0; i < array_length (how); i++)
+    if (how[i] == n)
+      n++;
+  return n;
+}
+
 static int
 do_test (void)
 {
@@ -133,10 +144,13 @@ do_test (void)
   struct sched_param sch_param;
   struct timespec ts;
   struct timeval tv;
+  sigset_t sigs;
   unsigned char vec[16];
   ss.ss_flags = ~SS_DISABLE;
   ts.tv_sec = -1;
 
+  sigemptyset (&sigs);
+
   int fails = 0;
   fails |= test_wrp (EINVAL, epoll_create, -1);
   fails |= test_wrp (EINVAL, epoll_create1, EPOLL_CLOEXEC + 1);
@@ -175,6 +189,11 @@ do_test (void)
   fails |= test_wrp (EBADF, sendfile, -1, -1, &off, 0);
   fails |= test_wrp (EINVAL, sigaltstack, &ss, NULL);
   fails |= test_wrp (ECHILD, wait4, -1, &status, 0, NULL);
+  /* Austin Group issue #1132 states EINVAL should be returned for invalid
+     how argument iff the new set mask is non-null.  And Linux follows the
+     standard on this regard.  */
+  fails |= test_wrp (EINVAL, sigprocmask, invalid_sigprocmask_how (), &sigs,
+		     NULL);
 
   return fails;
 }


                 reply	other threads:[~2020-04-21 18:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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

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

  git send-email \
    --in-reply-to=20200421181217.11A39384B0C1@sourceware.org \
    --to=azanella@sourceware.org \
    --cc=glibc-cvs@sourceware.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.
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).