[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>
This commit is contained in:
parent
0221575903
commit
ed1b58d8b5
|
@ -63,7 +63,7 @@ error:
|
||||||
*
|
*
|
||||||
* SIGWINCH can't be received synchronously, so you have to set up to receive it
|
* SIGWINCH can't be received synchronously, so you have to set up to receive it
|
||||||
* as a signal. That being the case, if you are going to wait for it, it is
|
* as a signal. That being the case, if you are going to wait for it, it is
|
||||||
* convenient to sit in a pause() and wait for the signal to bounce you out of
|
* convenient to sit in sigsuspend() and wait for the signal to bounce you out of
|
||||||
* it (see below for how we make sure to exit only on SIGWINCH).
|
* it (see below for how we make sure to exit only on SIGWINCH).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -94,18 +94,19 @@ static int winch_thread(void *arg)
|
||||||
"byte, err = %d\n", -count);
|
"byte, err = %d\n", -count);
|
||||||
|
|
||||||
/* We are not using SIG_IGN on purpose, so don't fix it as I thought to
|
/* We are not using SIG_IGN on purpose, so don't fix it as I thought to
|
||||||
* do! If using SIG_IGN, the pause() call below would not stop on
|
* do! If using SIG_IGN, the sigsuspend() call below would not stop on
|
||||||
* SIGWINCH. */
|
* SIGWINCH. */
|
||||||
|
|
||||||
signal(SIGWINCH, winch_handler);
|
signal(SIGWINCH, winch_handler);
|
||||||
sigfillset(&sigs);
|
sigfillset(&sigs);
|
||||||
sigdelset(&sigs, SIGWINCH);
|
/* Block all signals possible. */
|
||||||
/* Block anything else than SIGWINCH. */
|
|
||||||
if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
|
if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
|
||||||
printk("winch_thread : sigprocmask failed, errno = %d\n",
|
printk("winch_thread : sigprocmask failed, errno = %d\n",
|
||||||
errno);
|
errno);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
/* In sigsuspend(), block anything else than SIGWINCH. */
|
||||||
|
sigdelset(&sigs, SIGWINCH);
|
||||||
|
|
||||||
if(setsid() < 0){
|
if(setsid() < 0){
|
||||||
printk("winch_thread : setsid failed, errno = %d\n", errno);
|
printk("winch_thread : setsid failed, errno = %d\n", errno);
|
||||||
|
@ -130,7 +131,7 @@ static int winch_thread(void *arg)
|
||||||
while(1){
|
while(1){
|
||||||
/* This will be interrupted by SIGWINCH only, since other signals
|
/* This will be interrupted by SIGWINCH only, since other signals
|
||||||
* are blocked.*/
|
* are blocked.*/
|
||||||
pause();
|
sigsuspend(&sigs);
|
||||||
|
|
||||||
count = os_write_file(pipe_fd, &c, sizeof(c));
|
count = os_write_file(pipe_fd, &c, sizeof(c));
|
||||||
if(count != sizeof(c))
|
if(count != sizeof(c))
|
||||||
|
|
Loading…
Reference in a new issue