1 /* SPDX-License-Identifier: LGPL-2.1+ */
11 #include <sys/epoll.h>
12 #include <sys/types.h>
25 #include "memory_utils.h"
26 #include "open_utils.h"
28 #include "syscall_wrappers.h"
38 #define LXC_TERMINAL_BUFFER_SIZE 1024
40 lxc_log_define(terminal
, lxc
);
42 void lxc_terminal_winsz(int srcfd
, int dstfd
)
50 ret
= ioctl(srcfd
, TIOCGWINSZ
, &wsz
);
52 WARN("Failed to get window size");
56 ret
= ioctl(dstfd
, TIOCSWINSZ
, &wsz
);
58 WARN("Failed to set window size");
60 DEBUG("Set window size to %d columns and %d rows", wsz
.ws_col
,
66 static void lxc_terminal_winch(struct lxc_terminal_state
*ts
)
68 lxc_terminal_winsz(ts
->stdinfd
, ts
->ptxfd
);
71 int lxc_terminal_signalfd_cb(int fd
, uint32_t events
, void *cbdata
,
72 struct lxc_async_descr
*descr
)
75 struct signalfd_siginfo siginfo
;
76 struct lxc_terminal_state
*ts
= cbdata
;
78 ret
= lxc_read_nointr(fd
, &siginfo
, sizeof(siginfo
));
79 if (ret
< 0 || (size_t)ret
< sizeof(siginfo
)) {
80 ERROR("Failed to read signal info");
81 return LXC_MAINLOOP_ERROR
;
84 if (siginfo
.ssi_signo
== SIGTERM
) {
85 DEBUG("Received SIGTERM. Detaching from the terminal");
86 return LXC_MAINLOOP_CLOSE
;
89 if (siginfo
.ssi_signo
== SIGWINCH
)
90 lxc_terminal_winch(ts
);
92 return LXC_MAINLOOP_CONTINUE
;
95 struct lxc_terminal_state
*lxc_terminal_signal_init(int srcfd
, int dstfd
)
97 __do_close
int signal_fd
= -EBADF
;
98 __do_free
struct lxc_terminal_state
*ts
= NULL
;
102 ts
= malloc(sizeof(*ts
));
106 memset(ts
, 0, sizeof(*ts
));
111 ret
= sigemptyset(&mask
);
113 SYSERROR("Failed to initialize an empty signal set");
118 ret
= sigaddset(&mask
, SIGWINCH
);
120 SYSNOTICE("Failed to add SIGWINCH to signal set");
122 INFO("fd %d does not refer to a tty device", srcfd
);
125 /* Exit the mainloop cleanly on SIGTERM. */
126 ret
= sigaddset(&mask
, SIGTERM
);
128 SYSERROR("Failed to add SIGWINCH to signal set");
132 ret
= pthread_sigmask(SIG_BLOCK
, &mask
, &ts
->oldmask
);
134 WARN("Failed to block signals");
138 signal_fd
= signalfd(-1, &mask
, SFD_CLOEXEC
);
140 WARN("Failed to create signal fd");
141 (void)pthread_sigmask(SIG_SETMASK
, &ts
->oldmask
, NULL
);
144 ts
->sigfd
= move_fd(signal_fd
);
145 TRACE("Created signal fd %d", ts
->sigfd
);
150 int lxc_terminal_signal_sigmask_safe_blocked(struct lxc_terminal
*terminal
)
152 struct lxc_terminal_state
*state
= terminal
->tty_state
;
157 return pthread_sigmask(SIG_SETMASK
, &state
->oldmask
, NULL
);
161 * lxc_terminal_signal_fini: uninstall signal handler
163 * @terminal: terminal instance
165 * Restore the saved signal handler that was in effect at the time
166 * lxc_terminal_signal_init() was called.
168 static void lxc_terminal_signal_fini(struct lxc_terminal
*terminal
)
170 struct lxc_terminal_state
*state
= terminal
->tty_state
;
172 if (!terminal
->tty_state
)
175 state
= terminal
->tty_state
;
176 if (state
->sigfd
>= 0) {
179 if (pthread_sigmask(SIG_SETMASK
, &state
->oldmask
, NULL
) < 0)
180 SYSWARN("Failed to restore signal mask");
183 free(terminal
->tty_state
);
184 terminal
->tty_state
= NULL
;
187 static int lxc_terminal_truncate_log_file(struct lxc_terminal
*terminal
)
189 /* be very certain things are kosher */
190 if (!terminal
->log_path
|| terminal
->log_fd
< 0)
193 return lxc_unpriv(ftruncate(terminal
->log_fd
, 0));
196 static int lxc_terminal_rotate_log_file(struct lxc_terminal
*terminal
)
198 __do_free
char *tmp
= NULL
;
202 if (!terminal
->log_path
|| terminal
->log_rotate
== 0)
205 /* be very certain things are kosher */
206 if (terminal
->log_fd
< 0)
209 len
= strlen(terminal
->log_path
) + sizeof(".1");
210 tmp
= must_realloc(NULL
, len
);
212 ret
= strnprintf(tmp
, len
, "%s.1", terminal
->log_path
);
216 close(terminal
->log_fd
);
217 terminal
->log_fd
= -1;
218 ret
= lxc_unpriv(rename(terminal
->log_path
, tmp
));
222 return lxc_terminal_create_log_file(terminal
);
225 static int lxc_terminal_write_log_file(struct lxc_terminal
*terminal
, char *buf
,
230 int64_t space_left
= -1;
232 if (terminal
->log_fd
< 0)
235 /* A log size <= 0 means that there's no limit on the size of the log
236 * file at which point we simply ignore whether the log is supposed to
239 if (terminal
->log_size
<= 0)
240 return lxc_write_nointr(terminal
->log_fd
, buf
, bytes_read
);
242 /* Get current size of the log file. */
243 ret
= fstat(terminal
->log_fd
, &st
);
245 SYSERROR("Failed to stat the terminal log file descriptor");
249 /* handle non-regular files */
250 if ((st
.st_mode
& S_IFMT
) != S_IFREG
) {
251 /* This isn't a regular file. so rotating the file seems a
252 * dangerous thing to do, size limits are also very
253 * questionable. Let's not risk anything and tell the user that
254 * they're requesting us to do weird stuff.
256 if (terminal
->log_rotate
> 0 || terminal
->log_size
> 0)
259 /* I mean, sure log wherever you want to. */
260 return lxc_write_nointr(terminal
->log_fd
, buf
, bytes_read
);
263 space_left
= terminal
->log_size
- st
.st_size
;
265 /* User doesn't want to rotate the log file and there's no more space
266 * left so simply truncate it.
268 if (space_left
<= 0 && terminal
->log_rotate
<= 0) {
269 ret
= lxc_terminal_truncate_log_file(terminal
);
273 if ((uint64_t)bytes_read
<= terminal
->log_size
)
274 return lxc_write_nointr(terminal
->log_fd
, buf
, bytes_read
);
276 /* Write as much as we can into the buffer and loose the rest. */
277 return lxc_write_nointr(terminal
->log_fd
, buf
, terminal
->log_size
);
280 /* There's enough space left. */
281 if (bytes_read
<= space_left
)
282 return lxc_write_nointr(terminal
->log_fd
, buf
, bytes_read
);
284 /* There's not enough space left but at least write as much as we can
285 * into the old log file.
287 ret
= lxc_write_nointr(terminal
->log_fd
, buf
, space_left
);
291 /* Calculate how many bytes we still need to write. */
292 bytes_read
-= space_left
;
294 /* There'd be more to write but we aren't instructed to rotate the log
295 * file so simply return. There's no error on our side here.
297 if (terminal
->log_rotate
> 0)
298 ret
= lxc_terminal_rotate_log_file(terminal
);
300 ret
= lxc_terminal_truncate_log_file(terminal
);
304 if (terminal
->log_size
< (uint64_t)bytes_read
) {
305 /* Well, this is unfortunate because it means that there is more
306 * to write than the user has granted us space. There are
307 * multiple ways to handle this but let's use the simplest one:
308 * write as much as we can, tell the user that there was more
309 * stuff to write and move on.
310 * Note that this scenario shouldn't actually happen with the
311 * standard pty-based terminal that LXC allocates since it will
312 * be switched into raw mode. In raw mode only 1 byte at a time
313 * should be read and written.
315 WARN("Size of terminal log file is smaller than the bytes to write");
316 ret
= lxc_write_nointr(terminal
->log_fd
, buf
, terminal
->log_size
);
323 /* Yay, we made it. */
324 ret
= lxc_write_nointr(terminal
->log_fd
, buf
, bytes_read
);
331 static int lxc_terminal_ptx_io(struct lxc_terminal
*terminal
)
333 char buf
[LXC_TERMINAL_BUFFER_SIZE
];
334 int r
, w
, w_log
, w_rbuf
;
336 w
= r
= lxc_read_nointr(terminal
->ptx
, buf
, sizeof(buf
));
338 if (errno
== EWOULDBLOCK
)
344 /* write to peer first */
345 if (terminal
->peer
>= 0)
346 w
= lxc_write_nointr(terminal
->peer
, buf
, r
);
348 /* write to terminal ringbuffer */
349 if (terminal
->buffer_size
> 0)
350 w_rbuf
= lxc_ringbuf_write(&terminal
->ringbuf
, buf
, r
);
352 /* write to terminal log */
353 if (terminal
->log_fd
>= 0)
354 w_log
= lxc_terminal_write_log_file(terminal
, buf
, r
);
357 WARN("Short write on terminal r:%d != w:%d", r
, w
);
361 SYSTRACE("Failed to write %d bytes to terminal ringbuffer", r
);
365 TRACE("Failed to write %d bytes to terminal log", r
);
370 static int lxc_terminal_peer_io(struct lxc_terminal
*terminal
)
372 char buf
[LXC_TERMINAL_BUFFER_SIZE
];
375 w
= r
= lxc_read_nointr(terminal
->peer
, buf
, sizeof(buf
));
377 if (errno
== EWOULDBLOCK
)
383 w
= lxc_write_nointr(terminal
->ptx
, buf
, r
);
385 WARN("Short write on terminal r:%d != w:%d", r
, w
);
390 static int lxc_terminal_ptx_io_handler(int fd
, uint32_t events
, void *data
,
391 struct lxc_async_descr
*descr
)
393 struct lxc_terminal
*terminal
= data
;
396 ret
= lxc_terminal_ptx_io(data
);
398 return log_info(LXC_MAINLOOP_CLOSE
,
399 "Terminal client on fd %d has exited",
402 return LXC_MAINLOOP_CONTINUE
;
405 static int lxc_terminal_peer_io_handler(int fd
, uint32_t events
, void *data
,
406 struct lxc_async_descr
*descr
)
408 struct lxc_terminal
*terminal
= data
;
411 ret
= lxc_terminal_peer_io(data
);
413 return log_info(LXC_MAINLOOP_CLOSE
,
414 "Terminal client on fd %d has exited",
417 return LXC_MAINLOOP_CONTINUE
;
420 static int lxc_terminal_mainloop_add_peer(struct lxc_terminal
*terminal
)
424 if (terminal
->peer
>= 0) {
425 if (fd_make_nonblocking(terminal
->peer
))
426 return log_error_errno(-1, errno
, "Failed to make terminal peer fd non-blocking");
428 ret
= lxc_mainloop_add_handler(terminal
->descr
, terminal
->peer
,
429 lxc_terminal_peer_io_handler
,
430 default_cleanup_handler
,
431 terminal
, "lxc_terminal_peer_io_handler");
433 WARN("Failed to add terminal peer handler to mainloop");
438 if (!terminal
->tty_state
|| terminal
->tty_state
->sigfd
< 0)
441 ret
= lxc_mainloop_add_handler(terminal
->descr
,
442 terminal
->tty_state
->sigfd
,
443 lxc_terminal_signalfd_cb
,
444 default_cleanup_handler
,
446 "lxc_terminal_signalfd_cb");
448 WARN("Failed to add signal handler to mainloop");
455 int lxc_terminal_mainloop_add(struct lxc_async_descr
*descr
,
456 struct lxc_terminal
*terminal
)
460 if (terminal
->ptx
< 0) {
461 INFO("Terminal is not initialized");
465 if (fd_make_nonblocking(terminal
->ptx
))
466 return log_error_errno(-1, errno
, "Failed to make terminal ptx fd non-blocking");
468 ret
= lxc_mainloop_add_handler(descr
, terminal
->ptx
,
469 lxc_terminal_ptx_io_handler
,
470 default_cleanup_handler
,
471 terminal
, "lxc_terminal_ptx_io_handler");
473 ERROR("Failed to add handler for terminal ptx fd %d to mainloop", terminal
->ptx
);
477 /* We cache the descr so that we can add an fd to it when someone
478 * does attach to it in lxc_terminal_allocate().
480 terminal
->descr
= descr
;
482 return lxc_terminal_mainloop_add_peer(terminal
);
485 int lxc_setup_tios(int fd
, struct termios
*oldtios
)
488 struct termios newtios
;
491 ERROR("File descriptor %d does not refer to a terminal", fd
);
495 /* Get current termios. */
496 ret
= tcgetattr(fd
, oldtios
);
498 SYSERROR("Failed to get current terminal settings");
502 /* ensure we don't end up in an endless loop:
503 * The kernel might fire SIGTTOU while an
504 * ioctl() in tcsetattr() is executed. When the ioctl()
505 * is resumed and retries, the signal handler interrupts it again.
507 signal (SIGTTIN
, SIG_IGN
);
508 signal (SIGTTOU
, SIG_IGN
);
512 /* We use the same settings that ssh does. */
513 newtios
.c_iflag
|= IGNPAR
;
514 newtios
.c_iflag
&= ~(ISTRIP
| INLCR
| IGNCR
| ICRNL
| IXON
| IXANY
| IXOFF
);
516 newtios
.c_iflag
&= ~IUCLC
;
518 newtios
.c_lflag
&= ~(TOSTOP
| ISIG
| ICANON
| ECHO
| ECHOE
| ECHOK
| ECHONL
);
520 newtios
.c_lflag
&= ~IEXTEN
;
522 newtios
.c_oflag
|= ONLCR
;
523 newtios
.c_oflag
|= OPOST
;
524 newtios
.c_cc
[VMIN
] = 1;
525 newtios
.c_cc
[VTIME
] = 0;
527 /* Set new attributes. */
528 ret
= tcsetattr(fd
, TCSAFLUSH
, &newtios
);
530 ERROR("Failed to set new terminal settings");
537 static void lxc_terminal_peer_proxy_free(struct lxc_terminal
*terminal
)
539 lxc_terminal_signal_fini(terminal
);
541 close(terminal
->proxy
.ptx
);
542 terminal
->proxy
.ptx
= -1;
544 close(terminal
->proxy
.pty
);
545 terminal
->proxy
.pty
= -1;
547 terminal
->proxy
.busy
= -1;
549 terminal
->proxy
.name
[0] = '\0';
554 static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal
*terminal
,
558 struct termios oldtermio
;
559 struct lxc_terminal_state
*ts
;
561 if (terminal
->ptx
< 0) {
562 ERROR("Terminal not set up");
566 if (terminal
->proxy
.busy
!= -1 || terminal
->peer
!= -1) {
567 NOTICE("Terminal already in use");
571 if (terminal
->tty_state
) {
572 ERROR("Terminal has already been initialized");
576 /* This is the proxy terminal that will be given to the client, and
577 * that the real terminal ptx will send to / recv from.
579 ret
= openpty(&terminal
->proxy
.ptx
, &terminal
->proxy
.pty
, NULL
,
582 SYSERROR("Failed to open proxy terminal");
586 ret
= ttyname_r(terminal
->proxy
.pty
, terminal
->proxy
.name
,
587 sizeof(terminal
->proxy
.name
));
589 SYSERROR("Failed to retrieve name of proxy terminal pty");
593 ret
= lxc_fd_cloexec(terminal
->proxy
.ptx
, true);
595 SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal ptx");
599 ret
= lxc_fd_cloexec(terminal
->proxy
.pty
, true);
601 SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal pty");
605 ret
= lxc_setup_tios(terminal
->proxy
.pty
, &oldtermio
);
609 ts
= lxc_terminal_signal_init(terminal
->proxy
.ptx
, terminal
->ptx
);
613 terminal
->tty_state
= ts
;
614 terminal
->peer
= terminal
->proxy
.pty
;
615 terminal
->proxy
.busy
= sockfd
;
616 ret
= lxc_terminal_mainloop_add_peer(terminal
);
620 NOTICE("Opened proxy terminal with ptx fd %d and pty fd %d",
621 terminal
->proxy
.ptx
, terminal
->proxy
.pty
);
625 lxc_terminal_peer_proxy_free(terminal
);
629 int lxc_terminal_allocate(struct lxc_conf
*conf
, int sockfd
, int *ttyreq
)
633 struct lxc_tty_info
*ttys
= &conf
->ttys
;
634 struct lxc_terminal
*terminal
= &conf
->console
;
639 ret
= lxc_terminal_peer_proxy_alloc(terminal
, sockfd
);
643 ptxfd
= terminal
->proxy
.ptx
;
648 if ((size_t)*ttyreq
> ttys
->max
)
651 if (ttys
->tty
[*ttyreq
- 1].busy
>= 0)
654 /* The requested tty is available. */
659 /* Search for next available tty, fixup index tty1 => [0]. */
660 for (ttynum
= 1; ttynum
<= ttys
->max
&& ttys
->tty
[ttynum
- 1].busy
>= 0; ttynum
++) {
664 /* We didn't find any available slot for tty. */
665 if (ttynum
> ttys
->max
)
668 *ttyreq
= (int)ttynum
;
671 ttys
->tty
[ttynum
- 1].busy
= sockfd
;
672 ptxfd
= ttys
->tty
[ttynum
- 1].ptx
;
678 void lxc_terminal_free(struct lxc_conf
*conf
, int fd
)
680 struct lxc_tty_info
*ttys
= &conf
->ttys
;
681 struct lxc_terminal
*terminal
= &conf
->console
;
683 for (size_t i
= 0; i
< ttys
->max
; i
++)
684 if (ttys
->tty
[i
].busy
== fd
)
685 ttys
->tty
[i
].busy
= -1;
687 if (terminal
->proxy
.busy
!= fd
)
690 lxc_mainloop_del_handler(terminal
->descr
, terminal
->proxy
.pty
);
691 lxc_terminal_peer_proxy_free(terminal
);
694 static int lxc_terminal_peer_default(struct lxc_terminal
*terminal
)
696 struct lxc_terminal_state
*ts
;
701 path
= terminal
->path
;
705 terminal
->peer
= lxc_unpriv(open(path
, O_RDWR
| O_CLOEXEC
));
706 if (terminal
->peer
< 0) {
707 if (!terminal
->path
) {
709 SYSDEBUG("The process does not have a controlling terminal");
713 SYSERROR("Failed to open proxy terminal \"%s\"", path
);
716 DEBUG("Using terminal \"%s\" as proxy", path
);
718 if (!isatty(terminal
->peer
)) {
719 ERROR("File descriptor for \"%s\" does not refer to a terminal", path
);
720 goto on_error_free_tios
;
723 ts
= lxc_terminal_signal_init(terminal
->peer
, terminal
->ptx
);
724 terminal
->tty_state
= ts
;
726 WARN("Failed to install signal handler");
727 goto on_error_free_tios
;
730 lxc_terminal_winsz(terminal
->peer
, terminal
->ptx
);
732 terminal
->tios
= malloc(sizeof(*terminal
->tios
));
734 goto on_error_free_tios
;
736 ret
= lxc_setup_tios(terminal
->peer
, terminal
->tios
);
738 goto on_error_close_peer
;
743 free(terminal
->tios
);
744 terminal
->tios
= NULL
;
747 close(terminal
->peer
);
755 int lxc_terminal_write_ringbuffer(struct lxc_terminal
*terminal
)
760 struct lxc_ringbuf
*buf
= &terminal
->ringbuf
;
762 /* There's not log file where we can dump the ringbuffer to. */
763 if (terminal
->log_fd
< 0)
766 used
= lxc_ringbuf_used(buf
);
770 ret
= lxc_terminal_truncate_log_file(terminal
);
774 /* Write as much as we can without exceeding the limit. */
775 if (terminal
->log_size
< used
)
776 used
= terminal
->log_size
;
778 r_addr
= lxc_ringbuf_get_read_addr(buf
);
779 ret
= lxc_write_nointr(terminal
->log_fd
, r_addr
, used
);
786 void lxc_terminal_delete(struct lxc_terminal
*terminal
)
790 ret
= lxc_terminal_write_ringbuffer(terminal
);
792 WARN("Failed to write terminal log to disk");
794 if (terminal
->tios
&& terminal
->peer
>= 0) {
795 ret
= tcsetattr(terminal
->peer
, TCSAFLUSH
, terminal
->tios
);
797 SYSWARN("Failed to set old terminal settings");
799 free(terminal
->tios
);
800 terminal
->tios
= NULL
;
802 if (terminal
->peer
>= 0)
803 close(terminal
->peer
);
806 if (terminal
->ptx
>= 0)
807 close(terminal
->ptx
);
810 if (terminal
->pty
>= 0)
811 close(terminal
->pty
);
814 terminal
->pty_nr
= -1;
816 if (terminal
->log_fd
>= 0)
817 close(terminal
->log_fd
);
818 terminal
->log_fd
= -1;
822 * Note that this function needs to run before the mainloop starts. Since we
823 * register a handler for the terminal's ptxfd when we create the mainloop
824 * the terminal handler needs to see an allocated ringbuffer.
826 static int lxc_terminal_create_ringbuf(struct lxc_terminal
*terminal
)
829 struct lxc_ringbuf
*buf
= &terminal
->ringbuf
;
830 uint64_t size
= terminal
->buffer_size
;
832 /* no ringbuffer previously allocated and no ringbuffer requested */
833 if (!buf
->addr
&& size
<= 0)
836 /* ringbuffer allocated but no new ringbuffer requested */
837 if (buf
->addr
&& size
<= 0) {
838 lxc_ringbuf_release(buf
);
843 TRACE("Deallocated terminal ringbuffer");
850 /* check wether the requested size for the ringbuffer has changed */
851 if (buf
->addr
&& buf
->size
!= size
) {
852 TRACE("Terminal ringbuffer size changed from %" PRIu64
853 " to %" PRIu64
" bytes. Deallocating terminal ringbuffer",
855 lxc_ringbuf_release(buf
);
858 ret
= lxc_ringbuf_create(buf
, size
);
860 ERROR("Failed to setup %" PRIu64
" byte terminal ringbuffer", size
);
864 TRACE("Allocated %" PRIu64
" byte terminal ringbuffer", size
);
869 * This is the terminal log file. Please note that the terminal log file is
870 * (implementation wise not content wise) independent of the terminal ringbuffer.
872 int lxc_terminal_create_log_file(struct lxc_terminal
*terminal
)
874 if (!terminal
->log_path
)
877 terminal
->log_fd
= lxc_unpriv(open(terminal
->log_path
, O_CLOEXEC
| O_RDWR
| O_CREAT
| O_APPEND
, 0600));
878 if (terminal
->log_fd
< 0) {
879 SYSERROR("Failed to open terminal log file \"%s\"", terminal
->log_path
);
883 DEBUG("Using \"%s\" as terminal log file", terminal
->log_path
);
887 static int lxc_terminal_map_ids(struct lxc_conf
*c
, struct lxc_terminal
*terminal
)
891 if (list_empty(&c
->id_map
))
894 if (is_empty_string(terminal
->name
) && terminal
->pty
< 0)
897 if (terminal
->pty
>= 0)
898 ret
= userns_exec_mapped_root(NULL
, terminal
->pty
, c
);
900 ret
= userns_exec_mapped_root(terminal
->name
, -EBADF
, c
);
902 return log_error(-1, "Failed to chown terminal %d(%s)", terminal
->pty
,
903 !is_empty_string(terminal
->name
) ? terminal
->name
: "(null)");
905 TRACE("Chowned terminal %d(%s)", terminal
->pty
,
906 !is_empty_string(terminal
->name
) ? terminal
->name
: "(null)");
911 static int lxc_terminal_create_foreign(struct lxc_conf
*conf
, struct lxc_terminal
*terminal
)
915 ret
= openpty(&terminal
->ptx
, &terminal
->pty
, NULL
, NULL
, NULL
);
917 SYSERROR("Failed to open terminal");
921 ret
= lxc_terminal_map_ids(conf
, terminal
);
923 SYSERROR("Failed to change ownership of terminal multiplexer device");
927 ret
= ttyname_r(terminal
->pty
, terminal
->name
, sizeof(terminal
->name
));
929 SYSERROR("Failed to retrieve name of terminal pty");
933 ret
= lxc_fd_cloexec(terminal
->ptx
, true);
935 SYSERROR("Failed to set FD_CLOEXEC flag on terminal ptx");
939 ret
= lxc_fd_cloexec(terminal
->pty
, true);
941 SYSERROR("Failed to set FD_CLOEXEC flag on terminal pty");
945 ret
= lxc_terminal_peer_default(terminal
);
947 ERROR("Failed to allocate proxy terminal");
954 lxc_terminal_delete(terminal
);
958 int lxc_devpts_terminal(int devpts_fd
, int *ret_ptx
, int *ret_pty
,
959 int *ret_pty_nr
, bool require_tiocgptpeer
)
961 __do_close
int fd_devpts
= -EBADF
, fd_ptx
= -EBADF
,
962 fd_opath_pty
= -EBADF
, fd_pty
= -EBADF
;
967 * When we aren't told what devpts instance to allocate from we assume
968 * it is the one in the caller's mount namespace.
969 * This poses a slight complication, a lot of distros will change
970 * permissions on /dev/ptmx so it can be opened by unprivileged users
971 * but will not change permissions on /dev/pts/ptmx itself. In
972 * addition, /dev/ptmx can either be a symlink, a bind-mount, or a
973 * separate device node. So we need to allow for fairly lax lookup.
976 fd_ptx
= open_at(-EBADF
, "/dev/ptmx", PROTECT_OPEN_RW
& ~O_NOFOLLOW
,
977 PROTECT_LOOKUP_ABSOLUTE_XDEV_SYMLINKS
, 0);
979 fd_ptx
= open_beneath(devpts_fd
, "ptmx", O_RDWR
| O_NOCTTY
| O_CLOEXEC
);
982 return systrace("Exceeded number of allocatable terminals");
984 return syswarn("Failed to open terminal multiplexer device");
988 fd_devpts
= open_at(-EBADF
, "/dev/pts", PROTECT_OPATH_DIRECTORY
,
989 PROTECT_LOOKUP_ABSOLUTE_XDEV
, 0);
991 return syswarn("Failed to open devpts instance");
993 if (!same_device(fd_devpts
, "ptmx", fd_ptx
, ""))
994 return syswarn("The acquired ptmx devices don't match");
995 devpts_fd
= fd_devpts
;
998 ret
= unlockpt(fd_ptx
);
1000 return syswarn_set(-ENODEV
, "Failed to unlock multiplexer device device");
1002 fd_pty
= ioctl(fd_ptx
, TIOCGPTPEER
, O_RDWR
| O_NOCTTY
| O_CLOEXEC
);
1006 SYSTRACE("Pure fd-based terminal allocation not possible");
1009 SYSTRACE("Exceeded number of allocatable terminals");
1012 SYSWARN("Failed to allocate new pty device");
1016 /* The caller tells us that they trust the devpts instance. */
1017 if (require_tiocgptpeer
)
1018 return ret_errno(ENODEV
);
1021 ret
= ioctl(fd_ptx
, TIOCGPTN
, &pty_nr
);
1023 return syswarn_set(-ENODEV
, "Failed to retrieve name of terminal pty");
1027 * If we end up it means that TIOCGPTPEER isn't supported but
1028 * the caller told us they trust the devpts instance so we use
1029 * the pty nr to open the pty side.
1031 fd_pty
= open_at(devpts_fd
, fdstr(pty_nr
), PROTECT_OPEN_RW
,
1032 PROTECT_LOOKUP_ABSOLUTE_XDEV
, 0);
1034 return syswarn_set(-ENODEV
, "Failed to open terminal pty fd by path %d/%d",
1037 fd_opath_pty
= open_at(devpts_fd
, fdstr(pty_nr
), PROTECT_OPATH_FILE
,
1038 PROTECT_LOOKUP_ABSOLUTE_XDEV
, 0);
1039 if (fd_opath_pty
< 0)
1040 return syswarn_set(-ENODEV
, "Failed to open terminal pty fd by path %d/%d",
1043 if (!same_file_lax(fd_pty
, fd_opath_pty
))
1044 return syswarn_set(-ENODEV
, "Terminal file descriptor changed");
1047 *ret_ptx
= move_fd(fd_ptx
);
1048 *ret_pty
= move_fd(fd_pty
);
1049 *ret_pty_nr
= pty_nr
;
1053 int lxc_terminal_parent(struct lxc_conf
*conf
)
1055 struct lxc_terminal
*console
= &conf
->console
;
1058 if (!wants_console(&conf
->console
))
1061 /* Allocate console from the container's devpts. */
1062 if (conf
->pty_max
> 1)
1065 /* Allocate console for the container from the host's devpts. */
1066 ret
= lxc_devpts_terminal(-EBADF
, &console
->ptx
, &console
->pty
,
1067 &console
->pty_nr
, false);
1069 return syserror("Failed to allocate console");
1071 ret
= strnprintf(console
->name
, sizeof(console
->name
),
1072 "/dev/pts/%d", console
->pty_nr
);
1074 return syserror("Failed to create console path");
1076 return lxc_terminal_map_ids(conf
, &conf
->console
);
1079 static int lxc_terminal_create_native(const char *name
, const char *lxcpath
,
1080 struct lxc_terminal
*terminal
)
1082 __do_close
int devpts_fd
= -EBADF
;
1085 devpts_fd
= lxc_cmd_get_devpts_fd(name
, lxcpath
);
1087 return sysinfo("Failed to receive devpts fd");
1089 ret
= lxc_devpts_terminal(devpts_fd
, &terminal
->ptx
, &terminal
->pty
,
1090 &terminal
->pty_nr
, true);
1094 ret
= strnprintf(terminal
->name
, sizeof(terminal
->name
),
1095 "/dev/pts/%d", terminal
->pty_nr
);
1097 return syserror("Failed to create path");
1099 ret
= lxc_terminal_peer_default(terminal
);
1101 lxc_terminal_delete(terminal
);
1102 return syswarn_set(-ENODEV
, "Failed to allocate proxy terminal");
1108 int lxc_terminal_create(const char *name
, const char *lxcpath
,
1109 struct lxc_conf
*conf
, struct lxc_terminal
*terminal
)
1111 if (!lxc_terminal_create_native(name
, lxcpath
, terminal
))
1114 return lxc_terminal_create_foreign(conf
, terminal
);
1117 int lxc_terminal_setup(struct lxc_conf
*conf
)
1120 struct lxc_terminal
*terminal
= &conf
->console
;
1122 if (terminal
->path
&& strequal(terminal
->path
, "none"))
1123 return log_info(0, "No terminal requested");
1125 ret
= lxc_terminal_peer_default(terminal
);
1129 ret
= lxc_terminal_create_log_file(terminal
);
1133 ret
= lxc_terminal_create_ringbuf(terminal
);
1140 lxc_terminal_delete(terminal
);
1144 static bool __terminal_dup2(int duplicate
, int original
)
1148 if (!isatty(original
))
1151 ret
= dup2(duplicate
, original
);
1153 SYSERROR("Failed to dup2(%d, %d)", duplicate
, original
);
1160 int lxc_terminal_set_stdfds(int fd
)
1167 for (i
= 0; i
< 3; i
++)
1168 if (!__terminal_dup2(fd
, (int[]){STDIN_FILENO
, STDOUT_FILENO
,
1175 int lxc_terminal_stdin_cb(int fd
, uint32_t events
, void *cbdata
,
1176 struct lxc_async_descr
*descr
)
1180 struct lxc_terminal_state
*ts
= cbdata
;
1182 if (fd
!= ts
->stdinfd
)
1183 return LXC_MAINLOOP_CLOSE
;
1185 ret
= lxc_read_nointr(ts
->stdinfd
, &c
, 1);
1187 return LXC_MAINLOOP_CLOSE
;
1189 if (ts
->escape
>= 1) {
1190 /* we want to exit the terminal with Ctrl+a q */
1191 if (c
== ts
->escape
&& !ts
->saw_escape
) {
1193 return LXC_MAINLOOP_CONTINUE
;
1196 if (c
== 'q' && ts
->saw_escape
)
1197 return LXC_MAINLOOP_CLOSE
;
1202 ret
= lxc_write_nointr(ts
->ptxfd
, &c
, 1);
1204 return LXC_MAINLOOP_CLOSE
;
1206 return LXC_MAINLOOP_CONTINUE
;
1209 int lxc_terminal_ptx_cb(int fd
, uint32_t events
, void *cbdata
,
1210 struct lxc_async_descr
*descr
)
1213 char buf
[LXC_TERMINAL_BUFFER_SIZE
];
1214 struct lxc_terminal_state
*ts
= cbdata
;
1216 if (fd
!= ts
->ptxfd
)
1217 return LXC_MAINLOOP_CLOSE
;
1219 r
= lxc_read_nointr(fd
, buf
, sizeof(buf
));
1221 return LXC_MAINLOOP_CLOSE
;
1223 w
= lxc_write_nointr(ts
->stdoutfd
, buf
, r
);
1224 if (w
<= 0 || w
!= r
)
1225 return LXC_MAINLOOP_CLOSE
;
1227 return LXC_MAINLOOP_CONTINUE
;
1230 int lxc_terminal_getfd(struct lxc_container
*c
, int *ttynum
, int *ptxfd
)
1232 return lxc_cmd_get_tty_fd(c
->name
, ttynum
, ptxfd
, c
->config_path
);
1235 int lxc_console(struct lxc_container
*c
, int ttynum
,
1236 int stdinfd
, int stdoutfd
, int stderrfd
,
1239 int ptxfd
, ret
, ttyfd
;
1240 struct lxc_async_descr descr
;
1241 struct termios oldtios
;
1242 struct lxc_terminal_state
*ts
;
1243 struct lxc_terminal terminal
= {
1248 ttyfd
= lxc_cmd_get_tty_fd(c
->name
, &ttynum
, &ptxfd
, c
->config_path
);
1254 TRACE("Process is already group leader");
1256 ts
= lxc_terminal_signal_init(stdinfd
, ptxfd
);
1261 terminal
.tty_state
= ts
;
1262 ts
->escape
= escape
;
1263 ts
->stdoutfd
= stdoutfd
;
1265 istty
= isatty(stdinfd
);
1267 lxc_terminal_winsz(stdinfd
, ptxfd
);
1268 lxc_terminal_winsz(ts
->stdinfd
, ts
->ptxfd
);
1270 INFO("File descriptor %d does not refer to a terminal", stdinfd
);
1273 ret
= lxc_mainloop_open(&descr
);
1275 ERROR("Failed to create mainloop");
1279 if (ts
->sigfd
!= -1) {
1280 ret
= lxc_mainloop_add_handler(&descr
, ts
->sigfd
,
1281 lxc_terminal_signalfd_cb
,
1282 default_cleanup_handler
,
1283 ts
, "lxc_terminal_signalfd_cb");
1285 ERROR("Failed to add signal handler to mainloop");
1286 goto close_mainloop
;
1290 ret
= lxc_mainloop_add_handler(&descr
, ts
->stdinfd
,
1291 lxc_terminal_stdin_cb
,
1292 default_cleanup_handler
,
1293 ts
, "lxc_terminal_stdin_cb");
1295 ERROR("Failed to add stdin handler");
1296 goto close_mainloop
;
1299 ret
= lxc_mainloop_add_handler(&descr
, ts
->ptxfd
,
1300 lxc_terminal_ptx_cb
,
1301 default_cleanup_handler
,
1302 ts
, "lxc_terminal_ptx_cb");
1304 ERROR("Failed to add ptx handler");
1305 goto close_mainloop
;
1308 if (ts
->escape
>= 1) {
1311 "Connected to tty %1$d\n"
1312 "Type <Ctrl+%2$c q> to exit the console, "
1313 "<Ctrl+%2$c Ctrl+%2$c> to enter Ctrl+%2$c itself\n",
1314 ttynum
, 'a' + escape
- 1);
1318 ret
= lxc_setup_tios(stdinfd
, &oldtios
);
1320 goto close_mainloop
;
1323 ret
= lxc_mainloop(&descr
, -1);
1325 ERROR("The mainloop returned an error");
1333 istty
= tcsetattr(stdinfd
, TCSAFLUSH
, &oldtios
);
1335 SYSWARN("Failed to restore terminal properties");
1339 lxc_mainloop_close(&descr
);
1342 lxc_terminal_signal_fini(&terminal
);
1351 int lxc_make_controlling_terminal(int fd
)
1357 ret
= ioctl(fd
, TIOCSCTTY
, (char *)NULL
);
1364 int lxc_terminal_prepare_login(int fd
)
1368 ret
= lxc_make_controlling_terminal(fd
);
1372 ret
= lxc_terminal_set_stdfds(fd
);
1376 if (fd
> STDERR_FILENO
)
1382 void lxc_terminal_info_init(struct lxc_terminal_info
*terminal
)
1384 terminal
->name
[0] = '\0';
1385 terminal
->ptx
= -EBADF
;
1386 terminal
->pty
= -EBADF
;
1387 terminal
->busy
= -1;
1388 terminal
->pty_nr
= -1;
1391 void lxc_terminal_init(struct lxc_terminal
*terminal
)
1393 memset(terminal
, 0, sizeof(*terminal
));
1394 terminal
->pty_nr
= -1;
1395 terminal
->pty
= -EBADF
;
1396 terminal
->ptx
= -EBADF
;
1397 terminal
->peer
= -EBADF
;
1398 terminal
->log_fd
= -EBADF
;
1399 lxc_terminal_info_init(&terminal
->proxy
);
1402 void lxc_terminal_conf_free(struct lxc_terminal
*terminal
)
1404 free(terminal
->log_path
);
1405 free(terminal
->path
);
1406 if (terminal
->buffer_size
> 0 && terminal
->ringbuf
.addr
)
1407 lxc_ringbuf_release(&terminal
->ringbuf
);
1408 lxc_terminal_signal_fini(terminal
);