mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-12 01:08:00 +00:00
Fix sigsuspend() and sigprocmask() on OpenBSD
Test reliability is now iron clad.
This commit is contained in:
parent
b2cd58a322
commit
a91ba89d85
12 changed files with 148 additions and 13 deletions
34
examples/seq.c
Normal file
34
examples/seq.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#if 0
|
||||||
|
/*─────────────────────────────────────────────────────────────────╗
|
||||||
|
│ To the extent possible under law, Justine Tunney has waived │
|
||||||
|
│ all copyright and related or neighboring rights to this file, │
|
||||||
|
│ as it is written in the following disclaimers: │
|
||||||
|
│ • http://unlicense.org/ │
|
||||||
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────*/
|
||||||
|
#endif
|
||||||
|
#include "libc/fmt/conv.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview Prints sequence of numbers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
long a, b, i;
|
||||||
|
switch (argc) {
|
||||||
|
case 2:
|
||||||
|
a = 1;
|
||||||
|
b = strtol(argv[1], NULL, 0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
a = strtol(argv[1], NULL, 0);
|
||||||
|
b = strtol(argv[2], NULL, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (i = a; i <= b; ++i) {
|
||||||
|
printf("%ld\n", i);
|
||||||
|
}
|
||||||
|
}
|
46
libc/calls/thunks/sigprocmask-sysv.S
Normal file
46
libc/calls/thunks/sigprocmask-sysv.S
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
|
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dce.h"
|
||||||
|
#include "libc/macros.h"
|
||||||
|
|
||||||
|
/ Sets System Five process signal mask w/ standard ABI.
|
||||||
|
sys_sigprocmask:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
#if SupportsOpenbsd()
|
||||||
|
testb IsOpenbsd()
|
||||||
|
jz 4f
|
||||||
|
test %rsi,%rsi
|
||||||
|
jnz 1f
|
||||||
|
mov $1,%edi # SIG_BLOCK on BSDs
|
||||||
|
jmp 2f
|
||||||
|
1: mov (%rsi),%esi # openbsd:byvalue
|
||||||
|
2: call __sys_sigprocmask
|
||||||
|
cmp $-1,%eax
|
||||||
|
je 5f
|
||||||
|
test %rdx,%rdx # original param not a result
|
||||||
|
jz 3f
|
||||||
|
mov %eax,(%rdx) # openbsd:byvalue
|
||||||
|
3: xor %eax,%eax
|
||||||
|
jmp 5f
|
||||||
|
#endif
|
||||||
|
4: call __sys_sigprocmask
|
||||||
|
5: pop %rbp
|
||||||
|
ret
|
||||||
|
.endfn sys_sigprocmask,globl
|
34
libc/calls/thunks/sigsuspend-sysv.S
Normal file
34
libc/calls/thunks/sigsuspend-sysv.S
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
|
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/dce.h"
|
||||||
|
#include "libc/macros.h"
|
||||||
|
|
||||||
|
/ Pauses process w/ standard ABI.
|
||||||
|
sys_sigsuspend:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp,%rbp
|
||||||
|
#if SupportsOpenbsd()
|
||||||
|
testb IsOpenbsd()
|
||||||
|
jz 1f
|
||||||
|
mov (%rdi),%edi # openbsd:byvalue
|
||||||
|
#endif
|
||||||
|
1: call __sys_sigsuspend
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
|
.endfn sys_sigsuspend,globl
|
2
libc/sysv/calls/__sys_sigprocmask.s
Normal file
2
libc/sysv/calls/__sys_sigprocmask.s
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.include "o/libc/sysv/macros.internal.inc"
|
||||||
|
.scall __sys_sigprocmask 0x125030154203000e globl hidden
|
2
libc/sysv/calls/__sys_sigsuspend.s
Normal file
2
libc/sysv/calls/__sys_sigsuspend.s
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.include "o/libc/sysv/macros.internal.inc"
|
||||||
|
.scall __sys_sigsuspend 0x12606f155206f082 globl hidden
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/sysv/macros.internal.inc"
|
|
||||||
.scall sys_sigprocmask 0x125030154203000e globl hidden
|
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/sysv/macros.internal.inc"
|
|
||||||
.scall sys_sigsuspend 0x12606f155206f082 globl hidden
|
|
|
@ -2145,10 +2145,10 @@ syscon misc MCAST_INCLUDE 1 1 1 0 0 0
|
||||||
syscon misc MCAST_EXCLUDE 0 2 2 0 0 0
|
syscon misc MCAST_EXCLUDE 0 2 2 0 0 0
|
||||||
syscon misc MCAST_MSFILTER 48 0 0 0 0 0
|
syscon misc MCAST_MSFILTER 48 0 0 0 0 0
|
||||||
|
|
||||||
syscon misc SIG_SETMASK 2 3 3 3 3 0 # bsd consensus
|
syscon misc SIG_BLOCK 0 1 1 1 1 0 # bsd consensus; faked nt
|
||||||
syscon misc SIG_UNBLOCK 1 2 2 2 2 0 # bsd consensus
|
syscon misc SIG_UNBLOCK 1 2 2 2 2 1 # bsd consensus; faked nt
|
||||||
|
syscon misc SIG_SETMASK 2 3 3 3 3 2 # bsd consensus; faked nt
|
||||||
syscon misc SIG_ATOMIC_MIN -2147483648 -2147483648 -9223372036854775808 -2147483648 -2147483648 0
|
syscon misc SIG_ATOMIC_MIN -2147483648 -2147483648 -9223372036854775808 -2147483648 -2147483648 0
|
||||||
syscon misc SIG_BLOCK 0 1 1 1 1 0 # bsd consensus
|
|
||||||
|
|
||||||
syscon misc AREGTYPE 0 0 0 0 0 0 # consensus
|
syscon misc AREGTYPE 0 0 0 0 0 0 # consensus
|
||||||
syscon misc B0 0 0 0 0 0 0 # consensus
|
syscon misc B0 0 0 0 0 0 0 # consensus
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.include "libc/sysv/consts/syscon.inc"
|
.include "libc/sysv/consts/syscon.inc"
|
||||||
.syscon misc SIG_SETMASK 2 3 3 3 3 0
|
.syscon misc SIG_SETMASK 2 3 3 3 3 2
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.include "libc/sysv/consts/syscon.inc"
|
.include "libc/sysv/consts/syscon.inc"
|
||||||
.syscon misc SIG_UNBLOCK 1 2 2 2 2 0
|
.syscon misc SIG_UNBLOCK 1 2 2 2 2 1
|
||||||
|
|
|
@ -49,7 +49,7 @@ scall sys_msync 0x115100041204101a globl hidden
|
||||||
scall sys_mprotect 0x04a04a04a204a00a globl hidden
|
scall sys_mprotect 0x04a04a04a204a00a globl hidden
|
||||||
scall sys_munmap 0x049049049204900b globl hidden
|
scall sys_munmap 0x049049049204900b globl hidden
|
||||||
scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD
|
scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD
|
||||||
scall sys_sigprocmask 0x125030154203000e globl hidden # a.k.a. rt_sigprocmask
|
scall __sys_sigprocmask 0x125030154203000e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue
|
||||||
scall sys_ioctl 0x0360360362036010 globl hidden
|
scall sys_ioctl 0x0360360362036010 globl hidden
|
||||||
scall __sys_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; netbsd+openbsd:pad
|
scall __sys_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; netbsd+openbsd:pad
|
||||||
scall __sys_pwrite 0x0ae0ae1dc209a012 globl hidden # a.k.a. pwrite64; netbsd+openbsd:pad
|
scall __sys_pwrite 0x0ae0ae1dc209a012 globl hidden # a.k.a. pwrite64; netbsd+openbsd:pad
|
||||||
|
@ -163,7 +163,7 @@ scall sys_setresgid 0xfff11c138ffff077 globl hidden # polyfilled for xnu
|
||||||
scall getresuid 0xfff119168ffff076 globl # semantics aren't well-defined
|
scall getresuid 0xfff119168ffff076 globl # semantics aren't well-defined
|
||||||
scall getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined
|
scall getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined
|
||||||
scall sigpending 0x124034034203407f globl
|
scall sigpending 0x124034034203407f globl
|
||||||
scall sys_sigsuspend 0x12606f155206f082 globl hidden
|
scall __sys_sigsuspend 0x12606f155206f082 globl hidden # openbsd:byvalue
|
||||||
scall sigaltstack 0x1191200352035083 globl
|
scall sigaltstack 0x1191200352035083 globl
|
||||||
scall sys_mknod 0x1c200e00e200e085 globl hidden
|
scall sys_mknod 0x1c200e00e200e085 globl hidden
|
||||||
scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+
|
scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "libc/sysv/consts/fileno.h"
|
#include "libc/sysv/consts/fileno.h"
|
||||||
#include "libc/sysv/consts/inaddr.h"
|
#include "libc/sysv/consts/inaddr.h"
|
||||||
#include "libc/sysv/consts/ipproto.h"
|
#include "libc/sysv/consts/ipproto.h"
|
||||||
|
#include "libc/sysv/consts/itimer.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/consts/poll.h"
|
#include "libc/sysv/consts/poll.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
#include "libc/sysv/consts/sol.h"
|
#include "libc/sysv/consts/sol.h"
|
||||||
#include "libc/sysv/consts/w.h"
|
#include "libc/sysv/consts/w.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/time/time.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
#include "third_party/getopt/getopt.h"
|
#include "third_party/getopt/getopt.h"
|
||||||
#include "tool/build/runit.h"
|
#include "tool/build/runit.h"
|
||||||
|
@ -101,7 +103,7 @@ char *g_exepath;
|
||||||
volatile bool g_interrupted;
|
volatile bool g_interrupted;
|
||||||
struct sockaddr_in g_servaddr;
|
struct sockaddr_in g_servaddr;
|
||||||
unsigned char g_buf[PAGESIZE];
|
unsigned char g_buf[PAGESIZE];
|
||||||
bool g_daemonize, g_sendready;
|
bool g_daemonize, g_sendready, g_alarmed;
|
||||||
int g_timeout, g_devnullfd, g_servfd, g_clifd, g_exefd;
|
int g_timeout, g_devnullfd, g_servfd, g_clifd, g_exefd;
|
||||||
|
|
||||||
void OnInterrupt(int sig) {
|
void OnInterrupt(int sig) {
|
||||||
|
@ -238,6 +240,18 @@ void SendOutputFragmentMessage(int sock, enum RunitCommand kind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnAlarm(int sig) {
|
||||||
|
g_alarmed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDeadline(int seconds, int micros) {
|
||||||
|
g_alarmed = false;
|
||||||
|
LOGIFNEG1(
|
||||||
|
sigaction(SIGALRM, &(struct sigaction){.sa_handler = OnAlarm}, NULL));
|
||||||
|
LOGIFNEG1(setitimer(
|
||||||
|
ITIMER_REAL, &(const struct itimerval){{0, 0}, {seconds, micros}}, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
void HandleClient(void) {
|
void HandleClient(void) {
|
||||||
const size_t kMinMsgSize = 4 + 1 + 4 + 4;
|
const size_t kMinMsgSize = 4 + 1 + 4 + 4;
|
||||||
const size_t kMaxNameSize = 32;
|
const size_t kMaxNameSize = 32;
|
||||||
|
@ -308,6 +322,7 @@ void HandleClient(void) {
|
||||||
|
|
||||||
/* run program, tee'ing stderr to both log and client */
|
/* run program, tee'ing stderr to both log and client */
|
||||||
DEBUGF("spawning %s", exename);
|
DEBUGF("spawning %s", exename);
|
||||||
|
SetDeadline(1, 0);
|
||||||
ignore.sa_flags = 0;
|
ignore.sa_flags = 0;
|
||||||
ignore.sa_handler = SIG_IGN;
|
ignore.sa_handler = SIG_IGN;
|
||||||
LOGIFNEG1(sigemptyset(&ignore.sa_mask));
|
LOGIFNEG1(sigemptyset(&ignore.sa_mask));
|
||||||
|
@ -338,7 +353,13 @@ void HandleClient(void) {
|
||||||
SendOutputFragmentMessage(g_clifd, kRunitStderr, g_buf, got);
|
SendOutputFragmentMessage(g_clifd, kRunitStderr, g_buf, got);
|
||||||
}
|
}
|
||||||
while (waitpid(child, &wstatus, 0) == -1) {
|
while (waitpid(child, &wstatus, 0) == -1) {
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) {
|
||||||
|
if (g_alarmed) {
|
||||||
|
WARNF("killing %s which timed out");
|
||||||
|
LOGIFNEG1(kill(child, SIGKILL));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
FATALF("waitpid failed");
|
FATALF("waitpid failed");
|
||||||
}
|
}
|
||||||
if (WIFEXITED(wstatus)) {
|
if (WIFEXITED(wstatus)) {
|
||||||
|
|
Loading…
Reference in a new issue