]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-attach: fix redirection - stderr
authorChristian Brauner <christian.brauner@mailbox.org>
Fri, 4 Mar 2016 18:32:00 +0000 (19:32 +0100)
committerChristian Brauner <christian.brauner@mailbox.org>
Fri, 4 Mar 2016 23:38:39 +0000 (00:38 +0100)
So that we can do things like:

lxc-attach -n a -- sh -c 'echo ERR >&2' > /dev/null

There seems to be no easy way to discern when we need to write to stderr
instead of stdout when we receive an event on the master fd of an allocated
pty. So we're using a "trick"/"hack". We write to STDOUT_FILENO if it refers to
a pty. If STDOUT_FILENO does not refer to a pty we check whether STDERR_FILENO
refers to a pty and if so write to it.

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

index 348014d96207d7a8e59777e3e4f42bf571d1c4cd..ffcd3d189d35243fe17618cc635b542476f4d43f 100644 (file)
@@ -273,7 +273,39 @@ static int get_pty_on_host(struct lxc_container *c, struct wrapargs *wrap, int *
        if (lxc_console_create(conf) < 0)
                return -1;
        ts = conf->console.tty_state;
-       ts->stdoutfd = STDOUT_FILENO;
+       /*
+        * We need to make sure that the ouput that is produced inside the
+        * container is received on the host. Suppose we want to run
+        *
+        *      lxc-attach -n a -- /bin/sh -c 'hostname >&2' > /dev/null
+        *
+        * This command produces output on stderr inside the container. On the
+        * host we close stdout by redirecting it to /dev/null. But stderr is,
+        * as expected, still connected to a tty. We receive the output produced
+        * on stderr in the container on stderr on the host.
+        *
+        * For the command
+        *
+        *      lxc-attach -n a -- /bin/sh -c 'hostname >&2' 2> /dev/null
+        *
+        * the logic is analogous but because we now have closed stderr on the
+        * host no output will be received.
+        *
+        * Finally, imagine a more complicated case
+        *
+        *      lxc-attach -n a -- /bin/sh -c 'echo OUT; echo ERR >&2' > /tmp/out 2> /tmp/err
+        *
+        * Here, we produce output in the container on stdout and stderr. On the
+        * host we redirect stdout and stderr to files. Because of that stdout
+        * and stderr are not dup2()ed. Thus, they are not connected to a pty
+        * and output on stdout and stderr is redirected to the corresponding
+        * files as expected.
+        */
+       if (!isatty(STDOUT_FILENO) && isatty(STDERR_FILENO))
+               ts->stdoutfd = STDERR_FILENO;
+       else
+               ts->stdoutfd = STDOUT_FILENO;
+
        conf->console.descr = &descr;
 
        /* Shift ttys to container. */