Skip to content

Commit

Permalink
Merge pull request #1142 from Sonicadvance1/implement_base_signalfd
Browse files Browse the repository at this point in the history
Linux: Implements a base implementation of signalfd{4,}
  • Loading branch information
Stefanos Kornilios Mitsis Poiitidis authored Jul 2, 2021
2 parents 336eb9a + b923a82 commit 2db44cf
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 9 deletions.
29 changes: 29 additions & 0 deletions Source/Tests/LinuxSyscalls/SignalDelegator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ desc: Handles host -> host and host -> guest signal routing, emulates procmask &
#include <bits/types/stack_t.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/signalfd.h>
#include <unistd.h>

namespace FEX::HLE {
Expand Down Expand Up @@ -688,4 +689,32 @@ namespace FEX::HLE {

return Result == -1 ? -errno : Result;
}

uint64_t SignalDelegator::GuestSignalFD(int fd, const uint64_t *set, size_t sigsetsize, int flags) {
if (sigsetsize > sizeof(uint64_t)) {
return -EINVAL;
}

sigset_t HostSet{};
sigemptyset(&HostSet);

for (size_t i = 0; i < MAX_SIGNALS; ++i) {
if (HostHandlers[i + 1].Required) {
// For now skip our internal signals
continue;
}

if (ThreadData.CurrentSignalMask.Val & (1ULL << i)) {
sigaddset(&HostSet, i + 1);
}
}

// XXX: This is a barebones implementation just to get applications that listen for SIGCHLD to work
// In the future we need our own listern thread that forwards the result
// Thread is necessary to prevent deadlocks for a thread that has signaled on the same thread listening to the FD and blocking is enabled
uint64_t Result = signalfd(fd, &HostSet, flags);

return Result == -1 ? -errno : Result;
}

}
1 change: 1 addition & 0 deletions Source/Tests/LinuxSyscalls/SignalDelegator.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ namespace FEX::HLE {
uint64_t GuestSigPending(uint64_t *set, size_t sigsetsize);
uint64_t GuestSigSuspend(uint64_t *set, size_t sigsetsize);
uint64_t GuestSigTimedWait(uint64_t *set, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize);
uint64_t GuestSignalFD(int fd, const uint64_t *set, size_t sigsetsize , int flags);

// Called from the thunk handler to handle the signal
void HandleSignal(int Signal, void *Info, void *UContext);
Expand Down
8 changes: 8 additions & 0 deletions Source/Tests/LinuxSyscalls/Syscalls/Signals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(signalfd, [](FEXCore::Core::CpuStateFrame *Frame, int fd, const uint64_t *mask, size_t sigsetsize) -> uint64_t {
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSignalFD(fd, mask, sigsetsize, 0);
});

REGISTER_SYSCALL_IMPL(signalfd4, [](FEXCore::Core::CpuStateFrame *Frame, int fd, const uint64_t *mask, size_t sigsetsize, int flags) -> uint64_t {
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSignalFD(fd, mask, sigsetsize, flags);
});

if (Handler->IsHostKernelVersionAtLeast(5, 1, 0)) {
REGISTER_SYSCALL_IMPL(pidfd_send_signal, [](FEXCore::Core::CpuStateFrame *Frame, int pidfd, int sig, siginfo_t *info, unsigned int flags) -> uint64_t {
uint64_t Result = ::syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
Expand Down
8 changes: 0 additions & 8 deletions Source/Tests/LinuxSyscalls/Syscalls/Stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ namespace FEX::HLE {
SYSCALL_STUB(restart_syscall);
});

REGISTER_SYSCALL_IMPL(signalfd, [](FEXCore::Core::CpuStateFrame *Frame, int fd, const sigset_t *mask, size_t sizemask) -> uint64_t {
SYSCALL_STUB(signalfd);
});

REGISTER_SYSCALL_IMPL(signalfd4, [](FEXCore::Core::CpuStateFrame *Frame, int fd, const sigset_t *mask, size_t sizemask, int flags) -> uint64_t {
SYSCALL_STUB(signalfd4);
});

REGISTER_SYSCALL_IMPL(rt_tgsigqueueinfo, [](FEXCore::Core::CpuStateFrame *Frame, pid_t tgid, pid_t tid, int sig, siginfo_t *info) -> uint64_t {
SYSCALL_STUB(rt_tgsigqueueinfo);
});
Expand Down
1 change: 0 additions & 1 deletion unittests/gvisor-tests/Known_Failures
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ epoll_test
exceptions_test
exec_binary_test
exec_test
fallocate_test
fcntl_test
flock_test
fork_test
Expand Down

0 comments on commit 2db44cf

Please sign in to comment.