kernel+libc: Implement sigprocmask() and friends
Some checks failed
continuous-integration/drone/pr Build is failing

This commit is contained in:
apio 2023-07-10 21:01:59 +02:00
parent 015419b8f5
commit 8066e8f1d8
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 108 additions and 1 deletions

View File

@ -2,6 +2,7 @@
#include "memory/MemoryManager.h" #include "memory/MemoryManager.h"
#include "sys/Syscall.h" #include "sys/Syscall.h"
#include "thread/Scheduler.h" #include "thread/Scheduler.h"
#include <bits/signal.h>
Result<u64> sys_sigreturn(Registers* regs, SyscallArgs) Result<u64> sys_sigreturn(Registers* regs, SyscallArgs)
{ {
@ -66,3 +67,33 @@ Result<u64> sys_kill(Registers*, SyscallArgs args)
return 0; return 0;
} }
Result<u64> sys_sigprocmask(Registers*, SyscallArgs args)
{
auto* current = Scheduler::current();
int how = (int)args[0];
const sigset_t* set = (const sigset_t*)args[1];
sigset_t* oldset = (sigset_t*)args[2];
if (oldset)
{
if (!MemoryManager::copy_to_user_typed(oldset, &current->signal_mask)) return err(EFAULT);
}
if (set)
{
sigset_t kset;
if (!MemoryManager::copy_from_user_typed(set, &kset)) return err(EFAULT);
switch (how)
{
case SIG_BLOCK: current->signal_mask |= kset;
case SIG_UNBLOCK: current->signal_mask &= ~kset;
case SIG_SETMASK: current->signal_mask = kset;
default: return err(EINVAL);
}
}
return 0;
}

View File

@ -18,6 +18,11 @@ struct sigaction
void* __sa_sigreturn = nullptr; void* __sa_sigreturn = nullptr;
}; };
// Constants for the 'how' parameter in sigprocmask().
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
// The signals with explicit numbers have portable signal numbers. // The signals with explicit numbers have portable signal numbers.
enum __signals enum __signals
{ {

View File

@ -25,6 +25,24 @@ extern "C"
/* Send a signal to the current thread. */ /* Send a signal to the current thread. */
int raise(int signo); int raise(int signo);
/* Modify the current thread's signal mask. */
int sigprocmask(int how, const sigset_t* set, sigset_t* oldset);
/* Clear all signals from set. */
int sigemptyset(sigset_t* set);
/* Add all signals to set. */
int sigfillset(sigset_t* set);
/* Add a specific signal to set. */
int sigaddset(sigset_t* set, int signo);
/* Remove a specific signal from set. */
int sigdelset(sigset_t* set, int signo);
/* Check if a signal is in set.*/
int sigismember(const sigset_t* set, int signo);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,4 +23,57 @@ extern "C"
{ {
return kill(getpid(), signo); return kill(getpid(), signo);
} }
int sigprocmask(int how, const sigset_t* set, sigset_t* oldset)
{
long rc = syscall(SYS_sigprocmask, how, set, oldset);
__errno_return(rc, int);
}
int sigemptyset(sigset_t* set)
{
*set = 0;
return 0;
}
int sigfillset(sigset_t* set)
{
*set = 0xffffffff;
return 0;
}
int sigaddset(sigset_t* set, int signo)
{
if (signo <= 0 || signo > NSIG)
{
errno = EINVAL;
return -1;
}
*set |= (1 << (signo - 1));
return 0;
}
int sigdelset(sigset_t* set, int signo)
{
if (signo <= 0 || signo > NSIG)
{
errno = EINVAL;
return -1;
}
*set &= ~(1 << (signo - 1));
return 0;
}
int sigismember(const sigset_t* set, int signo)
{
if (signo <= 0 || signo > NSIG)
{
errno = EINVAL;
return -1;
}
return (*set & (1 << (signo - 1))) > 0;
}
} }

View File

@ -6,7 +6,7 @@
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \ _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \ _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \ _e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask)
enum Syscalls enum Syscalls
{ {