Blame view
arch/um/drivers/pty.c
3.11 KB
cb8fa61c2 uml: arch/um/driv... |
1 |
/* |
75886f21e uml: pty channel ... |
2 |
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 |
* Licensed under the GPL */ #include <stdio.h> |
24fa6c083 uml: move remaini... |
7 |
#include <stdlib.h> |
1da177e4c Linux-2.6.12-rc2 |
8 |
#include <unistd.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <errno.h> |
cb8fa61c2 uml: arch/um/driv... |
10 11 |
#include <fcntl.h> #include <string.h> |
1da177e4c Linux-2.6.12-rc2 |
12 |
#include <termios.h> |
75886f21e uml: pty channel ... |
13 |
#include <sys/stat.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include "chan_user.h" |
cb8fa61c2 uml: arch/um/driv... |
15 |
#include "os.h" |
c13e56907 [PATCH] uml: spli... |
16 |
#include "um_malloc.h" |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 20 21 22 23 24 |
struct pty_chan { void (*announce)(char *dev_name, int dev); int dev; int raw; struct termios tt; char dev_name[sizeof("/dev/pts/0123456\0")]; }; |
5e7672ec3 [PATCH] uml: cons... |
25 |
static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) |
1da177e4c Linux-2.6.12-rc2 |
26 27 |
{ struct pty_chan *data; |
43f5b3085 uml: fix build wh... |
28 |
data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); |
75886f21e uml: pty channel ... |
29 30 |
if (data == NULL) return NULL; |
cb8fa61c2 uml: arch/um/driv... |
31 |
*data = ((struct pty_chan) { .announce = opts->announce, |
1da177e4c Linux-2.6.12-rc2 |
32 33 |
.dev = device, .raw = opts->raw }); |
75886f21e uml: pty channel ... |
34 |
return data; |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 40 41 42 43 44 |
} static int pts_open(int input, int output, int primary, void *d, char **dev_out) { struct pty_chan *data = d; char *dev; int fd, err; fd = get_pty(); |
75886f21e uml: pty channel ... |
45 |
if (fd < 0) { |
b4fd310e1 [PATCH] uml: pres... |
46 |
err = -errno; |
75886f21e uml: pty channel ... |
47 48 |
printk(UM_KERN_ERR "open_pts : Failed to open pts "); |
b4fd310e1 [PATCH] uml: pres... |
49 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
50 |
} |
75886f21e uml: pty channel ... |
51 52 |
if (data->raw) { |
1da177e4c Linux-2.6.12-rc2 |
53 |
CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
75886f21e uml: pty channel ... |
54 |
if (err) |
e99525f97 uml: console subs... |
55 |
goto out_close; |
1da177e4c Linux-2.6.12-rc2 |
56 57 |
err = raw(fd); |
75886f21e uml: pty channel ... |
58 |
if (err) |
e99525f97 uml: console subs... |
59 |
goto out_close; |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 63 64 |
} dev = ptsname(fd); sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; |
75886f21e uml: pty channel ... |
65 |
|
1da177e4c Linux-2.6.12-rc2 |
66 67 |
if (data->announce) (*data->announce)(dev, data->dev); |
75886f21e uml: pty channel ... |
68 69 |
return fd; |
e99525f97 uml: console subs... |
70 71 72 73 |
out_close: close(fd); return err; |
1da177e4c Linux-2.6.12-rc2 |
74 75 76 77 |
} static int getmaster(char *line) { |
75886f21e uml: pty channel ... |
78 |
struct stat buf; |
1da177e4c Linux-2.6.12-rc2 |
79 80 81 82 83 84 85 |
char *pty, *bank, *cp; int master, err; pty = &line[strlen("/dev/ptyp")]; for (bank = "pqrs"; *bank; bank++) { line[strlen("/dev/pty")] = *bank; *pty = '0'; |
75886f21e uml: pty channel ... |
86 87 |
/* Did we hit the end ? */ if ((stat(line, &buf) < 0) && (errno == ENOENT)) |
1da177e4c Linux-2.6.12-rc2 |
88 |
break; |
75886f21e uml: pty channel ... |
89 |
|
1da177e4c Linux-2.6.12-rc2 |
90 91 |
for (cp = "0123456789abcdef"; *cp; cp++) { *pty = *cp; |
75886f21e uml: pty channel ... |
92 |
master = open(line, O_RDWR); |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 97 |
if (master >= 0) { char *tp = &line[strlen("/dev/")]; /* verify slave side is usable */ *tp = 't'; |
75886f21e uml: pty channel ... |
98 |
err = access(line, R_OK | W_OK); |
1da177e4c Linux-2.6.12-rc2 |
99 |
*tp = 'p'; |
cb8fa61c2 uml: arch/um/driv... |
100 |
if (!err) |
75886f21e uml: pty channel ... |
101 102 |
return master; close(master); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 |
} } } |
75886f21e uml: pty channel ... |
106 107 108 109 |
printk(UM_KERN_ERR "getmaster - no usable host pty devices "); return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 114 115 116 117 118 119 |
} static int pty_open(int input, int output, int primary, void *d, char **dev_out) { struct pty_chan *data = d; int fd, err; char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; fd = getmaster(dev); |
75886f21e uml: pty channel ... |
120 121 |
if (fd < 0) return fd; |
1da177e4c Linux-2.6.12-rc2 |
122 |
|
e99525f97 uml: console subs... |
123 |
if (data->raw) { |
1da177e4c Linux-2.6.12-rc2 |
124 |
err = raw(fd); |
e99525f97 uml: console subs... |
125 126 |
if (err) { close(fd); |
75886f21e uml: pty channel ... |
127 |
return err; |
e99525f97 uml: console subs... |
128 |
} |
1da177e4c Linux-2.6.12-rc2 |
129 |
} |
cb8fa61c2 uml: arch/um/driv... |
130 |
|
75886f21e uml: pty channel ... |
131 132 |
if (data->announce) (*data->announce)(dev, data->dev); |
1da177e4c Linux-2.6.12-rc2 |
133 134 135 |
sprintf(data->dev_name, "%s", dev); *dev_out = data->dev_name; |
75886f21e uml: pty channel ... |
136 137 |
return fd; |
1da177e4c Linux-2.6.12-rc2 |
138 |
} |
5e7672ec3 [PATCH] uml: cons... |
139 |
const struct chan_ops pty_ops = { |
1da177e4c Linux-2.6.12-rc2 |
140 141 142 143 144 145 |
.type = "pty", .init = pty_chan_init, .open = pty_open, .close = generic_close, .read = generic_read, .write = generic_write, |
fd9bc53b9 [PATCH] uml conso... |
146 |
.console_write = generic_console_write, |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 |
.window_size = generic_window_size, .free = generic_free, .winch = 0, }; |
5e7672ec3 [PATCH] uml: cons... |
151 |
const struct chan_ops pts_ops = { |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 155 156 157 |
.type = "pts", .init = pty_chan_init, .open = pts_open, .close = generic_close, .read = generic_read, .write = generic_write, |
fd9bc53b9 [PATCH] uml conso... |
158 |
.console_write = generic_console_write, |
1da177e4c Linux-2.6.12-rc2 |
159 160 161 162 |
.window_size = generic_window_size, .free = generic_free, .winch = 0, }; |