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