diff --git a/kernel/src/net/UnixSocket.cpp b/kernel/src/net/UnixSocket.cpp index 7ba013a6..d44fc1fe 100644 --- a/kernel/src/net/UnixSocket.cpp +++ b/kernel/src/net/UnixSocket.cpp @@ -143,9 +143,12 @@ Result UnixSocket::connect(Registers* regs, int flags, struct sockaddr* ad m_blocked_thread = nullptr; if (current->interrupted) { - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); - continue; + if (current->will_ignore_pending_signal()) + { + current->process_pending_signals(regs); + continue; + } + return err(EINTR); } break; } @@ -182,9 +185,12 @@ Result> UnixSocket::accept(Registers* regs, int f m_blocked_thread = nullptr; if (current->interrupted) { - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); - continue; + if (current->will_ignore_pending_signal()) + { + current->process_pending_signals(regs); + continue; + } + return err(EINTR); } } diff --git a/kernel/src/sys/file.cpp b/kernel/src/sys/file.cpp index 85fa7691..b47dd6b7 100644 --- a/kernel/src/sys/file.cpp +++ b/kernel/src/sys/file.cpp @@ -35,8 +35,12 @@ Result sys_read(Registers* regs, SyscallArgs args) if (current->interrupted) { kdbgln("signal: read interrupted by signal"); - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); + if (current->will_ignore_pending_signal()) + { + current->process_pending_signals(regs); + continue; + } + return err(EINTR); } } diff --git a/kernel/src/sys/poll.cpp b/kernel/src/sys/poll.cpp index 42d99fff..973d2f1a 100644 --- a/kernel/src/sys/poll.cpp +++ b/kernel/src/sys/poll.cpp @@ -5,7 +5,7 @@ #include "thread/Scheduler.h" #include -Result sys_poll(Registers* regs, SyscallArgs args) +Result sys_poll(Registers*, SyscallArgs args) { struct pollfd* fds = (struct pollfd*)args[0]; nfds_t nfds = (nfds_t)args[1]; @@ -58,8 +58,6 @@ Result sys_poll(Registers* regs, SyscallArgs args) { guard.deactivate(); free_impl(kfds); - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); return err(EINTR); } continue; diff --git a/kernel/src/sys/waitpid.cpp b/kernel/src/sys/waitpid.cpp index b52b9f91..88cbc996 100644 --- a/kernel/src/sys/waitpid.cpp +++ b/kernel/src/sys/waitpid.cpp @@ -27,9 +27,12 @@ Result sys_waitpid(Registers* regs, SyscallArgs args) if (current->interrupted) { kdbgln("signal: waitpid interrupted by signal"); - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); - goto wait_for_child; + if (current->will_ignore_pending_signal()) + { + current->process_pending_signals(regs); + goto wait_for_child; + } + return err(EINTR); } check(thread->state == ThreadState::Exited); @@ -48,9 +51,12 @@ Result sys_waitpid(Registers* regs, SyscallArgs args) if (current->interrupted) { kdbgln("signal: waitpid interrupted by signal"); - if (current->will_invoke_signal_handler()) return err(EINTR); - current->process_pending_signals(regs); - goto wait_for_any_child; + if (current->will_ignore_pending_signal()) + { + current->process_pending_signals(regs); + goto wait_for_any_child; + } + return err(EINTR); } check(current->child_being_waited_for.value_or(-1) != -1); diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index 5128b35e..27c35dcd 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -186,18 +186,19 @@ void Thread::process_pending_signals(Registers* current_regs) } } -bool Thread::will_invoke_signal_handler() +bool Thread::will_ignore_pending_signal() { for (int i = 0; i < NSIG; i++) { if (pending_signals & (1 << i)) { int signo = i + 1; - if (signo != SIGKILL && signo != SIGSTOP && signal_mask & (1 << i)) continue; - auto handler = signal_handlers[i]; - if (handler.sa_handler == SIG_IGN || handler.sa_handler == SIG_DFL) return false; if (signo == SIGKILL || signo == SIGSTOP) return false; - return true; + if (signal_mask & (1 << i)) continue; + auto handler = signal_handlers[i]; + if (handler.sa_handler == SIG_IGN) return true; + if (handler.sa_handler == SIG_DFL && default_actions[i] == DefaultSignalAction::Ignore) return true; + return false; } } return false; diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index d73e498e..90edd7ea 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -159,7 +159,7 @@ struct Thread : public LinkedListNode void process_pending_signals(Registers* current_regs); - bool will_invoke_signal_handler(); + bool will_ignore_pending_signal(); bool deliver_signal(int signo, Registers* current_regs); void sigreturn(Registers* current_regs);