44 #ifdef __INTEL_COMPILER
50 #include <sys/types.h>
51 #include <sys/ioctl.h>
53 #include <sys/resource.h>
55 #include <sys/param.h>
57 #ifdef HAVE_SYS_STROPTS_H
58 # include <sys/stropts.h>
59 # define _NEW_TTY_CTRL
71 #if defined(HAVE_LIBUTIL_H)
73 # if (!defined(__FreeBSD__) || __FreeBSD_version < 900007)
77 #if defined(HAVE_UTIL_H)
101 #if defined(HAVE_TCGETATTR)
102 # define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
103 #elif defined(TIOCGETA)
104 # define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
105 #elif defined(TCGETS)
106 # define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
111 #if defined(HAVE_TCSETATTR) && defined(TCSANOW)
112 # define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
113 #elif defined(TIOCSETA)
114 # define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
115 #elif defined(TCSETS)
116 # define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
121 #if defined (_HPUX_SOURCE)
122 # define _TERMIOS_INCLUDED
126 #if defined(HAVE_PTY_H)
131 #include <kstandarddirs.h>
143 #define TTY_GROUP "tty"
164 #define BASE_CHOWN "kgrantpty"
176 masterFd(-1), slaveFd(-1)
178 memset(&winSize, 0,
sizeof(winSize));
187 struct winsize winSize;
210 if(d->masterFd >= 0) {
211 kdWarning(175) <<
"KPty::setPty(): " <<
"d->masterFd >= 0" <<
endl;
214 d->masterFd = pty_master;
215 return _attachPty(pty_master);
218 bool KPty::_attachPty(
int pty_master)
222 kdDebug(175) <<
"KPty::_attachPty(): " << pty_master <<
endl;
223 #if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT)
224 char *ptsn = ptsname(d->masterFd);
226 grantpt(d->masterFd);
235 if (stat(d->ttyName.data(), &st))
239 if (((st.st_uid != getuid()) ||
240 (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
244 <<
"KPty::_attachPty(): " <<
"chownpty failed for device " << ptyName <<
"::" << d->ttyName << endl
245 <<
"KPty::_attachPty(): " <<
"This means the communication can be eavesdropped." <<
endl;
249 revoke(d->ttyName.data());
253 unlockpt(d->masterFd);
256 d->slaveFd =
::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
259 kdWarning(175) <<
"KPty::_attachPty(): " <<
"Can't open slave pseudo teletype" <<
endl;
265 #if (defined(__svr4__) || defined(__sgi__))
267 ioctl(d->slaveFd, I_PUSH,
"ptem");
268 ioctl(d->slaveFd, I_PUSH,
"ldterm");
275 struct ::termios ttmode;
277 _tcgetattr(d->slaveFd, &ttmode);
280 ttmode.c_iflag &= ~(IXOFF | IXON);
282 ttmode.c_iflag |= (IXOFF | IXON);
286 ttmode.c_iflag &= ~IUTF8;
288 ttmode.c_iflag |= IUTF8;
291 ttmode.c_cc[VINTR] = CINTR;
292 ttmode.c_cc[VQUIT] = CQUIT;
293 ttmode.c_cc[VERASE] = CERASE;
295 _tcsetattr(d->slaveFd, &ttmode);
298 ioctl(d->slaveFd, TIOCSWINSZ, (
char *)&d->winSize);
300 fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
301 fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
308 if (d->masterFd >= 0)
311 #if defined(__OpenBSD__) || defined(__FreeBSD__)
314 if (openpty(&d->masterFd, &d->slaveFd, cpty, NULL, &d->winSize) == 0) {
317 kdWarning(175) <<
"Can't open slave pseudo teletype" <<
endl;
331 #if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT)
333 d->masterFd =
::open(
"/dev/ptc",O_RDWR);
335 d->masterFd =
::open(
"/dev/ptmx",O_RDWR);
337 if (d->masterFd >= 0)
339 char *ptsn = ptsname(d->masterFd);
341 grantpt(d->masterFd);
352 for (
const char* s3 =
"pqrstuvwxyzabcdefghijklmno"; *s3; s3++)
354 for (
const char* s4 =
"0123456789abcdefghijklmnopqrstuvwxyz"; *s4; s4++)
356 ptyName.sprintf(
"/dev/pty%c%c", *s3, *s4);
357 d->ttyName.sprintf(
"/dev/tty%c%c", *s3, *s4);
359 d->masterFd =
::open(ptyName.data(), O_RDWR);
360 if (d->masterFd >= 0)
368 if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
374 if (!access(d->ttyName.data(),R_OK|W_OK))
378 struct group* p = getgrnam(TTY_GROUP);
380 p = getgrnam(
"wheel");
381 gid_t gid = p ? p->gr_gid : getgid ();
383 chown(d->ttyName.data(), getuid(), gid);
384 chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
394 kdWarning(175) <<
"KPty::open(): " <<
"Can't open a pseudo teletype" <<
endl;
399 return _attachPty(d->masterFd);
409 if (memcmp(d->ttyName.data(),
"/dev/pts/", 9)) {
412 if (!stat(d->ttyName.data(), &st)) {
413 chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
414 chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
417 fcntl(d->masterFd, F_SETFD, 0);
423 d->masterFd = d->slaveFd = -1;
436 ioctl(d->slaveFd, TIOCSCTTY, 0);
444 #if defined(_POSIX_VERSION) || defined(__svr4__)
445 tcsetpgrp (d->slaveFd, pgrp);
446 #elif defined(TIOCSPGRP)
447 ioctl(d->slaveFd, TIOCSPGRP, (
char *)&pgrp);
454 TDEProcess_Utmp utmp;
455 utmp.cmdFd = d->masterFd;
456 utmp << UTEMPTER_HELPER <<
"add";
461 Q_UNUSED(remotehost);
462 #elif defined(USE_LOGIN)
464 struct utmp l_struct;
465 memset(&l_struct, 0,
sizeof(
struct utmp));
469 strncpy(l_struct.ut_name, user, UT_NAMESIZE);
472 strncpy(l_struct.ut_host, remotehost, UT_HOSTSIZE);
475 str_ptr = d->ttyName.data();
476 if (!memcmp(str_ptr,
"/dev/", 5))
478 strncpy(l_struct.ut_line, str_ptr, UT_LINESIZE);
486 l_struct.ut_time=ut_time_temp;
492 Q_UNUSED(remotehost);
499 TDEProcess_Utmp utmp;
500 utmp.cmdFd = d->masterFd;
501 utmp << UTEMPTER_HELPER <<
"del";
503 #elif defined(USE_LOGIN)
504 const char *str_ptr = d->ttyName.data();
505 if (!memcmp(str_ptr,
"/dev/", 5))
509 const char *sl_ptr = strrchr(str_ptr,
'/');
511 str_ptr = sl_ptr + 1;
520 d->winSize.ws_row = (
unsigned short)lines;
521 d->winSize.ws_col = (
unsigned short)columns;
522 if (d->masterFd >= 0)
523 ioctl( d->masterFd, TIOCSWINSZ, (
char *)&d->winSize );
528 d->xonXoff = useXonXoff;
529 if (d->masterFd >= 0) {
533 struct ::termios ttmode;
535 _tcgetattr(d->masterFd, &ttmode);
538 ttmode.c_iflag &= ~(IXOFF | IXON);
540 ttmode.c_iflag |= (IXOFF | IXON);
542 _tcsetattr(d->masterFd, &ttmode);
550 if (d->masterFd >= 0) {
554 struct ::termios ttmode;
556 _tcgetattr(d->masterFd, &ttmode);
559 ttmode.c_iflag &= ~IUTF8;
561 ttmode.c_iflag |= IUTF8;
563 _tcsetattr(d->masterFd, &ttmode);
570 return d->ttyName.data();
584 bool KPty::chownpty(
bool grant)
586 #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
588 proc << locate(
"exe", BASE_CHOWN) << (grant?
"--grant":
"--revoke") << TQString::number(d->masterFd);