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, ioctling and closeing 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.