mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Some improvements to signals.
- Add sigprocmask() and sigpending(). - Forked children inherit signal dispositions and masks. - Exec clears signal dispositions and masks.
This commit is contained in:
parent
c97a5862ce
commit
6a0a2c9ab4
Notes:
sideshowbarker
2024-07-19 16:11:20 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/6a0a2c9ab43
7 changed files with 60 additions and 4 deletions
|
@ -227,6 +227,11 @@ int Process::sys$gethostname(char* buffer, size_t size)
|
||||||
Process* Process::fork(RegisterDump& regs)
|
Process* Process::fork(RegisterDump& regs)
|
||||||
{
|
{
|
||||||
auto* child = new Process(String(m_name), m_uid, m_gid, m_pid, m_ring, m_cwd.copyRef(), m_executable.copyRef(), m_tty, this);
|
auto* child = new Process(String(m_name), m_uid, m_gid, m_pid, m_ring, m_cwd.copyRef(), m_executable.copyRef(), m_tty, this);
|
||||||
|
if (!child)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
memcpy(child->m_signal_action_data, m_signal_action_data, sizeof(m_signal_action_data));
|
||||||
|
child->m_signal_mask = m_signal_mask;
|
||||||
#ifdef FORK_DEBUG
|
#ifdef FORK_DEBUG
|
||||||
dbgprintf("fork: child=%p\n", child);
|
dbgprintf("fork: child=%p\n", child);
|
||||||
#endif
|
#endif
|
||||||
|
@ -365,6 +370,9 @@ int Process::do_exec(const String& path, Vector<String>&& arguments, Vector<Stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(m_signal_action_data, 0, sizeof(m_signal_action_data));
|
||||||
|
m_signal_mask = 0xffffffff;
|
||||||
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
Scheduler::prepare_to_modify_tss(*this);
|
Scheduler::prepare_to_modify_tss(*this);
|
||||||
|
|
||||||
|
@ -737,13 +745,13 @@ void Process::send_signal(byte signal, Process* sender)
|
||||||
|
|
||||||
bool Process::has_unmasked_pending_signals() const
|
bool Process::has_unmasked_pending_signals() const
|
||||||
{
|
{
|
||||||
return m_pending_signals & ~m_signal_mask;
|
return m_pending_signals & m_signal_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::dispatch_one_pending_signal()
|
void Process::dispatch_one_pending_signal()
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
dword signal_candidates = m_pending_signals & ~m_signal_mask;
|
dword signal_candidates = m_pending_signals & m_signal_mask;
|
||||||
ASSERT(signal_candidates);
|
ASSERT(signal_candidates);
|
||||||
|
|
||||||
byte signal = 0;
|
byte signal = 0;
|
||||||
|
@ -1470,6 +1478,33 @@ Unix::sighandler_t Process::sys$signal(int signum, Unix::sighandler_t handler)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Process::sys$sigprocmask(int how, const Unix::sigset_t* set, Unix::sigset_t* old_set)
|
||||||
|
{
|
||||||
|
VALIDATE_USER_READ(set, sizeof(Unix::sigset_t));
|
||||||
|
if (old_set)
|
||||||
|
VALIDATE_USER_READ(old_set, sizeof(Unix::sigset_t));
|
||||||
|
*old_set = m_signal_mask;
|
||||||
|
switch (how) {
|
||||||
|
case SIG_BLOCK:
|
||||||
|
m_signal_mask &= ~(*set);
|
||||||
|
break;
|
||||||
|
case SIG_UNBLOCK:
|
||||||
|
m_signal_mask |= *set;
|
||||||
|
break;
|
||||||
|
case SIG_SETMASK:
|
||||||
|
m_signal_mask = *set;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Process::sys$sigpending(Unix::sigset_t* set)
|
||||||
|
{
|
||||||
|
VALIDATE_USER_READ(set, sizeof(Unix::sigset_t));
|
||||||
|
*set = m_pending_signals;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Process::sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act)
|
int Process::sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act)
|
||||||
{
|
{
|
||||||
// FIXME: Fail with -EINVAL if attepmting to change action for SIGKILL or SIGSTOP.
|
// FIXME: Fail with -EINVAL if attepmting to change action for SIGKILL or SIGSTOP.
|
||||||
|
|
|
@ -159,6 +159,8 @@ public:
|
||||||
int sys$dup(int oldfd);
|
int sys$dup(int oldfd);
|
||||||
int sys$dup2(int oldfd, int newfd);
|
int sys$dup2(int oldfd, int newfd);
|
||||||
int sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act);
|
int sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act);
|
||||||
|
int sys$sigprocmask(int how, const Unix::sigset_t* set, Unix::sigset_t* old_set);
|
||||||
|
int sys$sigpending(Unix::sigset_t*);
|
||||||
int sys$getgroups(int size, gid_t*);
|
int sys$getgroups(int size, gid_t*);
|
||||||
int sys$setgroups(size_t, const gid_t*);
|
int sys$setgroups(size_t, const gid_t*);
|
||||||
|
|
||||||
|
@ -247,7 +249,7 @@ private:
|
||||||
size_t m_max_open_file_descriptors { 16 };
|
size_t m_max_open_file_descriptors { 16 };
|
||||||
SignalActionData m_signal_action_data[32];
|
SignalActionData m_signal_action_data[32];
|
||||||
dword m_pending_signals { 0 };
|
dword m_pending_signals { 0 };
|
||||||
dword m_signal_mask { 0 };
|
dword m_signal_mask { 0xffffffff };
|
||||||
|
|
||||||
byte m_termination_status { 0 };
|
byte m_termination_status { 0 };
|
||||||
byte m_termination_signal { 0 };
|
byte m_termination_signal { 0 };
|
||||||
|
|
|
@ -159,6 +159,8 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
|
||||||
current->sys$sigreturn();
|
current->sys$sigreturn();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
return 0;
|
return 0;
|
||||||
|
case Syscall::SC_sigprocmask:
|
||||||
|
return current->sys$sigprocmask((int)arg1, (const Unix::sigset_t*)arg2, (Unix::sigset_t*)arg3);
|
||||||
default:
|
default:
|
||||||
kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
|
kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
__ENUMERATE_SYSCALL(getgroups) \
|
__ENUMERATE_SYSCALL(getgroups) \
|
||||||
__ENUMERATE_SYSCALL(setgroups) \
|
__ENUMERATE_SYSCALL(setgroups) \
|
||||||
__ENUMERATE_SYSCALL(sigreturn) \
|
__ENUMERATE_SYSCALL(sigreturn) \
|
||||||
|
__ENUMERATE_SYSCALL(sigprocmask) \
|
||||||
|
__ENUMERATE_SYSCALL(sigpending) \
|
||||||
|
|
||||||
|
|
||||||
#define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function))
|
#define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function))
|
||||||
|
|
|
@ -71,6 +71,18 @@ int sigismember(const sigset_t* set, int sig)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
|
||||||
|
{
|
||||||
|
int rc = Syscall::invoke(Syscall::SC_sigprocmask, (dword)how, (dword)set, (dword)old_set);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sigpending(sigset_t* set)
|
||||||
|
{
|
||||||
|
int rc = Syscall::invoke(Syscall::SC_sigpending, (dword)set);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
|
}
|
||||||
|
|
||||||
const char* sys_siglist[NSIG] = {
|
const char* sys_siglist[NSIG] = {
|
||||||
#undef __SIGNAL
|
#undef __SIGNAL
|
||||||
#define __SIGNAL(a, b) b,
|
#define __SIGNAL(a, b) b,
|
||||||
|
@ -78,5 +90,4 @@ const char* sys_siglist[NSIG] = {
|
||||||
#undef __SIGNAL
|
#undef __SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ int sigfillset(sigset_t*);
|
||||||
int sigaddset(sigset_t*, int sig);
|
int sigaddset(sigset_t*, int sig);
|
||||||
int sigdelset(sigset_t*, int sig);
|
int sigdelset(sigset_t*, int sig);
|
||||||
int sigismember(const sigset_t*, int sig);
|
int sigismember(const sigset_t*, int sig);
|
||||||
|
int sigprocmask(int how, const sigset_t* set, sigset_t* old_set);
|
||||||
|
int sigpending(sigset_t*);
|
||||||
|
|
||||||
#define NSIG 32
|
#define NSIG 32
|
||||||
extern const char* sys_siglist[NSIG];
|
extern const char* sys_siglist[NSIG];
|
||||||
|
|
|
@ -17,5 +17,7 @@
|
||||||
#undef __P
|
#undef __P
|
||||||
#define __P(a) a
|
#define __P(a) a
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" int main(int, char**);
|
extern "C" int main(int, char**);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue