1#!/bin/sh 2 3# 4# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 5# 6# Copyright (c) 2020 Konstantin Belousov 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27# SUCH DAMAGE. 28# 29 30# sigfastblock test scenario by Konstantin Belousov <kib@FreeBSD.org> 31 32. ../default.cfg 33[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 34[ `uname -p` != "amd64" ] && exit 0 35 36cat > /tmp/sigfastblock.c <<EOF 37/* $Id: sigfastblock1.c,v 1.4 2020/02/16 19:53:14 kostik Exp kostik $ */ 38 39#include <sys/types.h> 40#include <sys/signalvar.h> 41#include <sys/sysctl.h> 42#include <err.h> 43#include <errno.h> 44#include <signal.h> 45#include <stdio.h> 46#include <string.h> 47#include <time.h> 48#include <unistd.h> 49 50#ifdef __ILP32 51#define BITNESS "32" 52#else 53#define BITNESS "64" 54#endif 55 56int block; 57 58static void 59sighandler(int signo, siginfo_t *si, void *ucp __unused) 60{ 61 printf("block %#x sig %d si_code %d si_pid %d\n", 62 block, signo, si->si_code, si->si_pid); 63} 64 65int 66main(void) 67{ 68 struct timespec rqts; 69 struct sigaction sa; 70 int error, val; 71 size_t valsize; 72 pid_t child; 73 74 valsize = sizeof(val); 75 error = sysctlbyname("kern.elf" BITNESS ".sigfastblock", &val, 76 &valsize, NULL, 0); 77 if (error != 0) 78 err(1, "sigfastblock sysctl"); 79 if (val != 0) 80 errx(1, "sigfastblock use in rtld must be turned off"); 81 82 memset(&sa, 0, sizeof(sa)); 83 sa.sa_sigaction = sighandler; 84 sa.sa_flags = SA_SIGINFO; 85 error = sigaction(SIGUSR1, &sa, NULL); 86 87 child = fork(); 88 if (child == -1) 89 err(1, "fork"); 90 if (child == 0) { 91 sleep(2); 92 kill(getppid(), SIGUSR1); 93 _exit(0); 94 } 95 96 error = __sys_sigfastblock(SIGFASTBLOCK_SETPTR, &block); 97 if (error != 0) 98 err(1, "sigfastblock setptr"); 99 100 printf("Registered block at %p\n", &block); 101 block = SIGFASTBLOCK_INC; 102 rqts.tv_sec = 4; 103 rqts.tv_nsec = 0; 104 errno = 0; 105 error = nanosleep(&rqts, 0); 106 printf("nanosleep 1 returned %d, errno %d, block %#x\n", 107 error, errno, block); 108 raise(SIGUSR1); 109 errno = 0; 110 error = nanosleep(&rqts, 0); 111 printf("nanosleep 2 returned %d, errno %d, block %#x\n", 112 error, errno, block); 113 114 errno = 0; 115 block -= SIGFASTBLOCK_INC; 116 error = __sys_sigfastblock(SIGFASTBLOCK_UNBLOCK, NULL); 117 printf("unblock returned %d, errno %d, block %#x\n", 118 error, errno, block); 119} 120 121EOF 122mycc -o /tmp/sigfastblock -Wall -Wextra -O2 -g /tmp/sigfastblock.c || exit 1 123 124echo "Expect: 125Registered block at 0x2030c0 126nanosleep 1 returned -1, errno 4, block 0x11 127nanosleep 2 returned 0, errno 0, block 0x11 128unblock returned 0, errno 0, block 0 129block 0 sig 30 si_code 65543 si_pid 1151 130block 0 sig 30 si_code 65537 si_pid 1152 131" 132 133cd /tmp 134sysctl kern.elf64.sigfastblock=0 135sysctl kern.elf32.sigfastblock=0 136./sigfastblock; s=$? 137sysctl kern.elf64.sigfastblock=1 138sysctl kern.elf32.sigfastblock=1 139 140rm -f /tmp/sigfastblock.c /tmp/sigfastblock 141exit $s 142