xref: /linux/arch/um/drivers/tty.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3  * Licensed under the GPL
4  */
5 
6 #include <stdio.h>
7 #include <termios.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include "chan_user.h"
11 #include "user_util.h"
12 #include "user.h"
13 #include "os.h"
14 #include "um_malloc.h"
15 
16 struct tty_chan {
17 	char *dev;
18 	int raw;
19 	struct termios tt;
20 };
21 
22 static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
23 {
24 	struct tty_chan *data;
25 
26 	if(*str != ':'){
27 		printk("tty_init : channel type 'tty' must specify "
28 		       "a device\n");
29 		return NULL;
30 	}
31 	str++;
32 
33 	data = um_kmalloc(sizeof(*data));
34 	if(data == NULL)
35 		return NULL;
36 	*data = ((struct tty_chan) { .dev 	= str,
37 				     .raw 	= opts->raw });
38 
39 	return data;
40 }
41 
42 static int tty_open(int input, int output, int primary, void *d,
43 		    char **dev_out)
44 {
45 	struct tty_chan *data = d;
46 	int fd, err;
47 
48 	fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
49 	if(fd < 0)
50 		return fd;
51 
52 	if(data->raw){
53 		CATCH_EINTR(err = tcgetattr(fd, &data->tt));
54 		if(err)
55 			return err;
56 
57 		err = raw(fd);
58 		if(err)
59 			return err;
60 	}
61 
62 	*dev_out = data->dev;
63 	return fd;
64 }
65 
66 const struct chan_ops tty_ops = {
67 	.type		= "tty",
68 	.init		= tty_chan_init,
69 	.open		= tty_open,
70 	.close		= generic_close,
71 	.read		= generic_read,
72 	.write		= generic_write,
73 	.console_write	= generic_console_write,
74 	.window_size	= generic_window_size,
75 	.free		= generic_free,
76 	.winch		= 0,
77 };
78