]>
Commit | Line | Data |
---|---|---|
63376d7d DL |
1 | /* |
2 | * lxc: linux Container library | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2007, 2010 | |
5 | * | |
6 | * Authors: | |
9afe19d6 | 7 | * Daniel Lezcano <daniel.lezcano at free.fr> |
63376d7d DL |
8 | * |
9 | * This library is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License as published by the Free Software Foundation; either | |
12 | * version 2.1 of the License, or (at your option) any later version. | |
13 | * | |
14 | * This library is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | * Lesser General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU Lesser General Public | |
20 | * License along with this library; if not, write to the Free Software | |
250b1eec | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
63376d7d DL |
22 | */ |
23 | ||
e9a55b51 CB |
24 | #ifndef __LXC_TERMINAL_H |
25 | #define __LXC_TERMINAL_H | |
f1a4a029 | 26 | |
0519b5cc CB |
27 | #include <signal.h> |
28 | #include <stdio.h> | |
29 | ||
0d4137cc | 30 | #include "list.h" |
8c880e57 | 31 | #include "macro.h" |
13bb312d CB |
32 | #include "ringbuf.h" |
33 | ||
5b55021f | 34 | struct lxc_container; |
13bb312d | 35 | struct lxc_conf; |
5b55021f | 36 | struct lxc_epoll_descr; |
13bb312d | 37 | |
13bb312d | 38 | struct lxc_terminal_info { |
e9a55b51 | 39 | /* the path name of the slave side */ |
8c880e57 | 40 | char name[PATH_MAX]; |
e9a55b51 CB |
41 | |
42 | /* the file descriptor of the master */ | |
13bb312d | 43 | int master; |
e9a55b51 CB |
44 | |
45 | /* the file descriptor of the slave */ | |
13bb312d | 46 | int slave; |
e9a55b51 CB |
47 | |
48 | /* whether the terminal is currently used */ | |
13bb312d CB |
49 | int busy; |
50 | }; | |
51 | ||
5b55021f CB |
52 | struct lxc_terminal_state { |
53 | struct lxc_list node; | |
54 | int stdinfd; | |
55 | int stdoutfd; | |
56 | int masterfd; | |
e9a55b51 CB |
57 | |
58 | /* Escape sequence to use for exiting the terminal. A single char can | |
59 | * be specified. The terminal can then exited by doing: Ctrl + | |
60 | * specified_char + q. This field is checked by | |
61 | * lxc_terminal_stdin_cb(). Set to -1 to disable exiting the terminal | |
62 | * via a escape sequence. | |
5b55021f CB |
63 | */ |
64 | int escape; | |
e9a55b51 | 65 | |
5b55021f CB |
66 | /* Used internally by lxc_terminal_stdin_cb() to check whether an |
67 | * escape sequence has been received. | |
68 | */ | |
69 | int saw_escape; | |
e9a55b51 | 70 | |
5b55021f CB |
71 | /* File descriptor that accepts signals. If set to -1 no signal handler |
72 | * could be installed. This also means that the sigset_t oldmask member | |
73 | * is meaningless. | |
74 | */ | |
75 | int sigfd; | |
e9a55b51 | 76 | |
5b55021f CB |
77 | sigset_t oldmask; |
78 | }; | |
79 | ||
13bb312d CB |
80 | struct lxc_terminal { |
81 | int slave; | |
82 | int master; | |
83 | int peer; | |
fb87aa6a | 84 | struct lxc_terminal_info proxy; |
13bb312d CB |
85 | struct lxc_epoll_descr *descr; |
86 | char *path; | |
8c880e57 | 87 | char name[PATH_MAX]; |
13bb312d | 88 | struct termios *tios; |
5b55021f | 89 | struct lxc_terminal_state *tty_state; |
13bb312d | 90 | |
e9a55b51 | 91 | struct /* lxc_terminal_log */ { |
13bb312d CB |
92 | /* size of the log file */ |
93 | uint64_t log_size; | |
94 | ||
95 | /* path to the log file */ | |
96 | char *log_path; | |
97 | ||
98 | /* fd to the log file */ | |
99 | int log_fd; | |
100 | ||
101 | /* whether the log file will be rotated */ | |
102 | unsigned int log_rotate; | |
103 | }; | |
104 | ||
5b55021f | 105 | struct /* lxc_terminal_ringbuf */ { |
13bb312d CB |
106 | /* size of the ringbuffer */ |
107 | uint64_t buffer_size; | |
108 | ||
109 | /* the in-memory ringbuffer */ | |
110 | struct lxc_ringbuf ringbuf; | |
111 | }; | |
112 | }; | |
0d4137cc | 113 | |
e9a55b51 | 114 | /** |
c1ee47cd | 115 | * lxc_terminal_allocate: allocate the console or a tty |
22926b39 CB |
116 | * |
117 | * @conf : the configuration of the container to allocate from | |
118 | * @sockfd : the socket fd whose remote side when closed, will be an | |
119 | * indication that the console or tty is no longer in use | |
120 | * @ttyreq : the tty requested to be opened, -1 for any, 0 for the console | |
121 | */ | |
c1ee47cd | 122 | extern int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttynum); |
22926b39 | 123 | |
e9a55b51 CB |
124 | /** |
125 | * Create a new terminal: | |
126 | * - calls openpty() to allocate a master/slave pair | |
22926b39 | 127 | * - sets the FD_CLOEXEC flag on the master/slave fds |
e9a55b51 CB |
128 | * - allocates either the current controlling terminal (default) or a user |
129 | * specified terminal as proxy for the newly created master/slave pair | |
22926b39 CB |
130 | * - sets up SIGWINCH handler, winsz, and new terminal settings |
131 | * (Handlers for SIGWINCH and I/O are not registered in a mainloop.) | |
22926b39 | 132 | */ |
dcad02f8 | 133 | extern int lxc_terminal_create(struct lxc_terminal *console); |
5777fe90 CB |
134 | |
135 | /** | |
e9a55b51 CB |
136 | * lxc_terminal_setup: Create a new terminal. |
137 | * - In addition to lxc_terminal_create() also sets up logging. | |
5777fe90 | 138 | */ |
564e31c4 | 139 | extern int lxc_terminal_setup(struct lxc_conf *); |
22926b39 | 140 | |
e9a55b51 CB |
141 | /** |
142 | * Delete a terminal created via lxc_terminal_create() or lxc_terminal_setup(): | |
143 | * Note, registered handlers are not automatically deleted. | |
22926b39 | 144 | */ |
dcad02f8 | 145 | extern void lxc_terminal_delete(struct lxc_terminal *); |
22926b39 | 146 | |
e9a55b51 CB |
147 | /** |
148 | * lxc_terminal_free: mark the terminal as unallocated and free any resources | |
149 | * allocated by lxc_terminal_allocate(). | |
22926b39 CB |
150 | * |
151 | * @conf : the configuration of the container whose tty was closed | |
152 | * @fd : the socket fd whose remote side was closed, which indicated | |
e9a55b51 CB |
153 | * the terminal is no longer in use. this is used to match |
154 | * which terminal is being freed. | |
22926b39 | 155 | */ |
3dfe6f8d | 156 | extern void lxc_terminal_free(struct lxc_conf *conf, int fd); |
b5159817 | 157 | |
e9a55b51 CB |
158 | /** |
159 | * Register terminal event handlers in an open mainloop. | |
22926b39 | 160 | */ |
dcad02f8 | 161 | extern int lxc_terminal_mainloop_add(struct lxc_epoll_descr *, struct lxc_terminal *); |
22926b39 | 162 | |
e9a55b51 CB |
163 | /** |
164 | * Handle SIGWINCH events on the allocated terminals. | |
22926b39 | 165 | */ |
dad4a039 | 166 | extern void lxc_terminal_sigwinch(int sig); |
22926b39 | 167 | |
e9a55b51 CB |
168 | /** |
169 | * Connect to one of the ttys given to the container via lxc.tty.max. | |
170 | * - allocates either the current controlling terminal (default) or a user specified | |
171 | * terminal as proxy terminal for the containers tty | |
22926b39 CB |
172 | * - sets up SIGWINCH handler, winsz, and new terminal settings |
173 | * - opens mainloop | |
174 | * - registers SIGWINCH, I/O handlers in the mainloop | |
175 | * - performs all necessary cleanup operations | |
176 | */ | |
b5159817 DE |
177 | extern int lxc_console(struct lxc_container *c, int ttynum, |
178 | int stdinfd, int stdoutfd, int stderrfd, | |
179 | int escape); | |
22926b39 | 180 | |
e9a55b51 CB |
181 | /** |
182 | * Allocate one of the tty given to the container via lxc.tty.max. Returns an | |
183 | * open fd to the allocated tty. | |
184 | * Set ttynum to -1 to allocate the first available tty, or to a value within | |
185 | * the range specified by lxc.tty.max to allocate a specific tty. | |
22926b39 | 186 | */ |
e9a55b51 | 187 | extern int lxc_terminal_getfd(struct lxc_container *c, int *ttynum, |
b5159817 | 188 | int *masterfd); |
22926b39 | 189 | |
e9a55b51 CB |
190 | /** |
191 | * Make fd a duplicate of the standard file descriptors. The fd is made a | |
192 | * duplicate of a specific standard file descriptor iff the standard file | |
193 | * descriptor refers to a terminal. | |
22926b39 | 194 | */ |
ae6d3913 | 195 | extern int lxc_terminal_set_stdfds(int fd); |
22926b39 | 196 | |
e9a55b51 CB |
197 | /** |
198 | * Handler for events on the stdin fd of the terminal. To be registered via the | |
22926b39 | 199 | * corresponding functions declared and defined in mainloop.{c,h} or |
093bce5f | 200 | * lxc_terminal_mainloop_add(). |
22926b39 CB |
201 | * This function exits the loop cleanly when an EPOLLHUP event is received. |
202 | */ | |
52f9292f CB |
203 | extern int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata, |
204 | struct lxc_epoll_descr *descr); | |
22926b39 | 205 | |
e9a55b51 CB |
206 | /** |
207 | * Handler for events on the master fd of the terminal. To be registered via | |
208 | * the corresponding functions declared and defined in mainloop.{c,h} or | |
093bce5f | 209 | * lxc_terminal_mainloop_add(). |
22926b39 CB |
210 | * This function exits the loop cleanly when an EPOLLHUP event is received. |
211 | */ | |
ee9102ff CB |
212 | extern int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata, |
213 | struct lxc_epoll_descr *descr); | |
22926b39 | 214 | |
e9a55b51 | 215 | /** |
22926b39 CB |
216 | * Setup new terminal properties. The old terminal settings are stored in |
217 | * oldtios. | |
218 | */ | |
0d4137cc | 219 | extern int lxc_setup_tios(int fd, struct termios *oldtios); |
22926b39 CB |
220 | |
221 | ||
e9a55b51 | 222 | /** |
4e9c0330 | 223 | * lxc_terminal_winsz: propagate winsz from one terminal to another |
22926b39 | 224 | * |
e9a55b51 CB |
225 | * @srcfd |
226 | * - terminal to get size from (typically a slave pty) | |
227 | * @dstfd | |
228 | * - terminal to set size on (typically a master pty) | |
22926b39 | 229 | */ |
4e9c0330 | 230 | extern void lxc_terminal_winsz(int srcfd, int dstfd); |
22926b39 CB |
231 | |
232 | /* | |
dc8c7883 | 233 | * lxc_terminal_signal_init: install signal handler |
22926b39 | 234 | * |
e9a55b51 CB |
235 | * @srcfd |
236 | * - src for winsz in SIGWINCH handler | |
237 | * @dstfd | |
238 | * - dst for winsz in SIGWINCH handler | |
22926b39 | 239 | * |
e9a55b51 CB |
240 | * Returns lxc_terminal_state structure on success or NULL on failure. The |
241 | * sigfd member of the returned lxc_terminal_state can be | |
242 | * select()/poll()ed/epoll()ed on (i.e. added to a mainloop) for signals. | |
22926b39 | 243 | * |
e9a55b51 CB |
244 | * Must be called with process_lock held to protect the lxc_ttys list, or from |
245 | * a non-threaded context. | |
22926b39 | 246 | * |
f1e56364 | 247 | * Note that the signal handler isn't installed as a classic asynchronous |
0519b5cc CB |
248 | * handler, rather signalfd(2) is used so that we can handle the signal when |
249 | * we're ready for it. This avoids deadlocks since a signal handler (ie | |
dad4a039 | 250 | * lxc_terminal_sigwinch()) would need to take the thread mutex to prevent |
0519b5cc | 251 | * lxc_ttys list corruption, but using the fd we can provide the tty_state |
9bafc8cb | 252 | * needed to the callback (lxc_terminal_signalfd_cb()). |
22926b39 CB |
253 | * |
254 | * This function allocates memory. It is up to the caller to free it. | |
255 | */ | |
5b55021f | 256 | extern struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd); |
22926b39 | 257 | |
e9a55b51 | 258 | /** |
0519b5cc | 259 | * Handler for signal events. To be registered via the corresponding functions |
093bce5f | 260 | * declared and defined in mainloop.{c,h} or lxc_terminal_mainloop_add(). |
22926b39 | 261 | */ |
9bafc8cb | 262 | extern int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata, |
0519b5cc | 263 | struct lxc_epoll_descr *descr); |
22926b39 | 264 | |
e9a55b51 | 265 | /** |
a8867251 | 266 | * lxc_terminal_signal_fini: uninstall signal handler |
22926b39 | 267 | * |
e9a55b51 CB |
268 | * @ts |
269 | * - the lxc_terminal_state returned by lxc_terminal_signal_init | |
22926b39 CB |
270 | * |
271 | * Restore the saved signal handler that was in effect at the time | |
dc8c7883 | 272 | * lxc_terminal_signal_init() was called. |
22926b39 CB |
273 | * |
274 | * Must be called with process_lock held to protect the lxc_ttys list, or | |
275 | * from a non-threaded context. | |
276 | */ | |
5b55021f | 277 | extern void lxc_terminal_signal_fini(struct lxc_terminal_state *ts); |
f1a4a029 | 278 | |
e9a55b51 CB |
279 | extern int lxc_terminal_write_ringbuffer(struct lxc_terminal *terminal); |
280 | extern int lxc_terminal_create_log_file(struct lxc_terminal *terminal); | |
de708fb7 | 281 | extern int lxc_terminal_io_cb(int fd, uint32_t events, void *data, |
a529bc25 | 282 | struct lxc_epoll_descr *descr); |
63b74cda | 283 | |
cd0a2b2f | 284 | extern int lxc_make_controlling_terminal(int fd); |
d049f0e9 | 285 | extern int lxc_terminal_prepare_login(int fd); |
e9a55b51 CB |
286 | extern void lxc_terminal_conf_free(struct lxc_terminal *terminal); |
287 | extern void lxc_terminal_info_init(struct lxc_terminal_info *terminal); | |
288 | extern void lxc_terminal_init(struct lxc_terminal *terminal); | |
289 | extern int lxc_terminal_map_ids(struct lxc_conf *c, | |
290 | struct lxc_terminal *terminal); | |
e98affda | 291 | |
e9a55b51 | 292 | #endif /* __LXC_TERMINAL_H */ |