/* * pty_open_slave: open slave side of terminal, clearing for use. * * Copyright 1995, 1996, 2001 by the Massachusetts Institute of * Technology. * * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of * M.I.T. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability * of this software for any purpose. It is provided "as is" without * express or implied warranty. * */ #include "com_err.h" #include "libpty.h" #include "pty-int.h" long pty_open_slave(const char *slave, int *fd) { int tmpfd; long retval; /* 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(); /* * 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 /* 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 HAVE_REVOKE if (revoke(slave) < 0) { return PTY_OPEN_SLAVE_REVOKEFAIL; } #else /* !HAVE_REVOKE */ #ifdef VHANG_FIRST ptyint_vhangup(); #endif #endif /* !HAVE_REVOKE */ /* 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; } *fd = tmpfd; retval = pty_initialize_slave(*fd); if (retval) 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(tmpfd); return 0; }