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
port_user.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3
* Licensed under the GPL
4
*/
5
6
#include <
stdio.h
>
7
#include <
stdlib.h
>
8
#include <errno.h>
9
#include <termios.h>
10
#include <unistd.h>
11
#include <netinet/in.h>
12
#include "
chan_user.h
"
13
#include <os.h>
14
#include "
port.h
"
15
#include <
um_malloc.h
>
16
17
struct
port_chan
{
18
int
raw
;
19
struct
termios
tt
;
20
void
*
kernel_data
;
21
char
dev
[
sizeof
(
"32768\0"
)];
22
};
23
24
static
void
*
port_init
(
char
*
str
,
int
device
,
const
struct
chan_opts
*
opts
)
25
{
26
struct
port_chan
*
data
;
27
void
*kern_data;
28
char
*
end
;
29
int
port
;
30
31
if
(*str !=
':'
) {
32
printk
(
UM_KERN_ERR
"port_init : channel type 'port' must "
33
"specify a port number\n"
);
34
return
NULL
;
35
}
36
str++;
37
port = strtoul(str, &end, 0);
38
if
((*end !=
'\0'
) || (end == str)) {
39
printk
(
UM_KERN_ERR
"port_init : couldn't parse port '%s'\n"
,
40
str);
41
return
NULL
;
42
}
43
44
kern_data =
port_data
(port);
45
if
(kern_data ==
NULL
)
46
return
NULL
;
47
48
data =
uml_kmalloc
(
sizeof
(*data), UM_GFP_KERNEL);
49
if
(data ==
NULL
)
50
goto
err
;
51
52
*data = ((
struct
port_chan
) { .raw = opts->
raw
,
53
.kernel_data = kern_data });
54
sprintf
(data->
dev
,
"%d"
, port);
55
56
return
data
;
57
err
:
58
port_kern_free
(kern_data);
59
return
NULL
;
60
}
61
62
static
void
port_free(
void
*
d
)
63
{
64
struct
port_chan
*data =
d
;
65
66
port_kern_free
(data->
kernel_data
);
67
kfree
(data);
68
}
69
70
static
int
port_open(
int
input
,
int
output,
int
primary
,
void
*
d
,
71
char
**dev_out)
72
{
73
struct
port_chan
*data =
d
;
74
int
fd
,
err
;
75
76
fd =
port_wait
(data->
kernel_data
);
77
if
((fd >= 0) && data->
raw
) {
78
CATCH_EINTR
(err = tcgetattr(fd, &data->
tt
));
79
if
(err)
80
return
err
;
81
82
err =
raw
(fd);
83
if
(err)
84
return
err
;
85
}
86
*dev_out = data->
dev
;
87
return
fd
;
88
}
89
90
static
void
port_close(
int
fd,
void
*d)
91
{
92
struct
port_chan
*data =
d
;
93
94
port_remove_dev
(data->
kernel_data
);
95
os_close_file
(fd);
96
}
97
98
const
struct
chan_ops
port_ops
= {
99
.type =
"port"
,
100
.init =
port_init
,
101
.open = port_open,
102
.close = port_close,
103
.read =
generic_read
,
104
.write =
generic_write
,
105
.console_write =
generic_console_write
,
106
.window_size =
generic_window_size
,
107
.free = port_free,
108
.winch = 1,
109
};
110
111
int
port_listen_fd
(
int
port)
112
{
113
struct
sockaddr_in
addr;
114
int
fd
,
err
,
arg
;
115
116
fd =
socket
(
PF_INET
,
SOCK_STREAM
, 0);
117
if
(fd == -1)
118
return
-
errno
;
119
120
arg = 1;
121
if
(setsockopt(fd,
SOL_SOCKET
,
SO_REUSEADDR
, &arg,
sizeof
(arg)) < 0) {
122
err = -
errno
;
123
goto
out
;
124
}
125
126
addr.
sin_family
=
AF_INET
;
127
addr.
sin_port
=
htons
(port);
128
addr.
sin_addr
.s_addr =
htonl
(
INADDR_ANY
);
129
if
(bind(fd, (
struct
sockaddr
*) &addr,
sizeof
(addr)) < 0) {
130
err = -
errno
;
131
goto
out
;
132
}
133
134
if
(listen(fd, 1) < 0) {
135
err = -
errno
;
136
goto
out
;
137
}
138
139
err =
os_set_fd_block
(fd, 0);
140
if
(err < 0)
141
goto
out
;
142
143
return
fd
;
144
out
:
145
close(fd);
146
return
err
;
147
}
148
149
struct
port_pre_exec_data
{
150
int
sock_fd
;
151
int
pipe_fd
;
152
};
153
154
static
void
port_pre_exec(
void
*
arg
)
155
{
156
struct
port_pre_exec_data
*data =
arg
;
157
158
dup2(data->
sock_fd
, 0);
159
dup2(data->
sock_fd
, 1);
160
dup2(data->
sock_fd
, 2);
161
close(data->
sock_fd
);
162
dup2(data->
pipe_fd
, 3);
163
shutdown
(3,
SHUT_RD
);
164
close(data->
pipe_fd
);
165
}
166
167
int
port_connection
(
int
fd,
int
*
socket
,
int
*pid_out)
168
{
169
int
new
,
err
;
170
char
*argv[] = {
"/usr/sbin/in.telnetd"
,
"-L"
,
171
"/usr/lib/uml/port-helper"
,
NULL
};
172
struct
port_pre_exec_data
data;
173
174
new
= accept(fd,
NULL
, 0);
175
if
(
new
< 0)
176
return
-
errno
;
177
178
err =
os_pipe
(socket, 0, 0);
179
if
(err < 0)
180
goto
out_close;
181
182
data = ((
struct
port_pre_exec_data
)
183
{ .sock_fd =
new
,
184
.pipe_fd = socket[1] });
185
186
err =
run_helper
(port_pre_exec, &data, argv);
187
if
(err < 0)
188
goto
out_shutdown;
189
190
*pid_out =
err
;
191
return
new
;
192
193
out_shutdown:
194
shutdown
(socket[0],
SHUT_RDWR
);
195
close(socket[0]);
196
shutdown
(socket[1],
SHUT_RDWR
);
197
close(socket[1]);
198
out_close:
199
close(
new
);
200
return
err
;
201
}
Generated on Thu Jan 10 2013 13:19:21 for Linux Kernel by
1.8.2