1 /* 2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 #include <termios.h> 10 #include <errno.h> 11 #include "user.h" 12 #include "chan_user.h" 13 #include "os.h" 14 #include "um_malloc.h" 15 16 struct fd_chan { 17 int fd; 18 int raw; 19 struct termios tt; 20 char str[sizeof("1234567890\0")]; 21 }; 22 23 static void *fd_init(char *str, int device, const struct chan_opts *opts) 24 { 25 struct fd_chan *data; 26 char *end; 27 int n; 28 29 if(*str != ':'){ 30 printk("fd_init : channel type 'fd' must specify a file " 31 "descriptor\n"); 32 return(NULL); 33 } 34 str++; 35 n = strtoul(str, &end, 0); 36 if((*end != '\0') || (end == str)){ 37 printk("fd_init : couldn't parse file descriptor '%s'\n", str); 38 return(NULL); 39 } 40 data = um_kmalloc(sizeof(*data)); 41 if(data == NULL) return(NULL); 42 *data = ((struct fd_chan) { .fd = n, 43 .raw = opts->raw }); 44 return(data); 45 } 46 47 static int fd_open(int input, int output, int primary, void *d, char **dev_out) 48 { 49 struct fd_chan *data = d; 50 int err; 51 52 if(data->raw && isatty(data->fd)){ 53 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); 54 if(err) 55 return(err); 56 57 err = raw(data->fd); 58 if(err) 59 return(err); 60 } 61 sprintf(data->str, "%d", data->fd); 62 *dev_out = data->str; 63 return(data->fd); 64 } 65 66 static void fd_close(int fd, void *d) 67 { 68 struct fd_chan *data = d; 69 int err; 70 71 if(data->raw && isatty(fd)){ 72 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); 73 if(err) 74 printk("Failed to restore terminal state - " 75 "errno = %d\n", -err); 76 data->raw = 0; 77 } 78 } 79 80 const struct chan_ops fd_ops = { 81 .type = "fd", 82 .init = fd_init, 83 .open = fd_open, 84 .close = fd_close, 85 .read = generic_read, 86 .write = generic_write, 87 .console_write = generic_console_write, 88 .window_size = generic_window_size, 89 .free = generic_free, 90 .winch = 1, 91 }; 92 93 /* 94 * Overrides for Emacs so that we follow Linus's tabbing style. 95 * Emacs will notice this stuff at the end of the file and automatically 96 * adjust the settings for this buffer only. This must remain at the end 97 * of the file. 98 * --------------------------------------------------------------------------- 99 * Local variables: 100 * c-file-style: "linux" 101 * End: 102 */ 103