[MIPS] IRIX: Crapectopy.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Ralf Baechle 2006-08-03 21:53:10 +01:00
parent 048c6140c0
commit 1b223c861f

View File

@ -17,6 +17,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h>
#undef DEBUG_SIG #undef DEBUG_SIG
@ -172,11 +173,12 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
return ret; return ret;
} }
asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) void do_irix_signal(struct pt_regs *regs)
{ {
struct k_sigaction ka; struct k_sigaction ka;
siginfo_t info; siginfo_t info;
int signr; int signr;
sigset_t *oldset;
/* /*
* We want the common case to go fast, which is why we may in certain * We want the common case to go fast, which is why we may in certain
@ -184,14 +186,27 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
* if so. * if so.
*/ */
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return;
if (!oldset) if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = &current->saved_sigmask;
else
oldset = &current->blocked; oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) if (signr > 0) {
return handle_signal(signr, &info, &ka, oldset, regs); /* Whee! Actually deliver the signal. */
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return;
}
/* /*
* Who's code doesn't conform to the restartable syscall convention * Who's code doesn't conform to the restartable syscall convention
@ -204,8 +219,21 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
regs->regs[2] == ERESTARTNOINTR) { regs->regs[2] == ERESTARTNOINTR) {
regs->cp0_epc -= 8; regs->cp0_epc -= 8;
} }
if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
regs->regs[2] = __NR_restart_syscall;
regs->regs[7] = regs->regs[26];
regs->cp0_epc -= 4;
}
}
/*
* If there's no signal to deliver, we just put the saved sigmask
* back
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
} }
return 0;
} }
asmlinkage void asmlinkage void
@ -409,7 +437,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
asmlinkage int irix_sigsuspend(struct pt_regs *regs) asmlinkage int irix_sigsuspend(struct pt_regs *regs)
{ {
sigset_t saveset, newset; sigset_t newset;
sigset_t __user *uset; sigset_t __user *uset;
uset = (sigset_t __user *) regs->regs[4]; uset = (sigset_t __user *) regs->regs[4];
@ -418,18 +446,15 @@ asmlinkage int irix_sigsuspend(struct pt_regs *regs)
sigdelsetmask(&newset, ~_BLOCKABLE); sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
saveset = current->blocked; current->saved_sigmask = current->blocked;
current->blocked = newset; current->blocked = newset;
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
regs->regs[2] = -EINTR; current->state = TASK_INTERRUPTIBLE;
while (1) { schedule();
current->state = TASK_INTERRUPTIBLE; set_thread_flag(TIF_RESTORE_SIGMASK);
schedule(); return -ERESTARTNOHAND;
if (do_irix_signal(&saveset, regs))
return -EINTR;
}
} }
/* hate hate hate... */ /* hate hate hate... */