Commit 2c2c4c6e authored by David Mosberger's avatar David Mosberger

ia64: Rearrange ia64_do_signal() such that it is possible for a debugger to

	cancel system-call restart.
parent 45f4d49a
...@@ -538,31 +538,41 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) ...@@ -538,31 +538,41 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
if (!oldset) if (!oldset)
oldset = &current->blocked; oldset = &current->blocked;
if (IS_IA32_PROCESS(&scr->pt)) { /*
if (in_syscall) { * This only loops in the rare cases of handle_signal() failing, in which case we
if (errno >= 0) * need to push through a forced SIGSEGV.
restart = 0; */
else
errno = -errno;
}
} else if ((long) scr->pt.r10 != -1)
/*
* A system calls has to be restarted only if one of the error codes
* ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10
* isn't -1 then r8 doesn't hold an error code and we don't need to
* restart the syscall, so we can clear the "restart" flag here.
*/
restart = 0;
while (1) { while (1) {
int signr = get_signal_to_deliver(&info, &scr->pt, NULL); int signr = get_signal_to_deliver(&info, &scr->pt, NULL);
/*
* get_signal_to_deliver() may have run a debugger (via notify_parent())
* and the debugger may have modified the state (e.g., to arrange for an
* inferior call), thus it's important to check for restarting _after_
* get_signal_to_deliver().
*/
if (IS_IA32_PROCESS(&scr->pt)) {
if (in_syscall) {
if (errno >= 0)
restart = 0;
else
errno = -errno;
}
} else if ((long) scr->pt.r10 != -1)
/*
* A system calls has to be restarted only if one of the error codes
* ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned. If r10
* isn't -1 then r8 doesn't hold an error code and we don't need to
* restart the syscall, so we can clear the "restart" flag here.
*/
restart = 0;
if (signr <= 0) if (signr <= 0)
break; break;
ka = &current->sighand->action[signr - 1]; ka = &current->sighand->action[signr - 1];
if (restart) { if (unlikely(restart)) {
switch (errno) { switch (errno) {
case ERESTART_RESTARTBLOCK: case ERESTART_RESTARTBLOCK:
case ERESTARTNOHAND: case ERESTARTNOHAND:
...@@ -582,6 +592,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) ...@@ -582,6 +592,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
scr->pt.cr_iip -= 2; scr->pt.cr_iip -= 2;
} else } else
ia64_decrement_ip(&scr->pt); ia64_decrement_ip(&scr->pt);
restart = 0; /* don't restart twice if handle_signal() fails... */
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment