]> err.no Git - linux-2.6/commitdiff
uml: work around host tcsetattr bug
authorJeff Dike <jdike@addtoit.com>
Sat, 1 Dec 2007 20:16:30 +0000 (12:16 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 3 Dec 2007 16:13:17 +0000 (08:13 -0800)
Under the conditions that UML uses it, tcgetattr is guaranteed to return
-EINTR when the console is attached to /dev/ptmx, making generic_console_write
hang because it loops, calling tcgetattr until it succeeds.  This is a host
bug - see http://marc.info/?l=linux-kernel&m=119618990807182&w=2 for the
details.

This patch works around it by blocking SIGIO while the terminal attributes are
being fiddled.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/um/drivers/chan_user.c

index b88e93b3a39f055a5b8a4a4d72b54ae8fe3ed5ee..025764089ac8ea7b739652c827fbe88b3a400324 100644 (file)
@@ -74,10 +74,16 @@ void generic_free(void *data)
 
 int generic_console_write(int fd, const char *buf, int n)
 {
+       sigset_t old, no_sigio;
        struct termios save, new;
        int err;
 
        if (isatty(fd)) {
+               sigemptyset(&no_sigio);
+               sigaddset(&no_sigio, SIGIO);
+               if (sigprocmask(SIG_BLOCK, &no_sigio, &old))
+                       goto error;
+
                CATCH_EINTR(err = tcgetattr(fd, &save));
                if (err)
                        goto error;
@@ -97,8 +103,11 @@ int generic_console_write(int fd, const char *buf, int n)
         * Restore raw mode, in any case; we *must* ignore any error apart
         * EINTR, except for debug.
         */
-       if (isatty(fd))
+       if (isatty(fd)) {
                CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
+               sigprocmask(SIG_SETMASK, &old, NULL);
+       }
+
        return err;
 error:
        return -errno;