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(HAVE_TCGETATTR)
120 # define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
121 #elif defined(TIOCGETA)
122 # define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
123 #elif defined(TCGETS)
124 # define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
126 # error No method available to get terminal attributes
129 #if defined(HAVE_TCSETATTR) && defined(TCSANOW)
130 # define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
131 #elif defined(TIOCSETA)
132 # define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
133 #elif defined(TCSETS)
134 # define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
136 # error No method available to set terminal attributes
143 # define CTRL(x) ((x) & 037)
146 #define TTY_GROUP "tty"
150 # define PATH_MAX MAXPATHLEN
152 # define PATH_MAX 1024
165 masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent)
170 masterFd(_masterFd), slaveFd(_slaveFd), ownMaster(true), q_ptr(parent)
218 if (
d->masterFd >= 0) {
236 if (::openpty( &
d->masterFd, &
d->slaveFd, ptsn, 0, 0))
240 qWarning() <<
"Can't open a pseudo teletype";
247 #ifdef HAVE__GETPTY // irix
249 char *ptsn = _getpty(&
d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
255 #elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)
257 #ifdef HAVE_POSIX_OPENPT
258 d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
259 #elif defined(HAVE_GETPT)
260 d->masterFd = ::getpt();
261 #elif defined(PTM_DEVICE)
262 d->masterFd =
::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
264 # error No method to open a PTY master detected.
266 if (
d->masterFd >= 0)
269 char *ptsn = ptsname(
d->masterFd);
274 if (!ioctl(
d->masterFd, TIOCGPTN, &ptyno)) {
276 sprintf(buf,
"/dev/pts/%d", ptyno);
280 if (!grantpt(
d->masterFd))
289 #endif // HAVE_PTSNAME || TIOCGPTN
292 for (
const char* s3 =
"pqrstuvwxyzabcde"; *s3; s3++)
294 for (
const char* s4 =
"0123456789abcdef"; *s4; s4++)
296 ptyName = QString().sprintf(
"/dev/pty%c%c", *s3, *s4).toAscii();
297 d->ttyName = QString().sprintf(
"/dev/tty%c%c", *s3, *s4).toAscii();
299 d->masterFd =
::open(ptyName.data(), O_RDWR);
300 if (
d->masterFd >= 0)
308 if (ioctl(
d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
314 if (!access(
d->ttyName.data(),R_OK|W_OK))
320 p = getgrnam(
"wheel");
321 gid_t gid = p ? p->gr_gid : getgid ();
323 if (!chown(
d->ttyName.data(), getuid(), gid)) {
324 chmod(
d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
335 qWarning() <<
"Can't open a pseudo teletype";
340 if (
stat(
d->ttyName.data(), &st))
344 if (((st.st_uid != getuid()) ||
345 (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
349 <<
"chownpty failed for device " << ptyName <<
"::" <<
d->ttyName
350 <<
"\nThis means the communication can be eavesdropped." << endl;
353 #if defined(HAVE_GRANTPT) || defined(HAVE__GETPTY)
358 revoke(
d->ttyName.data());
362 unlockpt(
d->masterFd);
363 #elif defined(TIOCSPTLCK)
365 ioctl(
d->masterFd, TIOCSPTLCK, &flag);
368 d->slaveFd =
::open(
d->ttyName.data(), O_RDWR | O_NOCTTY);
371 qWarning() <<
"Can't open slave pseudo teletype";
377 #if (defined(__svr4__) || defined(__sgi__))
379 ioctl(
d->slaveFd, I_PUSH,
"ptem");
380 ioctl(
d->slaveFd, I_PUSH,
"ldterm");
384 fcntl(
d->masterFd, F_SETFD, FD_CLOEXEC);
385 fcntl(
d->slaveFd, F_SETFD, FD_CLOEXEC);
390 t.c_lflag &= ~ECHOCTL;
415 if (memcmp(
d->ttyName.data(),
"/dev/pts/", 9)) {
418 if (!
stat(
d->ttyName.data(), &st)) {
419 if (!chown(
d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1)) {
420 chmod(
d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
424 fcntl(
d->masterFd, F_SETFD, 0);
441 return _tcgetattr(
d->masterFd, ttmode) == 0;
448 return _tcsetattr(
d->masterFd, ttmode) == 0;
455 struct winsize winSize;
456 memset(&winSize, 0,
sizeof(winSize));
457 winSize.ws_row = (
unsigned short)lines;
458 winSize.ws_col = (
unsigned short)columns;
459 return ioctl(
d->masterFd, TIOCSWINSZ, (
char *)&winSize) == 0;
464 struct ::termios ttmode;
468 ttmode.c_lflag &= ~
ECHO;
470 ttmode.c_lflag |=
ECHO;
478 return d->ttyName.data();
bool chownpty(bool grant)
const char * ttyName() const
bool tcGetAttr(struct::termios *ttmode) const
Wrapper around tcgetattr(3).
void closeSlave()
Close the pty slave descriptor.
bool open()
Create a pty master/slave pair.
F77_RET_T const double const double double * d
bool setWinSize(int lines, int columns)
Change the logical (screen) size of the pty.
void close()
Close the pty master/slave pair.
bool tcSetAttr(struct::termios *ttmode)
Wrapper around tcsetattr(3) with mode TCSANOW.
subroutine stat(x, n, av, var, xmin, xmax)
KPtyPrivate(KPty *parent)
bool setEcho(bool echo)
Set whether the pty should echo input.
Provides primitives for opening & closing a pseudo TTY pair, assigning the controlling TTY...