Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Staging:C
glibc
setcontext-signal-mask.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File setcontext-signal-mask.patch of Package glibc
2015-03-12 Stefan Liebler <stli@linux.vnet.ibm.com> [BZ #18080] * sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S (__setcontext): Use SIG_SETMASK instead of SIG_BLOCK. * sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S (__setcontext): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S (__swapcontext): Use SIG_SETMASK instead of SIG_BLOCK. Call rt_sigprocmask syscall one time to set new signal mask and retrieve the current signal mask instead of two calls. * sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S (__swapcontext): Likewise. * stdlib/Makefile (tests): Add new testcase tst-setcontext2. * stdlib/tst-setcontext2.c: New file. Index: glibc-2.19/stdlib/Makefile =================================================================== --- glibc-2.19.orig/stdlib/Makefile +++ glibc-2.19/stdlib/Makefile @@ -64,11 +64,11 @@ test-srcs := tst-fmtmsg tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ test-canon test-canon2 tst-strtoll tst-environ \ tst-xpg-basename tst-random tst-random2 tst-bsearch \ - tst-limits tst-rand48 bug-strtod tst-setcontext \ - test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ - tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ - tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ - tst-makecontext2 tst-strtod6 tst-unsetenv1 \ + tst-limits tst-rand48 bug-strtod tst-setcontext \ + tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \ + bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 \ + tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5 \ + tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ tst-makecontext3 bug-getcontext bug-fmtmsg1 \ tst-secure-getenv tst-strtod-overflow tst-strtod-round \ tst-tininess tst-strtod-underflow tst-tls-atexit Index: glibc-2.19/stdlib/tst-setcontext2.c =================================================================== --- /dev/null +++ glibc-2.19/stdlib/tst-setcontext2.c @@ -0,0 +1,230 @@ +/* Testcase checks, if setcontext(), swapcontext() restores signal-mask + and if pending signals are delivered after those calls. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <signal.h> +#include <ucontext.h> +#include <unistd.h> + +volatile int global; +volatile sig_atomic_t handlerCalled; + +static void +check (const char *funcName) +{ + sigset_t set; + + /* check if SIGUSR2 is unblocked after setcontext-call. */ + sigprocmask (SIG_BLOCK, NULL, &set); + + if (sigismember (&set, SIGUSR2) != 0) + { + printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName); + exit (1); + } + + if (sigismember (&set, SIGUSR1) != 1) + { + printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName); + exit (1); + } +} + +static void +signalmask (int how, int signum) +{ + sigset_t set; + sigemptyset (&set); + sigaddset (&set, signum); + if (sigprocmask (how, &set, NULL) != 0) + { + printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum); + exit (1); + } +} + +static void +signalpending (int signum, const char *msg) +{ + sigset_t set; + sigemptyset (&set); + if (sigpending (&set) != 0) + { + printf ("FAIL: sigpending: %m\n"); + exit (1); + } + if (sigismember (&set, SIGUSR2) != 1) + { + printf ("FAIL: Signal %d is not pending %s\n", signum, msg); + exit (1); + } +} + +static void +handler (int __attribute__ ((unused)) signum) +{ + handlerCalled ++; +} + +static int +do_test (void) +{ + ucontext_t ctx, oldctx; + struct sigaction action; + pid_t pid; + + pid = getpid (); + + /* unblock SIGUSR2 */ + signalmask (SIG_UNBLOCK, SIGUSR2); + + /* block SIGUSR1 */ + signalmask (SIG_BLOCK, SIGUSR1); + + /* register handler for SIGUSR2 */ + action.sa_flags = 0; + action.sa_handler = handler; + sigemptyset (&action.sa_mask); + sigaction (SIGUSR2, &action, NULL); + + if (getcontext (&ctx) != 0) + { + printf ("FAIL: getcontext: %m\n"); + exit (1); + } + + global++; + + if (global == 1) + { + puts ("after getcontext"); + + /* block SIGUSR2 */ + signalmask (SIG_BLOCK, SIGUSR2); + + /* send SIGUSR2 to me */ + handlerCalled = 0; + kill (pid, SIGUSR2); + + /* was SIGUSR2 handler called? */ + if (handlerCalled != 0) + { + puts ("FAIL: signal handler was called, but signal was blocked."); + exit (1); + } + + /* is SIGUSR2 pending? */ + signalpending (SIGUSR2, "before setcontext"); + + /* SIGUSR2 will be unblocked by setcontext-call. */ + if (setcontext (&ctx) != 0) + { + printf ("FAIL: setcontext: %m\n"); + exit (1); + } + } + else if (global == 2) + { + puts ("after setcontext"); + + /* check SIGUSR1/2 */ + check ("setcontext"); + + /* was SIGUSR2 handler called? */ + if (handlerCalled != 1) + { + puts ("FAIL: signal handler was not called after setcontext."); + exit (1); + } + + /* block SIGUSR2 */ + signalmask (SIG_BLOCK, SIGUSR2); + + /* send SIGUSR2 to me */ + handlerCalled = 0; + kill (pid, SIGUSR2); + + /* was SIGUSR2 handler called? */ + if (handlerCalled != 0) + { + puts ("FAIL: signal handler was called, but signal was blocked."); + exit (1); + } + + /* is SIGUSR2 pending? */ + signalpending (SIGUSR2, "before swapcontext"); + + if (swapcontext (&oldctx, &ctx) != 0) + { + printf ("FAIL: swapcontext: %m\n"); + exit (1); + } + + puts ("after returned from swapcontext"); + + if (global != 3) + { + puts ("FAIL: returned from swapcontext without ctx-context called."); + exit (1); + } + + puts ("test succeeded"); + return 0; + } + else if ( global != 3 ) + { + puts ("FAIL: 'global' not incremented three times"); + exit (1); + } + + puts ("after swapcontext"); + /* check SIGUSR1/2 */ + check ("swapcontext"); + + /* was SIGUSR2 handler called? */ + if (handlerCalled != 1) + { + puts ("FAIL: signal handler was not called after swapcontext."); + exit (1); + } + + /* check sigmask in old context of swapcontext-call */ + if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1) + { + puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask."); + exit (1); + } + + if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1) + { + puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks."); + exit (1); + } + + /* change to old context, which was gathered by swapcontext() call. */ + setcontext (&oldctx); + + puts ("FAIL: returned from setcontext (&oldctx)"); + exit (1); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S =================================================================== --- glibc-2.19.orig/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S +++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S @@ -34,7 +34,7 @@ ENTRY(__setcontext) lr %r1,%r2 /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */ - la %r2,SIG_BLOCK + la %r2,SIG_SETMASK la %r3,SC_MASK(%r1) slr %r4,%r4 lhi %r5,_NSIG8 Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S =================================================================== --- glibc-2.19.orig/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S @@ -24,7 +24,7 @@ /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) Saves the machine context in oucp such that when it is activated, - it appears as if __swapcontextt() returned again, restores the + it appears as if __swapcontext() returned again, restores the machine context in ucp and thereby resumes execution in that context. @@ -39,13 +39,6 @@ ENTRY(__swapcontext) lr %r1,%r2 lr %r0,%r3 - /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ - la %r2,SIG_BLOCK - slr %r3,%r3 - la %r4,SC_MASK(%r1) - lhi %r5,_NSIG8 - svc SYS_ify(rt_sigprocmask) - /* Store fpu context. */ stfpc SC_FPC(%r1) std %f0,SC_FPRS(%r1) @@ -74,11 +67,12 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stm %r0,%r15,SC_GPRS(%r1) - /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ - la %r2,SIG_BLOCK + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, + sigsetsize). */ + la %r2,SIG_SETMASK lr %r5,%r0 la %r3,SC_MASK(%r5) - slr %r4,%r4 + la %r4,SC_MASK(%r1) lhi %r5,_NSIG8 svc SYS_ify(rt_sigprocmask) Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S =================================================================== --- glibc-2.19.orig/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S +++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S @@ -34,7 +34,7 @@ ENTRY(__setcontext) lgr %r1,%r2 /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ - la %r2,SIG_BLOCK + la %r2,SIG_SETMASK la %r3,SC_MASK(%r1) slgr %r4,%r4 lghi %r5,_NSIG8 Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S =================================================================== --- glibc-2.19.orig/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S @@ -24,7 +24,7 @@ /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) Saves the machine context in oucp such that when it is activated, - it appears as if __swapcontextt() returned again, restores the + it appears as if __swapcontext() returned again, restores the machine context in ucp and thereby resumes execution in that context. @@ -39,13 +39,6 @@ ENTRY(__swapcontext) lgr %r1,%r2 lgr %r0,%r3 - /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ - la %r2,SIG_BLOCK - slgr %r3,%r3 - la %r4,SC_MASK(%r1) - lghi %r5,_NSIG8 - svc SYS_ify(rt_sigprocmask) - /* Store fpu context. */ stfpc SC_FPC(%r1) std %f0,SC_FPRS(%r1) @@ -74,12 +67,13 @@ ENTRY(__swapcontext) /* Store general purpose registers. */ stmg %r0,%r15,SC_GPRS(%r1) - /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */ - la %r2,SIG_BLOCK + /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, + sigsetsize). */ + la %r2,SIG_SETMASK lgr %r5,%r0 la %r3,SC_MASK(%r5) + la %r4,SC_MASK(%r1) lghi %r5,_NSIG8 - slgr %r4,%r4 svc SYS_ify(rt_sigprocmask) /* Load fpu context. */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor