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
xterm.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 <stddef.h>
7
#include <
stdio.h
>
8
#include <
stdlib.h
>
9
#include <unistd.h>
10
#include <errno.h>
11
#include <string.h>
12
#include <termios.h>
13
#include "
chan_user.h
"
14
#include <os.h>
15
#include <
um_malloc.h
>
16
#include "
xterm.h
"
17
18
struct
xterm_chan
{
19
int
pid
;
20
int
helper_pid
;
21
char
*
title
;
22
int
device
;
23
int
raw
;
24
struct
termios
tt
;
25
};
26
27
static
void
*xterm_init(
char
*
str
,
int
device
,
const
struct
chan_opts
*
opts
)
28
{
29
struct
xterm_chan
*
data
;
30
31
data =
uml_kmalloc
(
sizeof
(*data), UM_GFP_KERNEL);
32
if
(data ==
NULL
)
33
return
NULL
;
34
*data = ((
struct
xterm_chan
) { .pid = -1,
35
.helper_pid = -1,
36
.device =
device
,
37
.title = opts->
xterm_title
,
38
.raw = opts->
raw
} );
39
return
data
;
40
}
41
42
/* Only changed by xterm_setup, which is a setup */
43
static
char
*terminal_emulator =
"xterm"
;
44
static
char
*title_switch =
"-T"
;
45
static
char
*exec_switch =
"-e"
;
46
47
static
int
__init
xterm_setup(
char
*
line
,
int
*
add
)
48
{
49
*add = 0;
50
terminal_emulator = line;
51
52
line =
strchr
(line,
','
);
53
if
(line ==
NULL
)
54
return
0;
55
56
*line++ =
'\0'
;
57
if
(*line)
58
title_switch = line;
59
60
line =
strchr
(line,
','
);
61
if
(line ==
NULL
)
62
return
0;
63
64
*line++ =
'\0'
;
65
if
(*line)
66
exec_switch = line;
67
68
return
0;
69
}
70
71
__uml_setup
(
"xterm="
, xterm_setup,
72
"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
73
" Specifies an alternate terminal emulator to use for the debugger,\n"
74
" consoles, and serial lines when they are attached to the xterm channel.\n"
75
" The values are the terminal emulator binary, the switch it uses to set\n"
76
" its title, and the switch it uses to execute a subprocess,\n"
77
" respectively. The title switch must have the form '<switch> title',\n"
78
" not '<switch>=title'. Similarly, the exec switch must have the form\n"
79
" '<switch> command arg1 arg2 ...'.\n"
80
" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n"
81
" are 'xterm=gnome-terminal,-t,-x'.\n\n"
82
);
83
84
static
int
xterm_open(
int
input
,
int
output,
int
primary
,
void
*
d
,
85
char
**dev_out)
86
{
87
struct
xterm_chan
*data =
d
;
88
int
pid
,
fd
,
new
,
err
;
89
char
title
[256],
file
[] =
"/tmp/xterm-pipeXXXXXX"
;
90
char
*argv[] = { terminal_emulator, title_switch,
title
, exec_switch,
91
OS_LIB_PATH
"/uml/port-helper"
,
"-uml-socket"
,
92
file
,
NULL
};
93
94
if
(
access
(argv[4], X_OK) < 0)
95
argv[4] =
"port-helper"
;
96
97
/*
98
* Check that DISPLAY is set, this doesn't guarantee the xterm
99
* will work but w/o it we can be pretty sure it won't.
100
*/
101
if
(getenv(
"DISPLAY"
) ==
NULL
) {
102
printk
(
UM_KERN_ERR
"xterm_open: $DISPLAY not set.\n"
);
103
return
-
ENODEV
;
104
}
105
106
/*
107
* This business of getting a descriptor to a temp file,
108
* deleting the file and closing the descriptor is just to get
109
* a known-unused name for the Unix socket that we really
110
* want.
111
*/
112
fd = mkstemp(file);
113
if
(fd < 0) {
114
err = -
errno
;
115
printk
(
UM_KERN_ERR
"xterm_open : mkstemp failed, errno = %d\n"
,
116
errno);
117
return
err
;
118
}
119
120
if
(unlink(file)) {
121
err = -
errno
;
122
printk
(
UM_KERN_ERR
"xterm_open : unlink failed, errno = %d\n"
,
123
errno);
124
close(fd);
125
return
err
;
126
}
127
close(fd);
128
129
fd =
os_create_unix_socket
(file,
sizeof
(file), 1);
130
if
(fd < 0) {
131
printk
(
UM_KERN_ERR
"xterm_open : create_unix_socket failed, "
132
"errno = %d\n"
, -fd);
133
return
fd
;
134
}
135
136
sprintf
(title, data->
title
, data->
device
);
137
pid =
run_helper
(
NULL
,
NULL
, argv);
138
if
(pid < 0) {
139
err =
pid
;
140
printk
(
UM_KERN_ERR
"xterm_open : run_helper failed, "
141
"errno = %d\n"
, -err);
142
goto
out_close1;
143
}
144
145
err =
os_set_fd_block
(fd, 0);
146
if
(err < 0) {
147
printk
(
UM_KERN_ERR
"xterm_open : failed to set descriptor "
148
"non-blocking, err = %d\n"
, -err);
149
goto
out_kill;
150
}
151
152
new
=
xterm_fd
(fd, &data->
helper_pid
);
153
if
(
new
< 0) {
154
err =
new
;
155
printk
(
UM_KERN_ERR
"xterm_open : os_rcv_fd failed, err = %d\n"
,
156
-err);
157
goto
out_kill;
158
}
159
160
err =
os_set_fd_block
(
new
, 0);
161
if
(err) {
162
printk
(
UM_KERN_ERR
"xterm_open : failed to set xterm "
163
"descriptor non-blocking, err = %d\n"
, -err);
164
goto
out_close2;
165
}
166
167
CATCH_EINTR
(err = tcgetattr(
new
, &data->
tt
));
168
if
(err) {
169
new
=
err
;
170
goto
out_close2;
171
}
172
173
if
(data->
raw
) {
174
err =
raw
(
new
);
175
if
(err) {
176
new
=
err
;
177
goto
out_close2;
178
}
179
}
180
181
unlink(file);
182
data->
pid
=
pid
;
183
*dev_out =
NULL
;
184
185
return
new
;
186
187
out_close2:
188
close(
new
);
189
out_kill:
190
os_kill_process
(pid, 1);
191
out_close1:
192
close(fd);
193
194
return
err
;
195
}
196
197
static
void
xterm_close(
int
fd,
void
*d)
198
{
199
struct
xterm_chan
*data =
d
;
200
201
if
(data->
pid
!= -1)
202
os_kill_process
(data->
pid
, 1);
203
data->
pid
= -1;
204
205
if
(data->
helper_pid
!= -1)
206
os_kill_process
(data->
helper_pid
, 0);
207
data->
helper_pid
= -1;
208
209
os_close_file
(fd);
210
}
211
212
const
struct
chan_ops
xterm_ops
= {
213
.type =
"xterm"
,
214
.init = xterm_init,
215
.open = xterm_open,
216
.close = xterm_close,
217
.read =
generic_read
,
218
.write =
generic_write
,
219
.console_write =
generic_console_write
,
220
.window_size =
generic_window_size
,
221
.free =
generic_free
,
222
.winch = 1,
223
};
Generated on Thu Jan 10 2013 13:19:28 for Linux Kernel by
1.8.2