Permalink
Browse files

Implement openpty

  • Loading branch information...
1 parent 391ab5e commit 2ea02037f97ffd63544f0cead31a528cb349cfba Dmitriy Kalinin and Pieter Noordhuis committed Mar 15, 2013
Showing with 73 additions and 27 deletions.
  1. +1 −1 warden/src/wsh/Makefile
  2. +61 −0 warden/src/wsh/pty.c
  3. +8 −0 warden/src/wsh/pty.h
  4. +3 −26 warden/src/wsh/wshd.c
View
@@ -11,7 +11,7 @@ install: all
.PHONY: all clean
-wshd: wshd.o barrier.o mount.o un.o util.o msg.o pwd.o
+wshd: wshd.o barrier.o mount.o un.o util.o msg.o pwd.o pty.o
$(CC) -static -o $@ $^ -lutil
wsh: wsh.o pump.o un.o util.o msg.o pwd.o
View
@@ -0,0 +1,61 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <pty.h>
+
+#include "pty.h"
+
+/* Instead of using openpty from glibc, the following custom version is used
+ * because we need to bypass dynamically loading the nsswitch libraries.
+ * Executing glibc's openpty calls grantpt, which in turn depends on nsswitch
+ * being loaded. The version of glibc inside a container may be different than
+ * the version that wshd is compiled for, leading to undefined behavior. */
+int openpty(int *master, int *slave, char *slave_name) {
+ int rv;
+ int lock;
+ int pty;
+ char buf[32];
+
+ /* Open master */
+ rv = open("/dev/ptmx", O_RDWR | O_NOCTTY);
+ if (rv == -1) {
+ return -1;
+ }
+
+ *master = rv;
+
+ /* Figure out PTY number */
+ pty = 0;
+ rv = ioctl(*master, TIOCGPTN, &pty);
+ if (rv == -1) {
+ return -1;
+ }
+
+ rv = snprintf(buf, sizeof(buf), "/dev/pts/%d", pty);
+ if (rv >= sizeof(buf)) {
+ return -1;
+ }
+
+ /* Unlock slave before opening it */
+ lock = 0;
+ rv = ioctl(*master, TIOCSPTLCK, &lock);
+ if (rv == -1) {
+ return -1;
+ }
+
+ /* Open slave */
+ rv = open(buf, O_RDWR | O_NOCTTY);
+ if (rv == -1) {
+ return -1;
+ }
+
+ *slave = rv;
+ if (slave_name != NULL) {
+ strcpy(slave_name, buf);
+ }
+
+ return 0;
+}
View
@@ -0,0 +1,8 @@
+#ifndef PTY_H
+#define PTY_H
+
+#define openpty __wshd_openpty
+
+int openpty(int *master, int *slave, char *name);
+
+#endif
View
@@ -23,6 +23,7 @@
#include "barrier.h"
#include "msg.h"
#include "mount.h"
+#include "pty.h"
#include "pwd.h"
#include "un.h"
#include "util.h"
@@ -356,36 +357,12 @@ int child_handle_interactive(int fd, wshd_t *w, msg_request_t *req) {
fcntl_mix_cloexec(p[1][0]);
fcntl_mix_cloexec(p[1][1]);
- rv = posix_openpt(O_RDWR | O_NOCTTY);
+ rv = openpty(&p[0][0], &p[0][1], NULL);
if (rv < 0) {
- perror("posix_openpt");
+ perror("openpty");
abort();
}
- /* Master side of the pseudo TTY */
- p[0][0] = rv;
-
- rv = grantpt(p[0][0]);
- if (rv < 0) {
- perror("grantpt");
- abort();
- }
-
- rv = unlockpt(p[0][0]);
- if (rv < 0) {
- perror("unlockpt");
- abort();
- }
-
- rv = open(ptsname(p[0][0]), O_RDWR);
- if (rv < 0) {
- perror("open");
- abort();
- }
-
- /* Slave side of the pseudo TTY */
- p[0][1] = rv;
-
fcntl_mix_cloexec(p[0][0]);
fcntl_mix_cloexec(p[0][1]);

0 comments on commit 2ea0203

Please sign in to comment.