signal.c revision c9a3072d13e4b8a6549ecc1db6390a55c7ee2ddf
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 PathScale, Inc 3ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Licensed under the GPL 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 70805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov#include <stdlib.h> 80805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov#include <stdarg.h> 9ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include <errno.h> 10ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include <signal.h> 11ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include <strings.h> 12cff65c4f0ea6662124bbb7bf3806e5df1c6d735dGennady Sharapov#include "os.h" 13ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include "sysdep/barrier.h" 14ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include "sysdep/sigcontext.h" 15ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike#include "user.h" 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike/* 1861b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike * These are the asynchronous signals. SIGPROF is excluded because we want to 191d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * be able to profile all of UML, not just the non-critical sections. If 201d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * profiling is not thread-safe, then that is not my problem. We can disable 211d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * profiling when SMP is enabled in that case. 221d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike */ 231d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike#define SIGIO_BIT 0 241d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike#define SIGIO_MASK (1 << SIGIO_BIT) 251d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 261d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike#define SIGVTALRM_BIT 1 271d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) 281d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 29ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike/* 30ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * These are used by both the signal handlers and 3153b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * block/unblock_signals. I don't want modifications cached in a 3253b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * register - they must go straight to memory. 3353b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike */ 3453b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dikestatic volatile int signals_enabled = 1; 3553b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dikestatic volatile int pending = 0; 361d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 374b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dikevoid sig_handler(int sig, struct sigcontext *sc) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 391d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike int enabled; 401d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 411d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike enabled = signals_enabled; 42ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (!enabled && (sig == SIGIO)) { 431d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike pending |= SIGIO_MASK; 441d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return; 451d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike } 461d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 471d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike block_signals(); 481d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 496aa802ce6acc9b1f0b34114b3f7c21c84872cc3aJeff Dike sig_handler_common_skas(sig, sc); 501d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 511d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike set_signals(enabled); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dikestatic void real_alarm_handler(struct sigcontext *sc) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5677bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike struct uml_pt_regs regs; 572ea5bc5e5bb51492f189bba44045e0de7decf4a0Jeff Dike 58ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sc != NULL) 592ea5bc5e5bb51492f189bba44045e0de7decf4a0Jeff Dike copy_sc(®s, sc); 6077bf4400319db9d2a8af6b00c2be6faa0f3d07cbJeff Dike regs.is_user = 0; 612ea5bc5e5bb51492f189bba44045e0de7decf4a0Jeff Dike unblock_signals(); 6261b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike timer_handler(SIGVTALRM, ®s); 631d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike} 641d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 654b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dikevoid alarm_handler(int sig, struct sigcontext *sc) 661d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike{ 671d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike int enabled; 681d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 691d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike enabled = signals_enabled; 70ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (!signals_enabled) { 7161b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike pending |= SIGVTALRM_MASK; 721d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return; 731d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike } 741d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 751d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike block_signals(); 761d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 7761b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike real_alarm_handler(sc); 781d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike set_signals(enabled); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8178a26e25ce4837a03ac3b6c32cdae1958e547639Jeff Dikevoid timer_init(void) 8278a26e25ce4837a03ac3b6c32cdae1958e547639Jeff Dike{ 8378a26e25ce4837a03ac3b6c32cdae1958e547639Jeff Dike set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, 8461b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1); 8578a26e25ce4837a03ac3b6c32cdae1958e547639Jeff Dike} 8678a26e25ce4837a03ac3b6c32cdae1958e547639Jeff Dike 870805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovvoid set_sigstack(void *sig_stack, int size) 880805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 890805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov stack_t stack = ((stack_t) { .ss_flags = 0, 900805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov .ss_sp = (__ptr_t) sig_stack, 910805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov .ss_size = size - sizeof(void *) }); 920805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 93ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sigaltstack(&stack, NULL) != 0) 940805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov panic("enabling signal stack failed, errno = %d\n", errno); 950805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 960805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 970805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovvoid remove_sigstack(void) 980805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 990805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, 1000805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov .ss_sp = NULL, 1010805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov .ss_size = 0 }); 1020805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 103ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sigaltstack(&stack, NULL) != 0) 1040805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov panic("disabling signal stack failed, errno = %d\n", errno); 1050805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 1060805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 1074b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dikevoid (*handlers[_NSIG])(int sig, struct sigcontext *sc); 1084b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike 109c14b84949e127560084c7c56b365931c71c60768Jeff Dikevoid handle_signal(int sig, struct sigcontext *sc) 110c14b84949e127560084c7c56b365931c71c60768Jeff Dike{ 111508a92741a105e2e3d466cd727fb73154ebf08deJeff Dike unsigned long pending = 1UL << sig; 112c14b84949e127560084c7c56b365931c71c60768Jeff Dike 113c14b84949e127560084c7c56b365931c71c60768Jeff Dike do { 114c14b84949e127560084c7c56b365931c71c60768Jeff Dike int nested, bail; 115c14b84949e127560084c7c56b365931c71c60768Jeff Dike 116c14b84949e127560084c7c56b365931c71c60768Jeff Dike /* 117c14b84949e127560084c7c56b365931c71c60768Jeff Dike * pending comes back with one bit set for each 118c14b84949e127560084c7c56b365931c71c60768Jeff Dike * interrupt that arrived while setting up the stack, 119c14b84949e127560084c7c56b365931c71c60768Jeff Dike * plus a bit for this interrupt, plus the zero bit is 120c14b84949e127560084c7c56b365931c71c60768Jeff Dike * set if this is a nested interrupt. 121c14b84949e127560084c7c56b365931c71c60768Jeff Dike * If bail is true, then we interrupted another 122c14b84949e127560084c7c56b365931c71c60768Jeff Dike * handler setting up the stack. In this case, we 123c14b84949e127560084c7c56b365931c71c60768Jeff Dike * have to return, and the upper handler will deal 124c14b84949e127560084c7c56b365931c71c60768Jeff Dike * with this interrupt. 125c14b84949e127560084c7c56b365931c71c60768Jeff Dike */ 126508a92741a105e2e3d466cd727fb73154ebf08deJeff Dike bail = to_irq_stack(&pending); 127ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (bail) 128c14b84949e127560084c7c56b365931c71c60768Jeff Dike return; 129c14b84949e127560084c7c56b365931c71c60768Jeff Dike 130c14b84949e127560084c7c56b365931c71c60768Jeff Dike nested = pending & 1; 131c14b84949e127560084c7c56b365931c71c60768Jeff Dike pending &= ~1; 132c14b84949e127560084c7c56b365931c71c60768Jeff Dike 133ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike while ((sig = ffs(pending)) != 0){ 134c14b84949e127560084c7c56b365931c71c60768Jeff Dike sig--; 135c14b84949e127560084c7c56b365931c71c60768Jeff Dike pending &= ~(1 << sig); 136c14b84949e127560084c7c56b365931c71c60768Jeff Dike (*handlers[sig])(sig, sc); 137c14b84949e127560084c7c56b365931c71c60768Jeff Dike } 138c14b84949e127560084c7c56b365931c71c60768Jeff Dike 139ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 140ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Again, pending comes back with a mask of signals 141c14b84949e127560084c7c56b365931c71c60768Jeff Dike * that arrived while tearing down the stack. If this 142c14b84949e127560084c7c56b365931c71c60768Jeff Dike * is non-zero, we just go back, set up the stack 143c14b84949e127560084c7c56b365931c71c60768Jeff Dike * again, and handle the new interrupts. 144c14b84949e127560084c7c56b365931c71c60768Jeff Dike */ 145ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (!nested) 146c14b84949e127560084c7c56b365931c71c60768Jeff Dike pending = from_irq_stack(nested); 147ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike } while (pending); 148c14b84949e127560084c7c56b365931c71c60768Jeff Dike} 149c14b84949e127560084c7c56b365931c71c60768Jeff Dike 1504b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dikeextern void hard_handler(int sig); 1514b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike 1520805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovvoid set_handler(int sig, void (*handler)(int), int flags, ...) 1530805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 1540805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov struct sigaction action; 1550805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov va_list ap; 1561d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike sigset_t sig_mask; 1570805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov int mask; 1580805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 1594b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike handlers[sig] = (void (*)(int, struct sigcontext *)) handler; 1604b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike action.sa_handler = hard_handler; 1614b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike 1620805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov sigemptyset(&action.sa_mask); 1634b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike 1644b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike va_start(ap, flags); 165ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike while ((mask = va_arg(ap, int)) != -1) 1660805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov sigaddset(&action.sa_mask, mask); 1670805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov va_end(ap); 1684b84c69b5f6c08a540e3683f1360a6cdef2806c7Jeff Dike 1690805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov action.sa_flags = flags; 1700805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov action.sa_restorer = NULL; 171ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sigaction(sig, &action, NULL) < 0) 1721d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike panic("sigaction failed - errno = %d\n", errno); 1731d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 1741d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike sigemptyset(&sig_mask); 1751d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike sigaddset(&sig_mask, sig); 176ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) 1771d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike panic("sigprocmask failed - errno = %d\n", errno); 1780805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 1790805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 1800805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovint change_sig(int signal, int on) 1810805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 1820805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov sigset_t sigset, old; 1830805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 1840805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov sigemptyset(&sigset); 1850805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov sigaddset(&sigset, signal); 186c9a3072d13e4b8a6549ecc1db6390a55c7ee2ddfWANG Cong if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old) < 0) 187c9a3072d13e4b8a6549ecc1db6390a55c7ee2ddfWANG Cong return -errno; 188ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike return !sigismember(&old, signal); 1890805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 1900805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 1910805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovvoid block_signals(void) 1920805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 1931d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike signals_enabled = 0; 194ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 195ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * This must return with signals disabled, so this barrier 19653b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * ensures that writes are flushed out before the return. 19753b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * This might matter if gcc figures out how to inline this and 19853b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * decides to shuffle this code into the caller. 19953b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike */ 20053b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike mb(); 2010805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 2020805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 2030805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovvoid unblock_signals(void) 2040805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 2051d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike int save_pending; 2060805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 207ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (signals_enabled == 1) 2081d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return; 2090805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 210ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 211ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * We loop because the IRQ handler returns with interrupts off. So, 2121d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * interrupts may have arrived and we need to re-enable them and 2131d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * recheck pending. 2141d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike */ 215ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike while(1) { 216ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 217ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Save and reset save_pending after enabling signals. This 2181d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * way, pending won't be changed while we're reading it. 2191d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike */ 2201d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike signals_enabled = 1; 2211d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 222ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 223ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Setting signals_enabled and reading pending must 22453b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * happen in this order. 22553b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike */ 22653b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike mb(); 22753b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike 2281d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike save_pending = pending; 229ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (save_pending == 0) { 230ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 231ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * This must return with signals enabled, so 23253b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * this barrier ensures that writes are 23353b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * flushed out before the return. This might 23453b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * matter if gcc figures out how to inline 23553b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * this (unlikely, given its size) and decides 23653b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike * to shuffle this code into the caller. 23753b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike */ 23853b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike mb(); 2391d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return; 24053b173327d283b9bdbfb0c3b6de6f0eb197819d6Jeff Dike } 2411d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 2421d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike pending = 0; 2431d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 244ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 245ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * We have pending interrupts, so disable signals, as the 2461d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * handlers expect them off when they are called. They will 2471d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * be enabled again above. 2481d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike */ 2491d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 2501d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike signals_enabled = 0; 2511d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 252ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike /* 253ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike * Deal with SIGIO first because the alarm handler might 2541d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * schedule, leaving the pending SIGIO stranded until we come 2551d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike * back here. 2561d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike */ 257ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (save_pending & SIGIO_MASK) 2586aa802ce6acc9b1f0b34114b3f7c21c84872cc3aJeff Dike sig_handler_common_skas(SIGIO, NULL); 2591d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike 260ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (save_pending & SIGVTALRM_MASK) 26161b63c556c0877ee6d3832ee641bc427ff4d94d6Jeff Dike real_alarm_handler(NULL); 2621d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike } 2630805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 2640805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 2650805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovint get_signals(void) 2660805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 2671d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return signals_enabled; 2680805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 2690805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 2700805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapovint set_signals(int enable) 2710805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov{ 2720805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov int ret; 273ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (signals_enabled == enable) 2741d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return enable; 2750805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 2761d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike ret = signals_enabled; 277ba180fd437156f7fd8cfb2fdd021d949eeef08d6Jeff Dike if (enable) 2781d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike unblock_signals(); 2791d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike else block_signals(); 2800805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov 2811d7173baf286c8b720f97f119ec92be43076ebdeJeff Dike return ret; 2820805d89c151b4800eade4c2f50d39c5253d7d054Gennady Sharapov} 283