Skip to content
Snippets Groups Projects
Commit 3a779f1c authored by Nadav Har'El's avatar Nadav Har'El Committed by Pekka Enberg
Browse files

libc: implement sigsetjmp(), siglongjmp()


This patch implements the sigsetjmp()/siglongjmp() functions. Fixes #241.

sigsetjmp() and siglongjmp() are similar to setjmp() and longjmp(), except
that they also save and restore the signals mask. Signals are hardly useful
in OSv, so we don't necessarily need this signal mask feature, but we still
want to implement these functions, if only so that applications which use
them by default could run (see issue #241).

Most of the code in this patch is from Musl 1.0.0, with a few small
modifications - namely, call our sigprocmask() function instead a Linux
syscall. Note I copied the x64 version of sigsetjmp.s only. Musl also
has this file for ARM and other architectures. Interestingly we already
had in our source tree, but didn't use, block.c, and this patch starts
to use it.

Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
parent fb0e0882
No related branches found
No related tags found
No related merge requests found
......@@ -9,27 +9,26 @@ extern "C" {
#include <bits/setjmp.h>
typedef struct __jmp_buf_tag {
__jmp_buf __jb;
unsigned long __fl;
unsigned long __ss[128/sizeof(long)];
} jmp_buf[1];
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
typedef struct __sigjmp_buf {
jmp_buf __jb;
unsigned long __fl;
unsigned long __ss[128/sizeof(long)];
} sigjmp_buf[1];
typedef jmp_buf sigjmp_buf;
int sigsetjmp (sigjmp_buf, int);
_Noreturn void siglongjmp (sigjmp_buf, int);
#endif
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
int _setjmp (jmp_buf);
_Noreturn void _longjmp (jmp_buf, int);
#endif
int setjmp (jmp_buf);
_Noreturn void longjmp (jmp_buf, int);
......
typedef unsigned long jmp_buf[8];
typedef unsigned long __jmp_buf[8];
......@@ -385,6 +385,9 @@ libc += arch/$(arch)/setjmp/longjmp.o
libc += signal/sigrtmax.o
libc += signal/sigrtmin.o
libc += signal/siglongjmp.o
libc += signal/sigsetjmp.o
libc += signal/block.o
libc += stdio/__fclose_ca.o
libc += stdio/__fdopen.o
......
#include "pthread_impl.h"
#include "syscall.h"
#include <signal.h>
......@@ -30,15 +29,15 @@ static const unsigned long app_mask[] = {
void __block_all_sigs(void *set)
{
__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8);
sigprocmask(SIG_BLOCK, (void*)&all_mask, set);
}
void __block_app_sigs(void *set)
{
__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8);
sigprocmask(SIG_BLOCK, (void*)&app_mask, set);
}
void __restore_sigs(void *set)
{
__syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8);
sigprocmask(SIG_SETMASK, set, 0);
}
#include <setjmp.h>
extern void __restore_sigs(void *set);
_Noreturn void siglongjmp(sigjmp_buf buf, int ret)
{
if (buf->__fl) __restore_sigs(buf->__ss);
longjmp(buf, ret);
}
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
.global sigsetjmp
.type sigsetjmp,@function
sigsetjmp:
andl %esi,%esi
movq %rsi,64(%rdi)
jz 1f
pushq %rdi
leaq 72(%rdi),%rdx
xorl %esi,%esi
movl $2,%edi
call sigprocmask
popq %rdi
1: jmp setjmp
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment