"Failed to disconnect from controlling tty."

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.

Still thinking on the nature of the “logout hang”…

If I forcebly allocate the tty when executing a command - “ssh -t localhost who” - ssh hangs as if I was logged in. It takes typing “~.” to get out.

If I try it this way - “ssh -t localhost who </dev/null >/dev/null 2>&1” - I get no output from the command but ssh logs out without any help.

So, the “logout hang” and “failing to disconnect from controlling tty” are somehow related.

Please comment.

Tony.

Yes, indeed, the “failure to disconnect from the controlling tty” is the cause of the logout hang.

When I do (as root) “ssh localhost su user” - I get the quite operational console (however it does not have “$” prompt) and I can type “logout” and it really logs me out.
If I do “ssh -t localhost su admin” - then problems are back - I cannot “logout” properly…

I wish I could fix this “failure to disconnect from controlling tty” issue!

Tony.

This is a snip from the code:
/*
pty-bsd.c

Author: Tatu Ylonen <ylo@ssh.fi>

Copyright (c) 1997 SSH Communications Security, Finland
All rights reserved

Allocating a pty on a generic BSD-like system.
*/

/* Makes the given tty the controlling tty of the current process.
This may close and reopen the original file descriptor. When called,
*ttyfd should be a valid file descriptor for the slave side, and ttyname
should contain its name (e.g., “/dev/ttyp3”). Returns FALSE if the
controlling tty could not be set. */

Boolean ssh_pty_internal_make_ctty(int *ttyfd, const char *ttyname)
{
int fd;

/* First disconnect from the old controlling tty. */
fd = open("/dev/tty", O_RDWR|O_NOCTTY);
if (fd >= 0) {
(void)ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}

/* Verify that we are successfully disconnected from the controlling tty. */
fd = open("/dev/tty", O_RDWR|O_NOCTTY);
if (fd >= 0) {
ssh_warning(“Failed to disconnect from controlling tty.”);
close(fd);
}

/* Make it our controlling tty. */
ssh_debug(“Setting controlling tty using TIOCSCTTY.”);
ioctl(*ttyfd, TIOCSCTTY, NULL);

if ( setsid() == -1 ) ssh_warning(“setsid() failed.”);

}

When running it under QNX v4.25G I get both warnings - “Failed to disconnect…” and “setsid() failed.”. What’s wrong with this code?
Reading the archives on inn.qnx.com I saw postings regarding troubles with “controlling tty”, but there was no hint if it was solved.

Tony.

PS Actually, SSH2 works but litters syslog with those warnings…