From 04301c1f80249f6b42d8b11d785755cd3d575ce3 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 16 Sep 2004 22:13:41 -0700 Subject: [PATCH] [PATCH] uml: clean up terminal state handling This patch cleans up UML's handling of terminal state with better error handling, interface cleanup, and some code tidying. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/fd.c | 17 ++++++++++++++--- arch/um/drivers/port_user.c | 11 ++++++++--- arch/um/drivers/pty.c | 23 +++++++++++++++++------ arch/um/drivers/tty.c | 11 ++++++++--- arch/um/drivers/xterm.c | 15 +++++++++++++-- arch/um/include/user_util.h | 7 +++---- arch/um/kernel/sigio_user.c | 3 ++- arch/um/kernel/user_util.c | 17 ++++------------- 8 files changed, 69 insertions(+), 35 deletions(-) diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 33c6c7868ce25..1c6daad921a24 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "user.h" #include "user_util.h" #include "chan_user.h" @@ -45,10 +46,16 @@ void *fd_init(char *str, int device, struct chan_opts *opts) int fd_open(int input, int output, int primary, void *d, char **dev_out) { struct fd_chan *data = d; + int err; if(data->raw && isatty(data->fd)){ - tcgetattr(data->fd, &data->tt); - raw(data->fd, 0); + CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); + if(err) + return(err); + + err = raw(data->fd); + if(err) + return(err); } sprintf(data->str, "%d", data->fd); *dev_out = data->str; @@ -58,9 +65,13 @@ int fd_open(int input, int output, int primary, void *d, char **dev_out) void fd_close(int fd, void *d) { struct fd_chan *data = d; + int err; if(data->raw && isatty(fd)){ - tcsetattr(fd, TCSAFLUSH, &data->tt); + CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); + if(err) + printk("Failed to restore terminal state - " + "errno = %d\n", -err); data->raw = 0; } } diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index e0588cbe3720a..1e8592ec1158f 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -76,12 +76,17 @@ void port_free(void *d) int port_open(int input, int output, int primary, void *d, char **dev_out) { struct port_chan *data = d; - int fd; + int fd, err; fd = port_wait(data->kernel_data); if((fd >= 0) && data->raw){ - tcgetattr(fd, &data->tt); - raw(fd, 0); + CATCH_EINTR(err = tcgetattr(fd, &data->tt)); + if(err) + return(err); + + err = raw(fd); + if(err) + return(err); } *dev_out = data->dev; return(fd); diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index bfa08d8126046..c4634b5003525 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -38,7 +38,7 @@ int pts_open(int input, int output, int primary, void *d, char **dev_out) { struct pty_chan *data = d; char *dev; - int fd; + int fd, err; fd = get_pty(); if(fd < 0){ @@ -46,8 +46,13 @@ int pts_open(int input, int output, int primary, void *d, char **dev_out) return(-errno); } if(data->raw){ - tcgetattr(fd, &data->tt); - raw(fd, 0); + CATCH_EINTR(err = tcgetattr(fd, &data->tt)); + if(err) + return(err); + + err = raw(fd); + if(err) + return(err); } dev = ptsname(fd); @@ -89,13 +94,19 @@ int getmaster(char *line) int pty_open(int input, int output, int primary, void *d, char **dev_out) { struct pty_chan *data = d; - int fd; + int fd, err; char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; fd = getmaster(dev); - if(fd < 0) return(-errno); + if(fd < 0) + return(-errno); + + if(data->raw){ + err = raw(fd); + if(err) + return(err); + } - if(data->raw) raw(fd, 0); if(data->announce) (*data->announce)(dev, data->dev); sprintf(data->dev_name, "%s", dev); diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 20a7e45a9ebbe..dd008aa8f5dd0 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -41,13 +41,18 @@ void *tty_chan_init(char *str, int device, struct chan_opts *opts) int tty_open(int input, int output, int primary, void *d, char **dev_out) { struct tty_chan *data = d; - int fd; + int fd, err; fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); if(fd < 0) return(fd); if(data->raw){ - tcgetattr(fd, &data->tt); - raw(fd, 0); + CATCH_EINTR(err = tcgetattr(fd, &data->tt)); + if(err) + return(err); + + err = raw(fd); + if(err) + return(err); } *dev_out = data->dev; diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index f429a35dbba6d..f417b3b668ade 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -142,8 +142,19 @@ int xterm_open(int input, int output, int primary, void *d, char **dev_out) goto out; } - tcgetattr(new, &data->tt); - if(data->raw) raw(new, 0); + CATCH_EINTR(err = tcgetattr(new, &data->tt)); + if(err){ + new = err; + goto out; + } + + if(data->raw){ + err = raw(new); + if(err){ + new = err; + goto out; + } + } data->pid = pid; *dev_out = NULL; diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 0ba8eb056deb1..fbb569095ec05 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,6 +8,8 @@ #include "sysdep/ptrace.h" +#define CATCH_EINTR(expr) while (((expr) < 0) && (errno == EINTR)) + extern int mode_tt; extern int grantpt(int __fd); @@ -89,11 +91,8 @@ extern void forward_pending_sigio(int target); extern int can_do_skas(void); extern void arch_init_thread(void); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); +extern int raw(int fd); -extern int __raw(int fd, int complain, int now); -#define raw(fd, complain) __raw((fd), (complain), 1) - -#define CATCH_EINTR(expr) while ( ((expr) < 0) && errno == EINTR) #endif /* diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index de4fcb279d6e1..82d19b451d5ea 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c @@ -68,7 +68,8 @@ void __init check_one_sigio(void (*proc)(int, int)) return; } - err = __raw(master, 1, 0); //Not now, but complain so we now where we failed. + /* Not now, but complain so we now where we failed. */ + err = raw(master); if (err < 0) panic("check_sigio : __raw failed, errno = %d\n", -err); diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index a366c189c638f..8eabe637720fd 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c @@ -118,35 +118,26 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay) } } -int __raw(int fd, int complain, int now) +int raw(int fd) { struct termios tt; int err; - int when; CATCH_EINTR(err = tcgetattr(fd, &tt)); - if (err < 0) { - if (complain) printk("tcgetattr failed, errno = %d\n", errno); return(-errno); } cfmakeraw(&tt); - if (now) - when = TCSANOW; - else - when = TCSADRAIN; - - CATCH_EINTR(err = tcsetattr(fd, when, &tt)); - + CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt)); if (err < 0) { - if (complain) printk("tcsetattr failed, errno = %d\n", errno); return(-errno); } - /*XXX: tcsetattr could have applied only some changes + + /* XXX tcsetattr could have applied only some changes * (and cfmakeraw() is a set of changes) */ return(0); } -- 2.53.0