diff options
author | Jeff Dike <jdike@addtoit.com> | 2006-09-26 02:33:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:49:07 -0400 |
commit | 4b84c69b5f6c08a540e3683f1360a6cdef2806c7 (patch) | |
tree | 708f1e4cbc2771886aaeb8eadb3ae4d458bc8133 /arch/um/os-Linux/main.c | |
parent | 19bdf0409f25a85a45874a5a8da6f3e4edcf4a49 (diff) |
[PATCH] uml: Move signal handlers to arch code
Have most signals go through an arch-provided handler which recovers the
sigcontext and then calls a generic handler. This replaces the
ARCH_GET_SIGCONTEXT macro, which was somewhat fragile. On x86_64, recovering
%rdx (which holds the sigcontext pointer) must be the first thing that
happens. sig_handler duly invokes that first, but there is no guarantee that
I can see that instructions won't be reordered such that %rdx is used before
that. Having the arch provide the handler seems much more robust.
Some signals in some parts of UML require their own handlers - these places
don't call set_handler any more. They call sigaction or signal themselves.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/os-Linux/main.c')
-rw-r--r-- | arch/um/os-Linux/main.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 90912aaca7aa..d1c5670787dc 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -67,13 +67,32 @@ static __init void do_uml_initcalls(void) | |||
67 | 67 | ||
68 | static void last_ditch_exit(int sig) | 68 | static void last_ditch_exit(int sig) |
69 | { | 69 | { |
70 | signal(SIGINT, SIG_DFL); | ||
71 | signal(SIGTERM, SIG_DFL); | ||
72 | signal(SIGHUP, SIG_DFL); | ||
73 | uml_cleanup(); | 70 | uml_cleanup(); |
74 | exit(1); | 71 | exit(1); |
75 | } | 72 | } |
76 | 73 | ||
74 | static void install_fatal_handler(int sig) | ||
75 | { | ||
76 | struct sigaction action; | ||
77 | |||
78 | /* All signals are enabled in this handler ... */ | ||
79 | sigemptyset(&action.sa_mask); | ||
80 | |||
81 | /* ... including the signal being handled, plus we want the | ||
82 | * handler reset to the default behavior, so that if an exit | ||
83 | * handler is hanging for some reason, the UML will just die | ||
84 | * after this signal is sent a second time. | ||
85 | */ | ||
86 | action.sa_flags = SA_RESETHAND | SA_NODEFER; | ||
87 | action.sa_restorer = NULL; | ||
88 | action.sa_handler = last_ditch_exit; | ||
89 | if(sigaction(sig, &action, NULL) < 0){ | ||
90 | printf("failed to install handler for signal %d - errno = %d\n", | ||
91 | errno); | ||
92 | exit(1); | ||
93 | } | ||
94 | } | ||
95 | |||
77 | #define UML_LIB_PATH ":/usr/lib/uml" | 96 | #define UML_LIB_PATH ":/usr/lib/uml" |
78 | 97 | ||
79 | static void setup_env_path(void) | 98 | static void setup_env_path(void) |
@@ -158,9 +177,12 @@ int main(int argc, char **argv, char **envp) | |||
158 | } | 177 | } |
159 | new_argv[argc] = NULL; | 178 | new_argv[argc] = NULL; |
160 | 179 | ||
161 | set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 180 | /* Allow these signals to bring down a UML if all other |
162 | set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 181 | * methods of control fail. |
163 | set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 182 | */ |
183 | install_fatal_handler(SIGINT); | ||
184 | install_fatal_handler(SIGTERM); | ||
185 | install_fatal_handler(SIGHUP); | ||
164 | 186 | ||
165 | scan_elf_aux( envp); | 187 | scan_elf_aux( envp); |
166 | 188 | ||