aboutsummaryrefslogtreecommitdiff
path: root/src/util/pty/open_slave.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/pty/open_slave.c')
-rw-r--r--src/util/pty/open_slave.c108
1 files changed, 55 insertions, 53 deletions
diff --git a/src/util/pty/open_slave.c b/src/util/pty/open_slave.c
index aea04de..cc52228 100644
--- a/src/util/pty/open_slave.c
+++ b/src/util/pty/open_slave.c
@@ -1,7 +1,8 @@
/*
* pty_open_slave: open slave side of terminal, clearing for use.
*
- * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
+ * Copyright 1995, 1996, 2001 by the Massachusetts Institute of
+ * Technology.
*
*
* Permission to use, copy, modify, and distribute this software and
@@ -24,76 +25,77 @@
#include "libpty.h"
#include "pty-int.h"
-
-long pty_open_slave ( slave, fd)
- const char *slave;
- int *fd;
+long
+pty_open_slave(const char *slave, int *fd)
{
- int vfd, testfd;
+ int tmpfd;
long retval;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
- /* Initialize "sa" structure. */
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-
-#endif
+ /* Sanity check. */
+ if (slave == NULL || *slave == '\0')
+ return PTY_OPEN_SLAVE_TOOSHORT;
+
+ /* First, set up a new session and void old associations. */
+ ptyint_void_association();
- /* First, chmod and chown the slave*/
/*
- * If we have vhangup then we really need pty_open_ctty to make sure
- * Our controlling terminal is the pty we're opening. However, if we
- * are using revoke or nothing then we just need a file descriiptor
- * for the pty. Considering some OSes in this category break on
- * the second call to open_ctty (currently OSF but others may),
- * we simply use a descriptor if we can.
- */
-#ifdef VHANG_FIRST
- if (( retval = pty_open_ctty ( slave, &vfd )) != 0 )
- return retval;
- if (vfd < 0)
+ * Make a first attempt at acquiring the ctty under certain
+ * condisions. This is necessary for several reasons:
+ *
+ * Under Irix, if you open a pty slave and then close it, a
+ * subsequent open of the slave will cause the master to read EOF.
+ * To prevent this, don't close the first fd until we do the real
+ * open following vhangup().
+ *
+ * Under Tru64 v5.0, if there isn't a fd open on the slave,
+ * revoke() fails with ENOTTY, curiously enough.
+ *
+ * Anyway, sshd seems to make a practice of doing this.
+ */
+#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN)
+ retval = pty_open_ctty(slave, fd);
+ if (retval)
+ return retval;
+ if (*fd < 0)
return PTY_OPEN_SLAVE_OPENFAIL;
-
#endif
-
- if (slave == NULL || *slave == '\0')
- return PTY_OPEN_SLAVE_TOOSHORT;
- if (chmod(slave, 0))
- return PTY_OPEN_SLAVE_CHMODFAIL;
- if ( chown(slave, 0, 0 ) == -1 )
- return PTY_OPEN_SLAVE_CHOWNFAIL;
+ /* chmod and chown the slave. */
+ if (chmod(slave, 0))
+ return PTY_OPEN_SLAVE_CHMODFAIL;
+ if (chown(slave, 0, 0) == -1)
+ return PTY_OPEN_SLAVE_CHOWNFAIL;
-#ifdef VHANG_FIRST
- ptyint_vhangup();
- (void) close(vfd);
-#endif
-
- if ( (retval = ptyint_void_association()) != 0)
- return retval;
-
#ifdef HAVE_REVOKE
- if (revoke (slave) < 0 ) {
+ if (revoke(slave) < 0) {
return PTY_OPEN_SLAVE_REVOKEFAIL;
}
-#endif /*HAVE_REVOKE*/
+#else /* !HAVE_REVOKE */
+#ifdef VHANG_FIRST
+ ptyint_vhangup();
+#endif
+#endif /* !HAVE_REVOKE */
-/* Open the pty for real. */
- if (( retval = pty_open_ctty ( slave, fd)) != 0 ) {
+ /* Open the pty for real. */
+ retval = pty_open_ctty(slave, &tmpfd);
+#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN)
+ close(*fd);
+#endif
+ if (retval) {
+ *fd = -1;
return PTY_OPEN_SLAVE_OPENFAIL;
}
- retval = pty_initialize_slave (*fd);
-
+ *fd = tmpfd;
+ retval = pty_initialize_slave(*fd);
if (retval)
- return retval;
- testfd = open("/dev/tty", O_RDWR|O_NDELAY);
- if ( testfd < 0 )
- {
+ return retval;
+ /* Make sure it's really our ctty. */
+ tmpfd = open("/dev/tty", O_RDWR|O_NDELAY);
+ if (tmpfd < 0) {
close(*fd);
*fd = -1;
return PTY_OPEN_SLAVE_NOCTTY;
- }
- close(testfd);
+ }
+ close(tmpfd);
return 0;
}