kernel+libc: Implement sigprocmask() and friends
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
This commit is contained in:
parent
015419b8f5
commit
8066e8f1d8
@ -2,6 +2,7 @@
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "sys/Syscall.h"
|
||||
#include "thread/Scheduler.h"
|
||||
#include <bits/signal.h>
|
||||
|
||||
Result<u64> sys_sigreturn(Registers* regs, SyscallArgs)
|
||||
{
|
||||
@ -66,3 +67,33 @@ Result<u64> sys_kill(Registers*, SyscallArgs args)
|
||||
|
||||
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, ¤t->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;
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ struct sigaction
|
||||
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.
|
||||
enum __signals
|
||||
{
|
||||
|
@ -25,6 +25,24 @@ extern "C"
|
||||
/* Send a signal to the current thread. */
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -23,4 +23,57 @@ extern "C"
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
_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(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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user