extern void newproc(ptptr p);
extern ptptr ptab_alloc(void);
extern void ssig(ptptr proc, uint8_t sig);
+extern void recalc_cursig(void);
extern uint8_t chksigs(void);
extern void program_vectors(uint16_t *pageptr);
extern void sgrpsig(uint16_t pgrp, uint8_t sig);
SIGBIT(SIGCHLD) | SIGBIT(SIGURG) | SIGBIT(SIGWINCH) | SIGBIT(SIGIO) |
SIGBIT(SIGCONT);
-/* Process a block of 16 signals so we can avoid using longs */
+/* Put back a computed signal so that we can recalculate what needs to be
+ serviced correctly */
+void recalc_cursig(void)
+{
+ if (udata.u_cursig) {
+ struct sigbits *sb = udata.u_ptab->p_sig;
+ if (udata.u_cursig & 16) {
+ sb++;
+ udata.u_cursig &= ~16;
+ }
+ sb->s_pending |= 1 << udata.u_cursig;
+ udata.u_cursig = 0;
+ }
+}
+/* Process a block of 16 signals so we can avoid using longs */
static uint8_t chksigset(struct sigbits *sb, uint8_t b)
{
uint8_t j = 1;
/* Sleeping without signals allowed. We rely upon the fact that
P_IOWAIT is never pre-empted or returns to user space so
udata.u_cursig is not consulted until it is safe to do so */
- if (udata.u_ptab->p_status == P_IOWAIT)
+ if (udata.u_ptab->p_status == P_IOWAIT) {
+ recalc_cursig();
return 0;
+ }
/* Fast path - no signals pending means no work.
Cursig being set means we've already worked out what to do.
if (sig != SIGKILL && sig != SIGSTOP)
udata.u_sigvec[sig] = func;
/* Force recalculation of signal pending in the syscall return path */
- udata.u_cursig = 0;
+ recalc_cursig();;
irqrestore(irq);
return (retval);
else
sb->s_held &= ~sigmask(sig);
/* Force recalculation of signal pending in the syscall return path */
- udata.u_cursig = 0;
+ recalc_cursig();
return 0;
}