diff options
Diffstat (limited to 'openbsd-compat/bsd-openpty.c')
-rw-r--r-- | openbsd-compat/bsd-openpty.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/openbsd-compat/bsd-openpty.c b/openbsd-compat/bsd-openpty.c index 1ab41f42..078d666c 100644 --- a/openbsd-compat/bsd-openpty.c +++ b/openbsd-compat/bsd-openpty.c @@ -71,28 +71,11 @@ #define O_NOCTTY 0 #endif -int -openpty(int *amaster, int *aslave, char *name, struct termios *termp, +#if defined(HAVE_DEV_PTMX) && !defined(HAVE__GETPTY) +static int +openpty_streams(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { -#if defined(HAVE__GETPTY) - /* - * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more - * pty's automagically when needed - */ - char *slave; - - if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL) - return (-1); - - /* Open the slave side. */ - if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) { - close(*amaster); - return (-1); - } - return (0); - -#elif defined(HAVE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) @@ -141,9 +124,53 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, # ifndef __hpux ioctl(*aslave, I_PUSH, "ttcompat"); # endif /* __hpux */ + return (0); +} +#endif + +int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, + struct winsize *winp) +{ +#if defined(HAVE__GETPTY) + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL) + return (-1); + /* Open the slave side. */ + if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } return (0); +#elif defined(HAVE_DEV_PTMX) + +#ifdef SSHD_ACQUIRES_CTTY + /* + * On some (most? all?) SysV based systems with STREAMS based terminals, + * sshd will acquire a controlling terminal when it pushes the "ptem" + * module. On such platforms, first allocate a sacrificial pty so + * that sshd already has a controlling terminal before allocating the + * one that will be passed back to the user process. This ensures + * the second pty is not already the controlling terminal for a + * different session and is available to become controlling terminal + * for the client's subprocess. See bugzilla #245 for details. + */ + static int junk_ptyfd = -1, junk_ttyfd; + + if (junk_ptyfd == -1) + (void)openpty_streams(&junk_ptyfd, &junk_ttyfd, NULL, NULL, + NULL); +#endif + + return openpty_streams(amaster, aslave, name, termp, winp); + #elif defined(HAVE_DEV_PTS_AND_PTC) /* AIX-style pty code. */ const char *ttname; |