Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 162 lines 3.4 kB view raw
1/* 2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6#include <stdio.h> 7#include <unistd.h> 8#include <string.h> 9#include <errno.h> 10#include <termios.h> 11#include "chan_user.h" 12#include "user.h" 13#include "user_util.h" 14#include "kern_util.h" 15#include "os.h" 16 17struct pty_chan { 18 void (*announce)(char *dev_name, int dev); 19 int dev; 20 int raw; 21 struct termios tt; 22 char dev_name[sizeof("/dev/pts/0123456\0")]; 23}; 24 25static void *pty_chan_init(char *str, int device, struct chan_opts *opts) 26{ 27 struct pty_chan *data; 28 29 data = um_kmalloc(sizeof(*data)); 30 if(data == NULL) return(NULL); 31 *data = ((struct pty_chan) { .announce = opts->announce, 32 .dev = device, 33 .raw = opts->raw }); 34 return(data); 35} 36 37static int pts_open(int input, int output, int primary, void *d, 38 char **dev_out) 39{ 40 struct pty_chan *data = d; 41 char *dev; 42 int fd, err; 43 44 fd = get_pty(); 45 if(fd < 0){ 46 printk("open_pts : Failed to open pts\n"); 47 return(-errno); 48 } 49 if(data->raw){ 50 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 51 if(err) 52 return(err); 53 54 err = raw(fd); 55 if(err) 56 return(err); 57 } 58 59 dev = ptsname(fd); 60 sprintf(data->dev_name, "%s", dev); 61 *dev_out = data->dev_name; 62 if (data->announce) 63 (*data->announce)(dev, data->dev); 64 return(fd); 65} 66 67static int getmaster(char *line) 68{ 69 char *pty, *bank, *cp; 70 int master, err; 71 72 pty = &line[strlen("/dev/ptyp")]; 73 for (bank = "pqrs"; *bank; bank++) { 74 line[strlen("/dev/pty")] = *bank; 75 *pty = '0'; 76 if (os_stat_file(line, NULL) < 0) 77 break; 78 for (cp = "0123456789abcdef"; *cp; cp++) { 79 *pty = *cp; 80 master = os_open_file(line, of_rdwr(OPENFLAGS()), 0); 81 if (master >= 0) { 82 char *tp = &line[strlen("/dev/")]; 83 84 /* verify slave side is usable */ 85 *tp = 't'; 86 err = os_access(line, OS_ACC_RW_OK); 87 *tp = 'p'; 88 if(err == 0) return(master); 89 (void) os_close_file(master); 90 } 91 } 92 } 93 return(-1); 94} 95 96static int pty_open(int input, int output, int primary, void *d, 97 char **dev_out) 98{ 99 struct pty_chan *data = d; 100 int fd, err; 101 char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; 102 103 fd = getmaster(dev); 104 if(fd < 0) 105 return(-errno); 106 107 if(data->raw){ 108 err = raw(fd); 109 if(err) 110 return(err); 111 } 112 113 if(data->announce) (*data->announce)(dev, data->dev); 114 115 sprintf(data->dev_name, "%s", dev); 116 *dev_out = data->dev_name; 117 return(fd); 118} 119 120static int pty_console_write(int fd, const char *buf, int n, void *d) 121{ 122 struct pty_chan *data = d; 123 124 return(generic_console_write(fd, buf, n, &data->tt)); 125} 126 127struct chan_ops pty_ops = { 128 .type = "pty", 129 .init = pty_chan_init, 130 .open = pty_open, 131 .close = generic_close, 132 .read = generic_read, 133 .write = generic_write, 134 .console_write = pty_console_write, 135 .window_size = generic_window_size, 136 .free = generic_free, 137 .winch = 0, 138}; 139 140struct chan_ops pts_ops = { 141 .type = "pts", 142 .init = pty_chan_init, 143 .open = pts_open, 144 .close = generic_close, 145 .read = generic_read, 146 .write = generic_write, 147 .console_write = pty_console_write, 148 .window_size = generic_window_size, 149 .free = generic_free, 150 .winch = 0, 151}; 152 153/* 154 * Overrides for Emacs so that we follow Linus's tabbing style. 155 * Emacs will notice this stuff at the end of the file and automatically 156 * adjust the settings for this buffer only. This must remain at the end 157 * of the file. 158 * --------------------------------------------------------------------------- 159 * Local variables: 160 * c-file-style: "linux" 161 * End: 162 */