This is a part of ssh-1.2.33 ported to QNX v4 by J.C.Michot.
If a remote user requests tty allocation - sshd logs “Failed to disconnect
from controlling tty.” but works…
Debugging shows that the only thing that happens here not the same way as in
unixes is the ctname - it is “//2/dev/ttyp0”, not just plain “/dev/tty”.
Opening it, ioctl-ing and closing it and reopening it goes OK. I can see that it’s fd
is of value 3 before and after the check.
/*
pty.c
Author: Tatu Ylonen <ylo@ssh.fi>
Copyright (c) 1995 Tatu Ylonen <ylo@ssh.fi>, Espoo, Finland
Copyright (c) 1995-1999 SSH Communications Security Oy, Espoo, Finland
All rights reserved
Created: Fri Mar 17 04:37:25 1995 ylo
Allocating a pseudo-terminal, and making it the controlling tty.
*/
…snip…
/* Makes the tty the processes controlling tty and sets it to sane modes. */
void pty_make_controlling_tty(int *ttyfd, const char *ttyname)
{
int fd;
#ifdef QNX
int cterr = 0;
#endif
char *ctname = “/dev/tty”;
#ifdef QNX
if (!(ctname = ctermid(NULL)) || ctname == ‘\0’)
error(“Failed to find the controlling tty.”);
else
{
#endif
/ First disconnect from the old controlling tty. /
#ifdef TIOCNOTTY
fd = open(ctname, O_RDWR|O_NOCTTY);
if (fd >= 0)
{
(void)ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
#endif / TIOCNOTTY */
/* Verify that we are successfully disconnected from the controlling tty. */
fd = open(ctname, O_RDWR|O_NOCTTY);
if (fd >= 0)
{
error(“Failed to disconnect from controlling tty.”);
close(fd);
}
#ifdef QNX
}
#endif
/* Make it our controlling tty. */
#ifdef QNX
debug(“Setting controlling tty using tcsetct().”);
if ((cterr = tcsetct(ttyfd, getpid())) == -1)
error(“tcsetct() on %.100s failed: %.100s”, ttyname, strerror(errno));
#else
#ifdef TIOCSCTTY
debug(“Setting controlling tty using TIOCSCTTY.”);
/ We ignore errors from this, because HPSUX defines TIOCSCTTY, but returns
EINVAL with these arguments, and there is absolutely no documentation. */
ioctl(ttyfd, TIOCSCTTY, NULL);
#endif / TIOCSCTTY /
#endif / QNX */
#ifdef QNX
fcntl(*ttyfd, F_SETFD, FD_CLOEXEC);
#endif
…snip…
#ifdef HAVE_SETPGID
/* This appears to be necessary on some machines… */
setpgid(0, 0);
#endif
fd = open(ttyname, O_RDWR);
if (fd < 0)
error(“open %.100s failed: %.100s”, ttyname, strerror(errno));
#ifndef QNX
else
close(fd);
#endif
#ifdef QNX
if (cterr == -1)
{
if (fd >= 0) close(fd);
close(*ttyfd);
*ttyfd = -1;
}
else
{
close(*ttyfd);
ttyfd = fd;
}
#else
/ Verify that we now have a controlling tty. */
fd = open(ctname, O_WRONLY);
if (fd < 0)
error(“open %s failed; could not set controlling tty: %.100s”,
ctname, strerror(errno));
else
{
close(fd);
#if defined(HAVE_VHANGUP) && !defined(HAVE_REVOKE)
signal(SIGHUP, SIG_IGN);
vhangup();
signal(SIGHUP, SIG_DFL);
fd = open(ttyname, O_RDWR);
if (fd == -1)
error(“pty_make_controlling_tty: reopening controlling tty after vhangup failed for %.100s”,
ttyname);
close(*ttyfd);
ttyfd = fd;
#endif / HAVE_VHANGUP && !HAVE_REVOKE /
}
#endif / QNX */
}
…snip…
What is the correct way of doing this in QNX v4?
Tony.