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().
This commit is contained in:
parent
3acc84ebd9
commit
ae1d13db05
|
@ -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)
|
||||
fd = openpt_allocate(flags, NULL);
|
||||
if (fd < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
if (unlockpt(master) < 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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
case MACHINE_HOST:
|
||||
|
||||
fd = posix_openpt(flags);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (unlockpt(fd) < 0)
|
||||
return -errno;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue