summaryrefslogtreecommitdiff
path: root/src/nspawn/nspawn.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-12-22 13:11:17 +0100
committerLennart Poettering <lennart@poettering.net>2012-12-22 22:17:58 +0100
commit51d88d1b4fb4ba7c2ecbc72cbbcababb21e4925f (patch)
treecad27bb070bb8808cc3f95f74778cea2b4e619a4 /src/nspawn/nspawn.c
parent5bbbe461fd4d133eac49f41210e2fd4846f577d8 (diff)
nspawn: allow nspawn to be invoked without tty
This allows invoking nspawn containers as systemd services, to create a minimal, light-weight OS container solution for servers.
Diffstat (limited to 'src/nspawn/nspawn.c')
-rw-r--r--src/nspawn/nspawn.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 59171abff3..4e4c5601e7 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -842,9 +842,19 @@ static int process_pty(int master, sigset_t *mask) {
goto finish;
}
- zero(stdin_ev);
- stdin_ev.events = EPOLLIN|EPOLLET;
- stdin_ev.data.fd = STDIN_FILENO;
+ /* We read from STDIN only if this is actually a TTY,
+ * otherwise we assume non-interactivity. */
+ if (isatty(STDIN_FILENO)) {
+ zero(stdin_ev);
+ stdin_ev.events = EPOLLIN|EPOLLET;
+ stdin_ev.data.fd = STDIN_FILENO;
+
+ if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0) {
+ log_error("Failed to register STDIN in epoll: %m");
+ r = -errno;
+ goto finish;
+ }
+ }
zero(stdout_ev);
stdout_ev.events = EPOLLOUT|EPOLLET;
@@ -858,11 +868,10 @@ static int process_pty(int master, sigset_t *mask) {
signal_ev.events = EPOLLIN;
signal_ev.data.fd = signal_fd;
- if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 ||
- epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
+ if (epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 ||
epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 ||
epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) {
- log_error("Failed to regiser fds in epoll: %m");
+ log_error("Failed to register fds in epoll: %m");
r = -errno;
goto finish;
}
@@ -1128,16 +1137,13 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (tcgetattr(STDIN_FILENO, &saved_attr) < 0) {
- log_error("Failed to get terminal attributes: %m");
- goto finish;
- }
-
- saved_attr_valid = true;
+ if (tcgetattr(STDIN_FILENO, &saved_attr) >= 0) {
+ saved_attr_valid = true;
- raw_attr = saved_attr;
- cfmakeraw(&raw_attr);
- raw_attr.c_lflag &= ~ECHO;
+ raw_attr = saved_attr;
+ cfmakeraw(&raw_attr);
+ raw_attr.c_lflag &= ~ECHO;
+ }
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
log_error("Failed to create kmsg socket pair");
@@ -1151,9 +1157,11 @@ int main(int argc, char *argv[]) {
for (;;) {
siginfo_t status;
- if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
- log_error("Failed to set terminal attributes: %m");
- goto finish;
+ if (saved_attr_valid) {
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
+ log_error("Failed to set terminal attributes: %m");
+ goto finish;
+ }
}
pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);