]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-attach: add comment, & implement login_tty() 839/head
authorChristian Brauner <christian.brauner@mailbox.org>
Mon, 22 Feb 2016 11:27:06 +0000 (12:27 +0100)
committerChristian Brauner <christian.brauner@mailbox.org>
Mon, 22 Feb 2016 14:41:58 +0000 (15:41 +0100)
- The code required to prepare an fd to act as a login tty is shared among
  pty_on_host_callback() and fork_pty(). This implements login_pty(), a
  minimalistic login_tty() clone, to avoid code redundancy.
- Give pty_in_container() a slightly extended comment.

Signed-off-by: Christian Brauner <christian.brauner@mailbox.org>
src/lxc/lxc_attach.c

index 98e917a1be799deaed9f2aa664249939391a07b3..3439b2f17955ac4a5950cd77ef0cbeb910122ec7 100644 (file)
@@ -210,6 +210,19 @@ struct wrapargs {
        int ptyfd;
 };
 
+/* Minimalistic login_tty() implementation. */
+static int login_pty(int fd)
+{
+       setsid();
+       if (ioctl(fd, TIOCSCTTY, NULL) < 0)
+               return -1;
+       if (lxc_console_set_stdfds(fd) < 0)
+               return -1;
+       if (fd > STDERR_FILENO)
+               close(fd);
+       return 0;
+}
+
 /* Minimalistic forkpty() implementation. */
 static pid_t fork_pty(int *masterfd)
 {
@@ -226,11 +239,8 @@ static pid_t fork_pty(int *masterfd)
                return -1;
        } else if (pid == 0) {
                close(master);
-               setsid();
-               if (ioctl(slave, TIOCSCTTY, NULL) < 0)
-                       _exit(-1); /* automatically closes fds */
-               if (lxc_console_set_stdfds(slave) < 0)
-                       _exit(-1); /* automatically closes fds */
+               if (login_pty(slave) < 0)
+                       _exit(-1); /* closes fds */
                return 0;
        } else {
                *masterfd = master;
@@ -239,6 +249,29 @@ static pid_t fork_pty(int *masterfd)
        }
 }
 
+/*
+ * This is probably redundant but just so that intentions can be checked against
+ * code for future modifications. Here is what this is supposed to achieve:
+ * Since we fork() in pty_in_container() the shell that is run on the slave side
+ * of the pty is the grandchild of c->attach() in main(). But what we probably
+ * are interested in is the exit code of the grandchild. So we wait for the
+ * grandchild to change status and return its exit code from this function. We
+ * thereby make the exit code of the grandchild the exit code of the child and
+ * allow the grandparent to see the exit code of the grandchild by waiting on
+ * the pid of the child to change status:
+ *
+ * grandchild: lxc_attach_run_command()/lxc_attach_run_shell()
+ *
+ * child: pty_in_container()
+ * - perform waitpid() on pid returned by lxc_attach_run_command() or
+ *   lxc_attach_run_shell()
+ *
+ * grandparent: c->attach()
+ * - return pid of pty_in_container() in pid argument.
+ *
+ * main()
+ * - perform waitpid() on pid returned in pid argument of c->attach()
+ */
 static int pty_in_container(void *p)
 {
        int ret;
@@ -335,9 +368,14 @@ err2:
 err1:
        tcsetattr(args->ptyfd, TCSAFLUSH, &oldtios);
 
-       if (pid > 0)
-               ret = lxc_wait_for_pid_status(pid);
-       return ret;
+       ret = lxc_wait_for_pid_status(pid);
+       if (ret < 0)
+               return ret;
+
+       if (WIFEXITED(ret))
+               return WEXITSTATUS(ret);
+
+       return -1;
 }
 
 static int pty_on_host_callback(void *p)
@@ -345,16 +383,13 @@ static int pty_on_host_callback(void *p)
        struct wrapargs *wrap = p;
 
        close(wrap->console->master);
-       setsid();
-       ioctl(wrap->console->slave, TIOCSCTTY, NULL);
-       if (lxc_console_set_stdfds(wrap->console->slave) < 0)
+       if (login_pty(wrap->console->slave) < 0)
                return -1;
 
        if (wrap->command->program)
                lxc_attach_run_command(wrap->command);
        else
                lxc_attach_run_shell(NULL);
-
        return -1;
 }
 
@@ -465,7 +500,7 @@ int main(int argc, char *argv[])
                if (access(my_args.lxcpath[0], O_RDWR) < 0) {
                        if (!my_args.quiet)
                                fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]);
-                       exit(ret);
+                       exit(EXIT_FAILURE);
                }
        }