diff options
author | Franck Bui <fbui@suse.com> | 2019-06-07 10:17:11 +0200 |
---|---|---|
committer | Franck Bui <fbui@suse.com> | 2019-06-18 09:26:31 +0200 |
commit | ae1d13db056ee139f89fbb7cbc893dc5d89ffde3 (patch) | |
tree | 5602b7aac5270cb767e4c0f41f8035f9c33a11a0 | |
parent | nspawn: allocate the pty used for /dev/console within the container (diff) | |
download | systemd-ae1d13db056ee139f89fbb7cbc893dc5d89ffde3.tar.xz systemd-ae1d13db056ee139f89fbb7cbc893dc5d89ffde3.zip |
terminal-util: introduce openpt_allocate()
Allocating a pty is done in a couple of places so let's introduce a new helper
which does the job.
Also the new function, as well as openpt_in_namespace(), returns both pty
master and slave so the callers don't need to know about the pty slave
allocation details.
For the same reasons machine_openpt() prototype has also been changed to return
both pty master and slave so callers don't need to allocate a pty slave which
might be in a different namespace.
Finally openpt_in_namespace() has been renamed into
openpt_allocate_in_namespace().
-rw-r--r-- | src/basic/terminal-util.c | 56 | ||||
-rw-r--r-- | src/basic/terminal-util.h | 4 | ||||
-rw-r--r-- | src/machine/machine-dbus.c | 21 | ||||
-rw-r--r-- | src/machine/machine.c | 17 | ||||
-rw-r--r-- | src/machine/machine.h | 2 |
5 files changed, 55 insertions, 45 deletions
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 3a0d16a74f..aa69bede6f 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -1049,7 +1049,34 @@ int ptsname_malloc(int fd, char **ret) { } } -int ptsname_namespace(int pty, char **ret) { +int openpt_allocate(int flags, char **ret_slave) { + _cleanup_close_ int fd = -1; + _cleanup_free_ char *p = NULL; + int r; + + fd = posix_openpt(flags|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ret_slave) { + r = ptsname_malloc(fd, &p); + if (r < 0) + return r; + + if (!path_startswith(p, "/dev/pts/")) + return -EINVAL; + } + + if (unlockpt(fd) < 0) + return -errno; + + if (ret_slave) + *ret_slave = TAKE_PTR(p); + + return TAKE_FD(fd); +} + +static int ptsname_namespace(int pty, char **ret) { int no = -1, r; /* Like ptsname(), but doesn't assume that the path is @@ -1068,8 +1095,8 @@ int ptsname_namespace(int pty, char **ret) { return 0; } -int openpt_in_namespace(pid_t pid, int flags) { - _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; +int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave) { + _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1, fd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; pid_t child; int r; @@ -1088,18 +1115,13 @@ int openpt_in_namespace(pid_t pid, int flags) { if (r < 0) return r; if (r == 0) { - int master; - pair[0] = safe_close(pair[0]); - master = posix_openpt(flags|O_NOCTTY|O_CLOEXEC); - if (master < 0) - _exit(EXIT_FAILURE); - - if (unlockpt(master) < 0) + fd = openpt_allocate(flags, NULL); + if (fd < 0) _exit(EXIT_FAILURE); - if (send_one_fd(pair[1], master, 0) < 0) + if (send_one_fd(pair[1], fd, 0) < 0) _exit(EXIT_FAILURE); _exit(EXIT_SUCCESS); @@ -1113,7 +1135,17 @@ int openpt_in_namespace(pid_t pid, int flags) { if (r != EXIT_SUCCESS) return -EIO; - return receive_one_fd(pair[0], 0); + fd = receive_one_fd(pair[0], 0); + if (fd < 0) + return fd; + + if (ret_slave) { + r = ptsname_namespace(fd, ret_slave); + if (r < 0) + return r; + } + + return TAKE_FD(fd); } int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 87d09f8759..6e5b273c75 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -151,9 +151,9 @@ int getttyname_malloc(int fd, char **r); int getttyname_harder(int fd, char **r); int ptsname_malloc(int fd, char **ret); -int ptsname_namespace(int pty, char **ret); -int openpt_in_namespace(pid_t pid, int flags); +int openpt_allocate(int flags, char **ret_slave); +int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave); int open_terminal_in_namespace(pid_t pid, const char *name, int mode); int vt_default_utf8(void); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 1ee878055e..b89e6046d9 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -423,14 +423,10 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_ if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - r = sd_bus_message_new_method_return(message, &reply); if (r < 0) return r; @@ -514,17 +510,12 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - p = path_startswith(pty_name, "/dev/pts/"); - if (!p) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name); + assert(p); r = container_bus_new(m, error, &allocated_bus); if (r < 0) @@ -630,14 +621,10 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - p = path_startswith(pty_name, "/dev/pts/"); assert(p); diff --git a/src/machine/machine.c b/src/machine/machine.c index b916d038d7..ef8ccd98fb 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -530,29 +530,20 @@ int machine_kill(Machine *m, KillWho who, int signo) { return manager_kill_unit(m->manager, m->unit, signo, NULL); } -int machine_openpt(Machine *m, int flags) { +int machine_openpt(Machine *m, int flags, char **ret_slave) { assert(m); switch (m->class) { - case MACHINE_HOST: { - int fd; - - fd = posix_openpt(flags); - if (fd < 0) - return -errno; - - if (unlockpt(fd) < 0) - return -errno; + case MACHINE_HOST: - return fd; - } + return openpt_allocate(flags, ret_slave); case MACHINE_CONTAINER: if (m->leader <= 0) return -EINVAL; - return openpt_in_namespace(m->leader, flags); + return openpt_allocate_in_namespace(m->leader, flags, ret_slave); default: return -EOPNOTSUPP; diff --git a/src/machine/machine.h b/src/machine/machine.h index 9ff9a65671..f7471be8f5 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -89,7 +89,7 @@ MachineState machine_state_from_string(const char *s) _pure_; const char *kill_who_to_string(KillWho k) _const_; KillWho kill_who_from_string(const char *s) _pure_; -int machine_openpt(Machine *m, int flags); +int machine_openpt(Machine *m, int flags, char **ret_slave); int machine_open_terminal(Machine *m, const char *path, int mode); int machine_get_uid_shift(Machine *m, uid_t *ret); |