assert_se(sigfillset(&fullmask) >= 0);
assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);
- /* Surrender the terminal this stub may control so that child processes can have a controlling terminal
- * without resorting to setsid hacks. */
- r = ioctl(STDIN_FILENO, TIOCNOTTY);
- if (r < 0 && errno != ENOTTY)
- return log_error_errno(errno, "Failed to surrender controlling terminal: %m");
-
pid = fork();
if (pid < 0)
return log_error_errno(errno, "Failed to fork child pid: %m");
(void) close_all_fds(NULL, 0);
log_open();
+ if (ioctl(STDIN_FILENO, TIOCNOTTY) < 0) {
+ if (errno != ENOTTY)
+ log_warning_errno(errno, "Unexpected error from TIOCNOTTY ioctl in init stub process, ignoring: %m");
+ } else
+ log_warning("Expected TIOCNOTTY to fail, but it succeeded in init stub process, ignoring.");
+
/* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
* set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
* find them set. */
#endif
#include <stdlib.h>
#include <sys/file.h>
+#include <sys/ioctl.h>
#include <sys/personality.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <termios.h>
#include <unistd.h>
#include "sd-bus.h"
_cleanup_close_ int terminal = -1;
int r;
- terminal = open_terminal("/dev/console", O_RDWR);
+ /* We open the TTY in O_NOCTTY mode, so that we do not become controller yet. We'll do that later
+ * explicitly, if we are configured to. */
+ terminal = open_terminal("/dev/console", O_RDWR|O_NOCTTY);
if (terminal < 0)
return log_error_errno(terminal, "Failed to open console: %m");
* wait until the parent is ready with the
* setup, too... */
if (!barrier_place_and_sync(barrier)) /* #5 */
- return log_error_errno(SYNTHETIC_ERRNO(ESRCH),
- "Parent died too early");
+ return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Parent died too early");
if (arg_chdir)
if (chdir(arg_chdir) < 0)
return r;
}
+ if (arg_console_mode != CONSOLE_PIPE) {
+ /* So far our pty wasn't controlled by any process. Finally, it's time to change that, if we
+ * are configured for that. Acquire it as controlling tty. */
+ if (ioctl(STDIN_FILENO, TIOCSCTTY) < 0)
+ return log_error_errno(errno, "Failed to acquire controlling TTY: %m");
+ }
+
log_debug("Inner child completed, invoking payload.");
/* Now, explicitly close the log, so that we then can close all remaining fds. Closing the log explicitly first