Commit 04301c1f authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[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: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 02fe18c5
......@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#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;
}
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
/*
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment