From 40e1f4ea7458a0a80eaf1ef356e52bfe0835412e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 7 Oct 2015 23:38:20 +0200 Subject: machined: when opening a shell via machined, pass tty fds in With this change we'll open the shell's tty right from machined and then pass it to the transient unit we create. This way we make sure the pty is opened exactly as long as the transient service is around, and no longer, and vice versa. This way pty forwarders do not have to deal with EIO problems due to vhangup, as the pty is open all the time from the point we set things up to the point where the service goes away. --- src/basic/terminal-util.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/basic/terminal-util.c') diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 50a86a331c..e9097d8ae5 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -1152,3 +1152,51 @@ int openpt_in_namespace(pid_t pid, int flags) { return receive_one_fd(pair[0], 0); } + +int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { + _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; + _cleanup_close_pair_ int pair[2] = { -1, -1 }; + siginfo_t si; + pid_t child; + int r; + + r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd); + if (r < 0) + return r; + + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) + return -errno; + + child = fork(); + if (child < 0) + return -errno; + + if (child == 0) { + int master; + + pair[0] = safe_close(pair[0]); + + r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd); + if (r < 0) + _exit(EXIT_FAILURE); + + master = open_terminal(name, mode|O_NOCTTY|O_CLOEXEC); + if (master < 0) + _exit(EXIT_FAILURE); + + if (send_one_fd(pair[1], master, 0) < 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + pair[1] = safe_close(pair[1]); + + r = wait_for_terminate(child, &si); + if (r < 0) + return r; + if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) + return -EIO; + + return receive_one_fd(pair[0], 0); +} -- cgit v1.2.3-54-g00ecf