#include "log.h"
#include "conf.h"
#include "config.h"
+#include "console.h"
#include "start.h" /* for struct lxc_handler */
#include "caps.h"
#include "commands.h"
static struct lxc_list lxc_ttys;
typedef void (*sighandler_t)(int);
-struct lxc_tty_state
-{
- struct lxc_list node;
- int stdinfd;
- int stdoutfd;
- int masterfd;
- int escape;
- int saw_escape;
- const char *winch_proxy;
- const char *winch_proxy_lxcpath;
- int sigfd;
- sigset_t oldmask;
-};
__attribute__((constructor))
void lxc_console_init(void)
* @srcfd : terminal to get size from (typically a slave pty)
* @dstfd : terminal to set size on (typically a master pty)
*/
-static void lxc_console_winsz(int srcfd, int dstfd)
+void lxc_console_winsz(int srcfd, int dstfd)
{
struct winsize wsz;
if (isatty(srcfd) && ioctl(srcfd, TIOCGWINSZ, &wsz) == 0) {
static void lxc_console_winch(struct lxc_tty_state *ts)
{
lxc_console_winsz(ts->stdinfd, ts->masterfd);
- if (ts->winch_proxy) {
- lxc_cmd_console_winch(ts->winch_proxy,
- ts->winch_proxy_lxcpath);
- }
+ if (ts->winch_proxy)
+ lxc_cmd_console_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
}
void lxc_console_sigwinch(int sig)
}
}
-static int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
- struct lxc_epoll_descr *descr)
+int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr)
{
struct signalfd_siginfo siginfo;
struct lxc_tty_state *ts = cbdata;
- if (read(fd, &siginfo, sizeof(siginfo)) < sizeof(siginfo)) {
+ ssize_t ret = read(fd, &siginfo, sizeof(siginfo));
+ if (ret < 0 || (size_t)ret < sizeof(siginfo)) {
ERROR("failed to read signal info");
return -1;
}
* prevent lxc_ttys list corruption, but using the fd we can provide the
* tty_state needed to the callback (lxc_console_cb_sigwinch_fd()).
*/
-static struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
+struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd)
{
sigset_t mask;
struct lxc_tty_state *ts;
* Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context.
*/
-static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts)
+void lxc_console_sigwinch_fini(struct lxc_tty_state *ts)
{
- if (ts->sigfd >= 0) {
+ if (ts->sigfd >= 0)
close(ts->sigfd);
- }
+
lxc_list_del(&ts->node);
sigprocmask(SIG_SETMASK, &ts->oldmask, NULL);
free(ts);
if (w != r)
WARN("console short write r:%d w:%d", r, w);
+
return 0;
}
return 0;
}
-static int setup_tios(int fd, struct termios *oldtios)
+int lxc_setup_tios(int fd, struct termios *oldtios)
{
struct termios newtios;
return -1;
}
- if (setup_tios(console->peerpty.slave, &oldtermio) < 0)
+ if (lxc_setup_tios(console->peerpty.slave, &oldtermio) < 0)
goto err1;
ts = lxc_console_sigwinch_init(console->peerpty.master, console->master);
}
/* search for next available tty, fixup index tty1 => [0] */
- for (ttynum = 1;
- ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy;
- ttynum++);
+ for (ttynum = 1; ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy; ttynum++)
+ ;
/* we didn't find any available slot for tty */
if (ttynum > tty_info->nbtty)
goto err1;
}
- if (setup_tios(console->peer, console->tios) < 0)
+ if (lxc_setup_tios(console->peer, console->tios) < 0)
goto err2;
return;
return 0;
}
-static int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
- struct lxc_epoll_descr *descr)
+int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr)
{
struct lxc_tty_state *ts = cbdata;
char c;
return 0;
}
-static int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata,
- struct lxc_epoll_descr *descr)
+int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr)
{
struct lxc_tty_state *ts = cbdata;
char buf[1024];
- int r,w;
+ int r, w;
assert(fd == ts->masterfd);
r = read(fd, buf, sizeof(buf));
return -1;
}
- ret = setup_tios(stdinfd, &oldtios);
+ ret = lxc_setup_tios(stdinfd, &oldtios);
if (ret) {
ERROR("failed to setup tios");
return -1;
return ret;
}
+
#ifndef __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
+#include "conf.h"
+#include "list.h"
+
struct lxc_epoll_descr;
struct lxc_container;
+struct lxc_tty_state
+{
+ struct lxc_list node;
+ int stdinfd;
+ int stdoutfd;
+ int masterfd;
+ int escape;
+ int saw_escape;
+ const char *winch_proxy;
+ const char *winch_proxy_lxcpath;
+ int sigfd;
+ sigset_t oldmask;
+};
extern int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttynum);
extern int lxc_console_create(struct lxc_conf *);
extern int lxc_console_getfd(struct lxc_container *c, int *ttynum,
int *masterfd);
extern int lxc_console_set_stdfds(struct lxc_handler *);
+extern int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr);
+extern int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr);
+extern int lxc_setup_tios(int fd, struct termios *oldtios);
+extern void lxc_console_winsz(int srcfd, int dstfd);
+extern int lxc_console_cb_sigwinch_fd(int fd, uint32_t events, void *cbdata,
+ struct lxc_epoll_descr *descr);
+extern struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd);
+extern void lxc_console_sigwinch_fini(struct lxc_tty_state *ts);
#endif