aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorBodo Stroesser <bstroesser@fujitsu-siemens.com>2005-09-03 18:57:24 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:21 -0400
commited1b58d8b53519e10a35c6a2bb49cac35f439621 (patch)
tree30eacf51f9e7d11fcfe2c795e3da48e1e7363daf /arch/um
parent0221575903ad68debea57679b5b46575bf57afb1 (diff)
[PATCH] uml: fix SIGWINCH handler race while waiting for signals.
If a SIGWINCH comes in, while winch_thread() isn't waiting in wait(), winch_thread could miss signals. It isn't very probable, that anyone will see this causing trouble, as it would need a very special timing, that a missed SIGWINCH results in a wrong window size. So, this is a minor problem. But why not fix, as it can be done so easy? Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com> Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Cc: 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')
-rw-r--r--arch/um/drivers/chan_user.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 5d3768156c92..de3bce71aeb3 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -63,7 +63,7 @@ error:
63 * 63 *
64 * SIGWINCH can't be received synchronously, so you have to set up to receive it 64 * SIGWINCH can't be received synchronously, so you have to set up to receive it
65 * as a signal. That being the case, if you are going to wait for it, it is 65 * as a signal. That being the case, if you are going to wait for it, it is
66 * convenient to sit in a pause() and wait for the signal to bounce you out of 66 * convenient to sit in sigsuspend() and wait for the signal to bounce you out of
67 * it (see below for how we make sure to exit only on SIGWINCH). 67 * it (see below for how we make sure to exit only on SIGWINCH).
68 */ 68 */
69 69
@@ -94,18 +94,19 @@ static int winch_thread(void *arg)
94 "byte, err = %d\n", -count); 94 "byte, err = %d\n", -count);
95 95
96 /* We are not using SIG_IGN on purpose, so don't fix it as I thought to 96 /* We are not using SIG_IGN on purpose, so don't fix it as I thought to
97 * do! If using SIG_IGN, the pause() call below would not stop on 97 * do! If using SIG_IGN, the sigsuspend() call below would not stop on
98 * SIGWINCH. */ 98 * SIGWINCH. */
99 99
100 signal(SIGWINCH, winch_handler); 100 signal(SIGWINCH, winch_handler);
101 sigfillset(&sigs); 101 sigfillset(&sigs);
102 sigdelset(&sigs, SIGWINCH); 102 /* Block all signals possible. */
103 /* Block anything else than SIGWINCH. */
104 if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ 103 if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
105 printk("winch_thread : sigprocmask failed, errno = %d\n", 104 printk("winch_thread : sigprocmask failed, errno = %d\n",
106 errno); 105 errno);
107 exit(1); 106 exit(1);
108 } 107 }
108 /* In sigsuspend(), block anything else than SIGWINCH. */
109 sigdelset(&sigs, SIGWINCH);
109 110
110 if(setsid() < 0){ 111 if(setsid() < 0){
111 printk("winch_thread : setsid failed, errno = %d\n", errno); 112 printk("winch_thread : setsid failed, errno = %d\n", errno);
@@ -130,7 +131,7 @@ static int winch_thread(void *arg)
130 while(1){ 131 while(1){
131 /* This will be interrupted by SIGWINCH only, since other signals 132 /* This will be interrupted by SIGWINCH only, since other signals
132 * are blocked.*/ 133 * are blocked.*/
133 pause(); 134 sigsuspend(&sigs);
134 135
135 count = os_write_file(pipe_fd, &c, sizeof(c)); 136 count = os_write_file(pipe_fd, &c, sizeof(c));
136 if(count != sizeof(c)) 137 if(count != sizeof(c))