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