Use the mainloop to manage io of the console. Signed-off-by: Daniel Lezcano <dlezc...@fr.ibm.com> --- src/lxc/lxc_console.c | 163 ++++++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 75 deletions(-)
Index: lxc/src/lxc/lxc_console.c =================================================================== --- lxc.orig/src/lxc/lxc_console.c +++ lxc/src/lxc/lxc_console.c @@ -38,10 +38,10 @@ #include <sys/poll.h> #include <sys/ioctl.h> -#include <lxc/error.h> -#include <lxc/lxc.h> -#include <lxc/log.h> - +#include "error.h" +#include "lxc.h" +#include "log.h" +#include "mainloop.h" #include "arguments.h" lxc_log_define(lxc_console_ui, lxc_console); @@ -102,7 +102,7 @@ static void sigwinch(int sig) static int setup_tios(int fd, struct termios *newtios, struct termios *oldtios) { - if (isatty(fd)) { + if (!isatty(fd)) { ERROR("'%d' is not a tty", fd); return -1; } @@ -132,21 +132,68 @@ static int setup_tios(int fd, struct ter return 0; } +static int stdin_handler(int fd, void *data, struct lxc_epoll_descr *descr) +{ + static int wait4q = 0; + int *peer = (int *)data; + char c; + + if (read(0, &c, 1) < 0) { + SYSERROR("failed to read"); + return 1; + } + + /* we want to exit the console with Ctrl+a q */ + if (c == my_args.escape) { + wait4q = !wait4q; + return 0; + } + + if (c == 'q' && wait4q) + return 1; + + wait4q = 0; + if (write(*peer, &c, 1) < 0) { + SYSERROR("failed to write"); + return 1; + } + + return 0; +} + +static int master_handler(int fd, void *data, struct lxc_epoll_descr *descr) +{ + char buf[1024]; + int *peer = (int *)data; + int r; + + r = read(fd, buf, sizeof(buf)); + if (r < 0) { + SYSERROR("failed to read"); + return 1; + } + write(*peer, buf, r); + + return 0; +} + int main(int argc, char *argv[]) { - int wait4q = 0; - int err; + int err, std_in = 1; + struct lxc_epoll_descr descr; struct termios newtios, oldtios; err = lxc_arguments_parse(&my_args, argc, argv); if (err) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + err = lxc_log_init(my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet); + if (err) return -1; - if (setup_tios(0, &newtios, &oldtios)) { + err = setup_tios(0, &newtios, &oldtios); + if (err) { ERROR("failed to setup tios"); return -1; } @@ -158,77 +205,47 @@ int main(int argc, char *argv[]) fprintf(stderr, "\nType <Ctrl+%c q> to exit the console\n", 'a' + my_args.escape - 1); - if (setsid()) + err = setsid(); + if (err) INFO("already group leader"); if (signal(SIGWINCH, sigwinch) == SIG_ERR) { SYSERROR("failed to set SIGWINCH handler"); - return -1; + err = -1; + goto out; } winsz(); - err = 0; + err = lxc_mainloop_open(&descr); + if (err) { + ERROR("failed to create mainloop"); + goto out; + } + + err = lxc_mainloop_add_handler(&descr, 0, stdin_handler, &master); + if (err) { + ERROR("failed to add handler for the stdin"); + goto out_mainloop_open; + } + + err = lxc_mainloop_add_handler(&descr, master, master_handler, &std_in); + if (err) { + ERROR("failed to add handler for the master"); + goto out_mainloop_open; + } - /* let's proxy the tty */ - for (;;) { - struct pollfd pfd[2] = { - { .fd = 0, - .events = POLLIN|POLLPRI, - .revents = 0 }, - { .fd = master, - .events = POLLIN|POLLPRI, - .revents = 0 }, - }; - - if (poll(pfd, 2, -1) < 0) { - if (errno == EINTR) - continue; - SYSERROR("failed to poll"); - goto out_err; - } - - /* read the "stdin" and write that to the master - */ - if (pfd[0].revents & POLLIN) { - char c; - if (read(0, &c, 1) < 0) { - SYSERROR("failed to read"); - goto out_err; - } - - /* we want to exit the console with Ctrl+a q */ - if (c == my_args.escape) { - wait4q = !wait4q; - continue; - } - - if (c == 'q' && wait4q) - goto out; - - wait4q = 0; - if (write(master, &c, 1) < 0) { - SYSERROR("failed to write"); - goto out_err; - } - } - - /* other side has closed the connection */ - if (pfd[1].revents & POLLHUP) - goto out; - - /* read the master and write to "stdout" */ - if (pfd[1].revents & POLLIN) { - char buf[1024]; - int r; - r = read(master, buf, sizeof(buf)); - if (r < 0) { - SYSERROR("failed to read"); - goto out_err; - } - write(1, buf, r); - } + err = lxc_mainloop(&descr); + if (err) { + ERROR("mainloop returned an error"); + goto out_mainloop_open; } + + err = 0; + +out_mainloop_open: + lxc_mainloop_close(&descr); + out: /* Restore previous terminal parameter */ tcsetattr(0, TCSAFLUSH, &oldtios); @@ -239,8 +256,4 @@ out: close(master); return err; - -out_err: - err = -1; - goto out; } ------------------------------------------------------------------------------ The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel