mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +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_MSFILTER 48 0 0 0 0 0
|
||||
|
||||
syscon misc SIG_SETMASK 2 3 3 3 3 0 # bsd consensus
|
||||
syscon misc SIG_UNBLOCK 1 2 2 2 2 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 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_BLOCK 0 1 1 1 1 0 # bsd consensus
|
||||
|
||||
syscon misc AREGTYPE 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"
|
||||
.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"
|
||||
.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_munmap 0x049049049204900b globl hidden
|
||||
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_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; 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 getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined
|
||||
scall sigpending 0x124034034203407f globl
|
||||
scall sys_sigsuspend 0x12606f155206f082 globl hidden
|
||||
scall __sys_sigsuspend 0x12606f155206f082 globl hidden # openbsd:byvalue
|
||||
scall sigaltstack 0x1191200352035083 globl
|
||||
scall sys_mknod 0x1c200e00e200e085 globl hidden
|
||||
scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
@ -56,6 +57,7 @@
|
|||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/consts/w.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "tool/build/runit.h"
|
||||
|
@ -101,7 +103,7 @@ char *g_exepath;
|
|||
volatile bool g_interrupted;
|
||||
struct sockaddr_in g_servaddr;
|
||||
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;
|
||||
|
||||
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) {
|
||||
const size_t kMinMsgSize = 4 + 1 + 4 + 4;
|
||||
const size_t kMaxNameSize = 32;
|
||||
|
@ -308,6 +322,7 @@ void HandleClient(void) {
|
|||
|
||||
/* run program, tee'ing stderr to both log and client */
|
||||
DEBUGF("spawning %s", exename);
|
||||
SetDeadline(1, 0);
|
||||
ignore.sa_flags = 0;
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
LOGIFNEG1(sigemptyset(&ignore.sa_mask));
|
||||
|
@ -338,7 +353,13 @@ void HandleClient(void) {
|
|||
SendOutputFragmentMessage(g_clifd, kRunitStderr, g_buf, got);
|
||||
}
|
||||
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");
|
||||
}
|
||||
if (WIFEXITED(wstatus)) {
|
||||
|
|
Loading…
Reference in a new issue