Merge pull request #4 from mrunalp/opt_parsing

Separate tty/non-tty and add opt parsing
This commit is contained in:
Mrunal Patel 2016-09-13 09:56:21 -07:00 committed by GitHub
commit 817b22b5f3

View file

@ -1,4 +1,5 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdbool.h> #include <stdbool.h>
@ -58,7 +59,9 @@ static void tty_restore(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret; int ret;
const char *cid; int opt;
bool terminal = FALSE;
const char *cid = NULL;
char cmd[CMD_SIZE]; char cmd[CMD_SIZE];
GError *err = NULL; GError *err = NULL;
_cleanup_free_ char *contents; _cleanup_free_ char *contents;
@ -74,12 +77,29 @@ int main(int argc, char *argv[])
struct epoll_event ev; struct epoll_event ev;
struct epoll_event evlist[MAX_EVENTS]; struct epoll_event evlist[MAX_EVENTS];
if (argc < 2) { while ((opt = getopt(argc, argv, "tc:")) != -1) {
nexit("Run as: conmon <id>"); 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 */ if (cid == NULL) {
cid = argv[1]; nexit("Container ID not passed");
}
/* /*
* Set self as subreaper so we can wait for container process * 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"); pexit("Failed to set as subreaper");
} }
/* Open the master pty */ if (terminal) {
mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* Open the master pty */
if (mfd < 0) mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
pexit("Failed to open console master pty"); if (mfd < 0)
pexit("Failed to open console master pty");
/* Grant access to the slave pty */ /* Grant access to the slave pty */
if (grantpt(mfd) == -1) if (grantpt(mfd) == -1)
pexit("Failed to grant access to slave pty"); pexit("Failed to grant access to slave pty");
/* Unlock the slave pty */ /* Unlock the slave pty */
if (unlockpt(mfd) == -1) { /* Unlock slave pty */ if (unlockpt(mfd) == -1) { /* Unlock slave pty */
pexit("Failed to unlock the 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 */ /* 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); ret = system(cmd);
if (ret != 0) { if (ret != 0) {
nexit("Failed to create container"); nexit("Failed to create container");
@ -128,73 +155,75 @@ int main(int argc, char *argv[])
cpid = atoi(contents); cpid = atoi(contents);
printf("container PID: %d\n", cpid); printf("container PID: %d\n", cpid);
/* Save exiting termios settings */ if (terminal) {
if (tcgetattr(STDIN_FILENO, &tty_orig) == -1) /* Save exiting termios settings */
pexit("tcegetattr"); if (tcgetattr(STDIN_FILENO, &tty_orig) == -1)
pexit("tcegetattr");
/* Settings for raw mode */ /* Settings for raw mode */
t.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN); t.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN);
t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK |
ISTRIP | IXON | IXOFF | IGNPAR | PARMRK); ISTRIP | IXON | IXOFF | IGNPAR | PARMRK);
t.c_oflag &= ~OPOST; t.c_oflag &= ~OPOST;
t.c_cc[VMIN] = 1; t.c_cc[VMIN] = 1;
t.c_cc[VTIME] = 0; t.c_cc[VTIME] = 0;
/* Set terminal to raw mode */ /* Set terminal to raw mode */
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) == -1) if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) == -1)
pexit("tcsetattr"); pexit("tcsetattr");
/* Setup terminal restore on exit */ /* Setup terminal restore on exit */
if (atexit(tty_restore) != 0) if (atexit(tty_restore) != 0)
pexit("atexit"); pexit("atexit");
epfd = epoll_create(5); epfd = epoll_create(5);
if (epfd < 0) if (epfd < 0)
pexit("epoll_create"); pexit("epoll_create");
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.fd = STDIN_FILENO; ev.data.fd = STDIN_FILENO;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) { if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) < 0) {
pexit("Failed to add stdin to epoll"); pexit("Failed to add stdin to epoll");
} }
ev.data.fd = mfd; ev.data.fd = mfd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, mfd, &ev) < 0) { if (epoll_ctl(epfd, EPOLL_CTL_ADD, mfd, &ev) < 0) {
pexit("Failed to add console master fd to epoll"); pexit("Failed to add console master fd to epoll");
} }
/* Copy data back and forth between STDIN and master fd */ /* Copy data back and forth between STDIN and master fd */
while (true) { while (true) {
int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1); int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1);
for (int i = 0; i < ready; i++) { for (int i = 0; i < ready; i++) {
if (evlist[i].events & EPOLLIN) { if (evlist[i].events & EPOLLIN) {
if (evlist[i].data.fd == STDIN_FILENO) { if (evlist[i].data.fd == STDIN_FILENO) {
num_read = read(STDIN_FILENO, buf, BUF_SIZE); num_read = read(STDIN_FILENO, buf, BUF_SIZE);
if (num_read <= 0) if (num_read <= 0)
goto out; goto out;
if (write(mfd, buf, num_read) != num_read) { if (write(mfd, buf, num_read) != num_read) {
nwarn("partial/failed write (masterFd)"); nwarn("partial/failed write (masterFd)");
goto out; goto out;
} }
} else if (evlist[i].data.fd == mfd) { } else if (evlist[i].data.fd == mfd) {
num_read = read(mfd, buf, BUF_SIZE); num_read = read(mfd, buf, BUF_SIZE);
if (num_read <= 0) if (num_read <= 0)
goto out; goto out;
if (write(STDOUT_FILENO, buf, num_read) != num_read) { if (write(STDOUT_FILENO, buf, num_read) != num_read) {
nwarn("partial/failed write (STDOUT_FILENO)"); nwarn("partial/failed write (STDOUT_FILENO)");
goto out; 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: out:
tty_restore(); tty_restore();
}
/* Wait for the container process and record its exit code */ /* Wait for the container process and record its exit code */
while ((pid = waitpid(-1, &status, 0)) > 0) { while ((pid = waitpid(-1, &status, 0)) > 0) {