mirror of
https://github.com/ish-app/ish.git
synced 2026-01-18 13:57:29 +00:00
Implement pselect
This commit is contained in:
parent
00ec13cb6e
commit
db525dc2ad
@ -122,6 +122,7 @@ syscall_t syscall_table[] = {
|
||||
[305] = (syscall_t) sys_readlinkat,
|
||||
[306] = (syscall_t) sys_fchmodat,
|
||||
[307] = (syscall_t) sys_faccessat,
|
||||
[308] = (syscall_t) sys_pselect,
|
||||
[320] = (syscall_t) sys_utimensat,
|
||||
[324] = (syscall_t) sys_fallocate,
|
||||
[340] = (syscall_t) sys_prlimit,
|
||||
|
||||
@ -190,6 +190,7 @@ struct pollfd_ {
|
||||
};
|
||||
dword_t sys_poll(addr_t fds, dword_t nfds, dword_t timeout);
|
||||
dword_t sys_select(fd_t nfds, addr_t readfds_addr, addr_t writefds_addr, addr_t exceptfds_addr, addr_t timeout_addr);
|
||||
dword_t sys_pselect(fd_t nfds, addr_t readfds_addr, addr_t writefds_addr, addr_t exceptfds_addr, addr_t timeout_addr, addr_t sigmask_addr);
|
||||
|
||||
// misc
|
||||
dword_t sys_futex(addr_t uaddr, dword_t op, dword_t val);
|
||||
|
||||
@ -134,3 +134,23 @@ dword_t sys_poll(addr_t fds, dword_t nfds, dword_t timeout) {
|
||||
return _EFAULT;
|
||||
return err;
|
||||
}
|
||||
|
||||
dword_t sys_pselect(fd_t nfds, addr_t readfds_addr, addr_t writefds_addr, addr_t exceptfds_addr, addr_t timeout_addr, addr_t sigmask_addr) {
|
||||
// a system call can only take 6 parameters, so the last two need to be passed as a pointer to a struct
|
||||
struct {
|
||||
addr_t mask_addr;
|
||||
dword_t mask_size;
|
||||
} sigmask;
|
||||
if (user_get(sigmask_addr, sigmask))
|
||||
return _EFAULT;
|
||||
if (sigmask.mask_size != sizeof(sigset_t_))
|
||||
return _EINVAL;
|
||||
sigset_t_ mask, old_mask;
|
||||
if (user_get(sigmask.mask_addr, mask))
|
||||
return _EFAULT;
|
||||
|
||||
do_sigprocmask(SIG_SETMASK_, mask, &old_mask);
|
||||
dword_t res = sys_select(nfds, readfds_addr, writefds_addr, exceptfds_addr, timeout_addr);
|
||||
do_sigprocmask(SIG_SETMASK_, old_mask, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -213,22 +213,11 @@ dword_t sys_sigaction(dword_t signum, addr_t action_addr, addr_t oldaction_addr)
|
||||
return sys_rt_sigaction(signum, action_addr, oldaction_addr, 1);
|
||||
}
|
||||
|
||||
dword_t sys_rt_sigprocmask(dword_t how, addr_t set_addr, addr_t oldset_addr, dword_t size) {
|
||||
if (size != sizeof(sigset_t_))
|
||||
return _EINVAL;
|
||||
|
||||
sigset_t_ set;
|
||||
if (user_get(set_addr, set))
|
||||
return _EFAULT;
|
||||
STRACE("rt_sigprocmask(%s, 0x%llx, 0x%x, %d)",
|
||||
how == SIG_BLOCK_ ? "SIG_BLOCK" :
|
||||
how == SIG_UNBLOCK_ ? "SIG_UNBLOCK" :
|
||||
how == SIG_SETMASK_ ? "SIG_SETMASK" : "??",
|
||||
(long long) set, oldset_addr, size);
|
||||
sigset_t_ oldset = current->blocked;
|
||||
|
||||
int do_sigprocmask(dword_t how, sigset_t_ set, sigset_t_ *oldset_out) {
|
||||
struct sighand *sighand = current->sighand;
|
||||
lock(&sighand->lock);
|
||||
sigset_t oldset = current->blocked;
|
||||
|
||||
if (how == SIG_BLOCK_)
|
||||
current->blocked |= set;
|
||||
else if (how == SIG_UNBLOCK_)
|
||||
@ -245,7 +234,27 @@ dword_t sys_rt_sigprocmask(dword_t how, addr_t set_addr, addr_t oldset_addr, dwo
|
||||
current->pending |= current->queued & unblocked;
|
||||
current->queued &= ~unblocked;
|
||||
unlock(&sighand->lock);
|
||||
if (oldset_out != NULL)
|
||||
*oldset_out = current->blocked;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dword_t sys_rt_sigprocmask(dword_t how, addr_t set_addr, addr_t oldset_addr, dword_t size) {
|
||||
if (size != sizeof(sigset_t_))
|
||||
return _EINVAL;
|
||||
|
||||
sigset_t_ set, oldset;
|
||||
if (user_get(set_addr, set))
|
||||
return _EFAULT;
|
||||
STRACE("rt_sigprocmask(%s, 0x%llx, 0x%x, %d)",
|
||||
how == SIG_BLOCK_ ? "SIG_BLOCK" :
|
||||
how == SIG_UNBLOCK_ ? "SIG_UNBLOCK" :
|
||||
how == SIG_SETMASK_ ? "SIG_SETMASK" : "??",
|
||||
(long long) set, oldset_addr, size);
|
||||
|
||||
int err = do_sigprocmask(how, set, &oldset);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (oldset_addr != 0)
|
||||
if (user_put(oldset_addr, oldset))
|
||||
return _EFAULT;
|
||||
|
||||
@ -81,6 +81,7 @@ dword_t sys_rt_sigreturn(dword_t sig);
|
||||
#define SIG_UNBLOCK_ 1
|
||||
#define SIG_SETMASK_ 2
|
||||
typedef uint64_t sigset_t_;
|
||||
int do_sigprocmask(dword_t how, sigset_t_ set, sigset_t_ *oldset);
|
||||
dword_t sys_rt_sigprocmask(dword_t how, addr_t set, addr_t oldset, dword_t size);
|
||||
|
||||
struct stack_t_ {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user