diff options
Diffstat (limited to 'arch/um/os-Linux/signal.c')
-rw-r--r-- | arch/um/os-Linux/signal.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 420ee86d0d1a..18e5c8b67eb8 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -117,6 +117,46 @@ void remove_sigstack(void) | |||
117 | 117 | ||
118 | void (*handlers[_NSIG])(int sig, struct sigcontext *sc); | 118 | void (*handlers[_NSIG])(int sig, struct sigcontext *sc); |
119 | 119 | ||
120 | void handle_signal(int sig, struct sigcontext *sc) | ||
121 | { | ||
122 | unsigned long pending = 0; | ||
123 | |||
124 | do { | ||
125 | int nested, bail; | ||
126 | |||
127 | /* | ||
128 | * pending comes back with one bit set for each | ||
129 | * interrupt that arrived while setting up the stack, | ||
130 | * plus a bit for this interrupt, plus the zero bit is | ||
131 | * set if this is a nested interrupt. | ||
132 | * If bail is true, then we interrupted another | ||
133 | * handler setting up the stack. In this case, we | ||
134 | * have to return, and the upper handler will deal | ||
135 | * with this interrupt. | ||
136 | */ | ||
137 | bail = to_irq_stack(sig, &pending); | ||
138 | if(bail) | ||
139 | return; | ||
140 | |||
141 | nested = pending & 1; | ||
142 | pending &= ~1; | ||
143 | |||
144 | while((sig = ffs(pending)) != 0){ | ||
145 | sig--; | ||
146 | pending &= ~(1 << sig); | ||
147 | (*handlers[sig])(sig, sc); | ||
148 | } | ||
149 | |||
150 | /* Again, pending comes back with a mask of signals | ||
151 | * that arrived while tearing down the stack. If this | ||
152 | * is non-zero, we just go back, set up the stack | ||
153 | * again, and handle the new interrupts. | ||
154 | */ | ||
155 | if(!nested) | ||
156 | pending = from_irq_stack(nested); | ||
157 | } while(pending); | ||
158 | } | ||
159 | |||
120 | extern void hard_handler(int sig); | 160 | extern void hard_handler(int sig); |
121 | 161 | ||
122 | void set_handler(int sig, void (*handler)(int), int flags, ...) | 162 | void set_handler(int sig, void (*handler)(int), int flags, ...) |