summaryrefslogtreecommitdiff
path: root/src/basic/terminal-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-07 22:45:48 +0200
committerLennart Poettering <lennart@poettering.net>2015-10-08 12:49:59 +0200
commit66cb2fde7b0ab6603775ad13c30c004f5fd88f0c (patch)
treeb046cf10f6245ccf8f1d32651f234f70a3ddba09 /src/basic/terminal-util.c
parent041f793b6b1e4b86edc909b4b2867463b3ef3efd (diff)
basic: move two more terminal-related calls into terminal-util.[ch]
Diffstat (limited to 'src/basic/terminal-util.c')
-rw-r--r--src/basic/terminal-util.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 22ee6ad83f..50a86a331c 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -1054,6 +1054,33 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
return 0;
}
+int ptsname_malloc(int fd, char **ret) {
+ size_t l = 100;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ for (;;) {
+ char *c;
+
+ c = new(char, l);
+ if (!c)
+ return -ENOMEM;
+
+ if (ptsname_r(fd, c, l) == 0) {
+ *ret = c;
+ return 0;
+ }
+ if (errno != ERANGE) {
+ free(c);
+ return -errno;
+ }
+
+ free(c);
+ l *= 2;
+ }
+}
+
int ptsname_namespace(int pty, char **ret) {
int no = -1, r;
@@ -1072,3 +1099,56 @@ 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;
+ _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ siginfo_t si;
+ pid_t child;
+ int r;
+
+ assert(pid > 0);
+
+ 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 = posix_openpt(flags|O_NOCTTY|O_CLOEXEC);
+ if (master < 0)
+ _exit(EXIT_FAILURE);
+
+ if (unlockpt(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);
+}