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

Reply via email to