
From: <blaisorblade_spam@yahoo.it>

Fixes raw() and uses it in check_one_sigio; also fixes a silly panic (EINTR
returned by call).

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/um/include/user_util.h |    4 +++-
 25-akpm/arch/um/kernel/sigio_user.c |   11 ++++-------
 25-akpm/arch/um/kernel/user_util.c  |   29 ++++++++++++++++++++++++-----
 3 files changed, 31 insertions(+), 13 deletions(-)

diff -puN arch/um/include/user_util.h~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call arch/um/include/user_util.h
--- 25/arch/um/include/user_util.h~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call	2004-07-05 16:00:42.846506792 -0700
+++ 25-akpm/arch/um/include/user_util.h	2004-07-05 16:00:42.853505728 -0700
@@ -62,7 +62,6 @@ extern void set_cmdline(char *cmd);
 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
 extern int get_pty(void);
 extern void *um_kmalloc(int size);
-extern int raw(int fd, int complain);
 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
 extern void setup_machinename(char *machine_out);
 extern void setup_hostinfo(void);
@@ -90,6 +89,9 @@ extern void forward_pending_sigio(int ta
 extern int can_do_skas(void);
 extern void arch_init_thread(void);
 
+extern int __raw(int fd, int complain, int now);
+#define raw(fd, complain) __raw((fd), (complain), 1)
+
 #endif
 
 /*
diff -puN arch/um/kernel/sigio_user.c~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call arch/um/kernel/sigio_user.c
--- 25/arch/um/kernel/sigio_user.c~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call	2004-07-05 16:00:42.847506640 -0700
+++ 25-akpm/arch/um/kernel/sigio_user.c	2004-07-05 16:00:42.853505728 -0700
@@ -16,6 +16,7 @@
 #include "init.h"
 #include "user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "sigio.h"
 #include "helper.h"
 #include "os.h"
@@ -50,7 +51,6 @@ static void openpty_cb(void *arg)
 void __init check_one_sigio(void (*proc)(int, int))
 {
 	struct sigaction old, new;
-	struct termios tt;
 	struct openpty_arg pty = { .master = -1, .slave = -1 };
 	int master, slave, err;
 
@@ -68,12 +68,9 @@ void __init check_one_sigio(void (*proc)
 		return;
 	}
 
-	/* XXX These can fail with EINTR */
-	if(tcgetattr(master, &tt) < 0)
-		panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
-	cfmakeraw(&tt);
-	if(tcsetattr(master, TCSADRAIN, &tt) < 0)
-		panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
+	err = __raw(master, 1, 0); //Not now, but complain so we now where we failed.
+	if (err < 0)
+		panic("check_sigio : __raw failed, errno = %d\n", -err);
 
 	err = os_sigio_async(master, slave);
 	if(err < 0)
diff -puN arch/um/kernel/user_util.c~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call arch/um/kernel/user_util.c
--- 25/arch/um/kernel/user_util.c~uml-fixes-raw-and-uses-it-in-check_one_sigio-also-fixes-a-silly-panic-eintr-returned-by-call	2004-07-05 16:00:42.849506336 -0700
+++ 25-akpm/arch/um/kernel/user_util.c	2004-07-05 16:00:42.854505576 -0700
@@ -118,18 +118,37 @@ int wait_for_stop(int pid, int sig, int 
 	}
 }
 
-int raw(int fd, int complain)
+int __raw(int fd, int complain, int now)
 {
 	struct termios tt;
 	int err;
+	int when;
+
+	while (((err = tcgetattr(fd, &tt)) < 0) && errno == EINTR)
+		;
+
+	if (err < 0) {
+		if (complain)
+			printk("tcgetattr failed, errno = %d\n", errno);
+		return(-errno);
+	}
 
-	tcgetattr(fd, &tt);
 	cfmakeraw(&tt);
-	err = tcsetattr(fd, TCSANOW, &tt);
-	if((err < 0) && complain){
-		printk("tcsetattr failed, errno = %d\n", errno);
+
+	if (now)
+		when = TCSANOW;
+	else
+		when = TCSADRAIN;
+
+	while (((err = tcsetattr(fd, when, &tt)) < 0) && errno == EINTR)
+		;
+	if (err < 0) {
+		if (complain)
+			printk("tcsetattr failed, errno = %d\n", errno);
 		return(-errno);
 	}
+	/*XXX: tcsetattr could have applied only some changes
+	 * (and cfmakeraw() is a set of changes) */
 	return(0);
 }
 
_
