From a7ca60ae30ce8f195e404eb717c3034a19695ec9 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Mon, 12 Sep 2016 16:38:30 -0700 Subject: [PATCH] Separate tty/non-tty and add opt parsing Signed-off-by: Mrunal Patel --- conmon/conmon.c | 183 ++++++++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 77 deletions(-) diff --git a/conmon/conmon.c b/conmon/conmon.c index 90bec01e..126a7dbd 100644 --- a/conmon/conmon.c +++ b/conmon/conmon.c @@ -1,4 +1,5 @@ #define _GNU_SOURCE +#include #include #include #include @@ -58,7 +59,9 @@ static void tty_restore(void) int main(int argc, char *argv[]) { int ret; - const char *cid; + int opt; + bool terminal = FALSE; + const char *cid = NULL; char cmd[CMD_SIZE]; GError *err = NULL; _cleanup_free_ char *contents; @@ -74,12 +77,29 @@ int main(int argc, char *argv[]) struct epoll_event ev; struct epoll_event evlist[MAX_EVENTS]; - if (argc < 2) { - nexit("Run as: conmon "); + while ((opt = getopt(argc, argv, "tc:")) != -1) { + switch(opt) { + case 't': + terminal = TRUE; + break; + case 'c': + cid = optarg; + break; + case '?': + if (optopt == 'c') + nexit("Option -%c requires an argument.", optopt); + else if (isprint (optopt)) + nexit("Unknown option `-%c'.", optopt); + else + nexit("Unknown option character `\\x%x'.\n", optopt); + default: + nexit("Usage: %s [-c container_id] [-t]", argv[0]); + } } - /* Get the container id */ - cid = argv[1]; + if (cid == NULL) { + nexit("Container ID not passed"); + } /* * Set self as subreaper so we can wait for container process @@ -90,28 +110,35 @@ int main(int argc, char *argv[]) pexit("Failed to set as subreaper"); } - /* Open the master pty */ - mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); - if (mfd < 0) - pexit("Failed to open console master pty"); + if (terminal) { + /* Open the master pty */ + mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); + if (mfd < 0) + pexit("Failed to open console master pty"); - /* Grant access to the slave pty */ - if (grantpt(mfd) == -1) - pexit("Failed to grant access to slave pty"); + /* Grant access to the slave pty */ + if (grantpt(mfd) == -1) + pexit("Failed to grant access to slave pty"); - /* Unlock the slave pty */ - if (unlockpt(mfd) == -1) { /* Unlock slave pty */ - pexit("Failed to unlock the slave pty"); - } + /* Unlock the slave pty */ + if (unlockpt(mfd) == -1) { /* Unlock slave pty */ + pexit("Failed to unlock the slave pty"); + } + + /* Get the slave pty name */ + ret = ptsname_r(mfd, slname, BUF_SIZE); + if (ret != 0) { + pexit("Failed to get the slave pty name"); + } - /* Get the slave pty name */ - ret = ptsname_r(mfd, slname, BUF_SIZE); - if (ret != 0) { - pexit("Failed to get the slave pty name"); } /* Create the container */ - snprintf(cmd, CMD_SIZE, "runc create %s --pid-file pidfile --console %s", cid, slname); + if (terminal) { + snprintf(cmd, CMD_SIZE, "runc create %s --pid-file pidfile --console %s", cid, slname); + } else { + snprintf(cmd, CMD_SIZE, "runc create %s --pid-file pidfile", cid); + } ret = system(cmd); if (ret != 0) { nexit("Failed to create container"); @@ -128,73 +155,75 @@ int main(int argc, char *argv[]) cpid = atoi(contents); printf("container PID: %d\n", cpid); - /* Save exiting termios settings */ - if (tcgetattr(STDIN_FILENO, &tty_orig) == -1) - pexit("tcegetattr"); + if (terminal) { + /* Save exiting termios settings */ + if (tcgetattr(STDIN_FILENO, &tty_orig) == -1) + pexit("tcegetattr"); - /* Settings for raw mode */ - t.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN); - t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | - ISTRIP | IXON | IXOFF | IGNPAR | PARMRK); - t.c_oflag &= ~OPOST; - t.c_cc[VMIN] = 1; - t.c_cc[VTIME] = 0; + /* Settings for raw mode */ + t.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN); + t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | + ISTRIP | IXON | IXOFF | IGNPAR | PARMRK); + t.c_oflag &= ~OPOST; + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; - /* Set terminal to raw mode */ - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) == -1) - pexit("tcsetattr"); + /* Set terminal to raw mode */ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) == -1) + pexit("tcsetattr"); - /* Setup terminal restore on exit */ - if (atexit(tty_restore) != 0) - pexit("atexit"); + /* Setup terminal restore on exit */ + if (atexit(tty_restore) != 0) + pexit("atexit"); - epfd = epoll_create(5); - if (epfd < 0) - pexit("epoll_create"); - ev.events = EPOLLIN; - ev.data.fd = STDIN_FILENO; - if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) { - pexit("Failed to add stdin to epoll"); - } - ev.data.fd = mfd; - if (epoll_ctl(epfd, EPOLL_CTL_ADD, mfd, &ev) < 0) { - pexit("Failed to add console master fd to epoll"); - } + epfd = epoll_create(5); + if (epfd < 0) + pexit("epoll_create"); + ev.events = EPOLLIN; + ev.data.fd = STDIN_FILENO; + if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) { + pexit("Failed to add stdin to epoll"); + } + ev.data.fd = mfd; + if (epoll_ctl(epfd, EPOLL_CTL_ADD, mfd, &ev) < 0) { + pexit("Failed to add console master fd to epoll"); + } - /* Copy data back and forth between STDIN and master fd */ - while (true) { - int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1); - for (int i = 0; i < ready; i++) { - if (evlist[i].events & EPOLLIN) { - if (evlist[i].data.fd == STDIN_FILENO) { - num_read = read(STDIN_FILENO, buf, BUF_SIZE); - if (num_read <= 0) - goto out; + /* Copy data back and forth between STDIN and master fd */ + while (true) { + int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1); + for (int i = 0; i < ready; i++) { + if (evlist[i].events & EPOLLIN) { + if (evlist[i].data.fd == STDIN_FILENO) { + num_read = read(STDIN_FILENO, buf, BUF_SIZE); + if (num_read <= 0) + goto out; - if (write(mfd, buf, num_read) != num_read) { - nwarn("partial/failed write (masterFd)"); - goto out; - } - } else if (evlist[i].data.fd == mfd) { - num_read = read(mfd, buf, BUF_SIZE); - if (num_read <= 0) - goto out; - - if (write(STDOUT_FILENO, buf, num_read) != num_read) { - nwarn("partial/failed write (STDOUT_FILENO)"); - goto out; + if (write(mfd, buf, num_read) != num_read) { + nwarn("partial/failed write (masterFd)"); + goto out; + } + } else if (evlist[i].data.fd == mfd) { + num_read = read(mfd, buf, BUF_SIZE); + if (num_read <= 0) + goto out; + + if (write(STDOUT_FILENO, buf, num_read) != num_read) { + nwarn("partial/failed write (STDOUT_FILENO)"); + goto out; + } } + } else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) { + printf("closing fd %d\n", evlist[i].data.fd); + if (close(evlist[i].data.fd) < 0) + pexit("close"); + goto out; } - } else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) { - printf("closing fd %d\n", evlist[i].data.fd); - if (close(evlist[i].data.fd) < 0) - pexit("close"); - goto out; } } - } out: - tty_restore(); + tty_restore(); + } /* Wait for the container process and record its exit code */ while ((pid = waitpid(-1, &status, 0)) > 0) {