46 #ifdef __INTEL_COMPILER
52 #include <sys/types.h>
53 #include <sys/ioctl.h>
55 #include <sys/resource.h>
57 #include <sys/param.h>
71 # if defined(HAVE_PTY_H)
74 # ifdef HAVE_LIBUTIL_H
76 # elif defined(HAVE_UTIL_H)
104 #if defined(HAVE_TERMIO_H)
109 #if defined (_HPUX_SOURCE)
110 # define _TERMIOS_INCLUDED
114 #ifdef HAVE_SYS_STROPTS_H
115 # include <sys/stropts.h>
116 # define _NEW_TTY_CTRL
119 #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
120 # define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
122 # if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__)
123 # define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
125 # define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
129 #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
130 # define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
132 # if defined(_HPUX_SOURCE) || defined(__CYGWIN__)
133 # define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
135 # define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
143 # define CTRL(x) ((x) & 037)
146 #define TTY_GROUP "tty"
157 masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent)
162 masterFd(_masterFd), slaveFd(_slaveFd), ownMaster(true), q_ptr(parent)
210 if (
d->masterFd >= 0) {
228 if (::openpty( &
d->masterFd, &
d->slaveFd, ptsn, 0, 0))
232 qWarning() <<
"Can't open a pseudo teletype";
239 #ifdef HAVE__GETPTY // irix
241 char *ptsn = _getpty(&
d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
247 #elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)
249 #ifdef HAVE_POSIX_OPENPT
250 d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
251 #elif defined(HAVE_GETPT)
252 d->masterFd = ::getpt();
253 #elif defined(PTM_DEVICE)
254 d->masterFd =
::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
256 # error No method to open a PTY master detected.
258 if (
d->masterFd >= 0)
261 char *ptsn = ptsname(
d->masterFd);
266 if (!ioctl(
d->masterFd, TIOCGPTN, &ptyno)) {
268 sprintf(buf,
"/dev/pts/%d", ptyno);
272 if (!grantpt(
d->masterFd))
281 #endif // HAVE_PTSNAME || TIOCGPTN
284 for (
const char* s3 =
"pqrstuvwxyzabcde"; *s3; s3++)
286 for (
const char* s4 =
"0123456789abcdef"; *s4; s4++)
288 ptyName = QString().sprintf(
"/dev/pty%c%c", *s3, *s4).toAscii();
289 d->ttyName = QString().sprintf(
"/dev/tty%c%c", *s3, *s4).toAscii();
291 d->masterFd =
::open(ptyName.data(), O_RDWR);
292 if (
d->masterFd >= 0)
300 if (ioctl(
d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
306 if (!access(
d->ttyName.data(),R_OK|W_OK))
312 p = getgrnam(
"wheel");
313 gid_t gid = p ? p->gr_gid : getgid ();
315 if (!chown(
d->ttyName.data(), getuid(), gid)) {
316 chmod(
d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
327 qWarning() <<
"Can't open a pseudo teletype";
332 if (
stat(
d->ttyName.data(), &st))
336 if (((st.st_uid != getuid()) ||
337 (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
341 <<
"chownpty failed for device " << ptyName <<
"::" <<
d->ttyName
342 <<
"\nThis means the communication can be eavesdropped." << endl;
345 #if defined(HAVE_GRANTPT) || defined(HAVE__GETPTY)
350 revoke(
d->ttyName.data());
354 unlockpt(
d->masterFd);
355 #elif defined(TIOCSPTLCK)
357 ioctl(
d->masterFd, TIOCSPTLCK, &flag);
360 d->slaveFd =
::open(
d->ttyName.data(), O_RDWR | O_NOCTTY);
363 qWarning() <<
"Can't open slave pseudo teletype";
369 #if (defined(__svr4__) || defined(__sgi__))
371 ioctl(
d->slaveFd, I_PUSH,
"ptem");
372 ioctl(
d->slaveFd, I_PUSH,
"ldterm");
376 fcntl(
d->masterFd, F_SETFD, FD_CLOEXEC);
377 fcntl(
d->slaveFd, F_SETFD, FD_CLOEXEC);
381 t.c_lflag &= ~ECHOCTL;
406 if (memcmp(
d->ttyName.data(),
"/dev/pts/", 9)) {
409 if (!
stat(
d->ttyName.data(), &st)) {
410 if (!chown(
d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1)) {
411 chmod(
d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
415 fcntl(
d->masterFd, F_SETFD, 0);
446 struct winsize winSize;
447 memset(&winSize, 0,
sizeof(winSize));
448 winSize.ws_row = (
unsigned short)lines;
449 winSize.ws_col = (
unsigned short)columns;
450 return ioctl(
d->masterFd, TIOCSWINSZ, (
char *)&winSize) == 0;
455 struct ::termios ttmode;
459 ttmode.c_lflag &= ~
ECHO;
461 ttmode.c_lflag |=
ECHO;
469 return d->ttyName.data();