Mercurial > octave-nkf
view gui/src/terminal/kpty.cpp @ 13646:2e1f54803758
Lowered size limits for subwindows.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Tue, 23 Aug 2011 18:06:45 +0200 |
parents | 484a487f3999 |
children |
line wrap: on
line source
/* This file is part of the KDE libraries Copyright (C) 2002 Waldo Bastian <bastian@kde.org> Copyright (C) 2002-2003,2007-2008 Oswald Buddenhagen <ossi@kde.org> Copyright (C) 2010 KDE e.V. <kde-ev-board@kde.org> Author Adriaan de Groot <groot@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kpty_p.h" #include <fcntl.h> #include <stdio.h> #include <pty.h> #include <utmp.h> /* for HP-UX (some versions) the extern C is needed, and for other platforms it doesn't hurt */ extern "C" { #include <termios.h> } #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__) #define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode) #else #if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__) || defined(__sun) #define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode) #else #define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode) #endif #endif #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__) #define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode) #else #if defined(_HPUX_SOURCE) || defined(__CYGWIN__) || defined(__sun) #define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode) #else #define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode) #endif #endif #include <QtCore/Q_PID> #define TTY_GROUP "tty" KPtyPrivate::KPtyPrivate (KPty * parent): masterFd (-1), slaveFd (-1), ownMaster (true), q_ptr (parent) { } KPtyPrivate::~KPtyPrivate () { } KPty::KPty (): d_ptr (new KPtyPrivate (this)) { } KPty::KPty (KPtyPrivate * d): d_ptr (d) { d_ptr->q_ptr = this; } KPty::~KPty () { close (); delete d_ptr; } bool KPty::open () { Q_D (KPty); if (d->masterFd >= 0) return true; d->ownMaster = true; QByteArray ptyName; // Find a master pty that we can open //////////////////////////////// // Because not all the pty animals are created equal, they want to // be opened by several different methods. // We try, as we know them, one by one. char ptsn[PATH_MAX]; if (::openpty (&d->masterFd, &d->slaveFd, ptsn, 0, 0)) { d->masterFd = -1; d->slaveFd = -1; return false; } d->ttyName = ptsn; fcntl (d->masterFd, F_SETFD, FD_CLOEXEC); fcntl (d->slaveFd, F_SETFD, FD_CLOEXEC); return true; } bool KPty::open (int fd) { Q_D (KPty); if (d->masterFd >= 0) { return false; } d->ownMaster = false; int ptyno; if (!ioctl (fd, TIOCGPTN, &ptyno)) { char buf[32]; sprintf (buf, "/dev/pts/%d", ptyno); d->ttyName = buf; } else { return false; } d->masterFd = fd; if (!openSlave ()) { d->masterFd = -1; return false; } return true; } void KPty::closeSlave () { Q_D (KPty); if (d->slaveFd < 0) return; ::close (d->slaveFd); d->slaveFd = -1; } bool KPty::openSlave () { Q_D (KPty); if (d->slaveFd >= 0) return true; if (d->masterFd < 0) { return false; } d->slaveFd =::open (d->ttyName.data (), O_RDWR | O_NOCTTY); if (d->slaveFd < 0) { return false; } fcntl (d->slaveFd, F_SETFD, FD_CLOEXEC); return true; } void KPty::close () { Q_D (KPty); if (d->masterFd < 0) return; closeSlave (); if (d->ownMaster) { ::close (d->masterFd); } d->masterFd = -1; } void KPty::setCTty () { Q_D (KPty); // Setup job control ////////////////////////////////// // Become session leader, process group leader, // and get rid of the old controlling terminal. setsid (); // make our slave pty the new controlling terminal. ioctl (d->slaveFd, TIOCSCTTY, 0); // make our new process group the foreground group on the pty int pgrp = getpid (); tcsetpgrp (d->slaveFd, pgrp); } void KPty::login (const char *user, const char *remotehost) { struct utmp l_struct; memset (&l_struct, 0, sizeof (l_struct)); // note: strncpy without terminators _is_ correct here. man 4 utmp if (user) strncpy (l_struct.ut_name, user, sizeof (l_struct.ut_name)); if (remotehost) { strncpy (l_struct.ut_host, remotehost, sizeof (l_struct.ut_host)); } l_struct.ut_time = time (0); utmpname (_PATH_UTMP); setutent (); pututline (&l_struct); endutent (); updwtmp (_PATH_WTMP, &l_struct); } void KPty::logout () { Q_D (KPty); const char *str_ptr = d->ttyName.data (); if (!memcmp (str_ptr, "/dev/", 5)) str_ptr += 5; else { const char *sl_ptr = strrchr (str_ptr, '/'); if (sl_ptr) str_ptr = sl_ptr + 1; } struct utmp l_struct, *ut; memset (&l_struct, 0, sizeof (l_struct)); strncpy (l_struct.ut_line, str_ptr, sizeof (l_struct.ut_line)); utmpname (_PATH_UTMP); setutent (); if ((ut = getutline (&l_struct))) { memset (ut->ut_name, 0, sizeof (*ut->ut_name)); memset (ut->ut_host, 0, sizeof (*ut->ut_host)); ut->ut_time = time (0); pututline (ut); } endutent (); } bool KPty::tcGetAttr (struct::termios * ttmode) const { Q_D (const KPty); return _tcgetattr (d->masterFd, ttmode) == 0; } bool KPty::tcSetAttr (struct::termios * ttmode) { Q_D (KPty); return _tcsetattr (d->masterFd, ttmode) == 0; } bool KPty::setWinSize (int lines, int columns) { Q_D (KPty); struct winsize winSize; memset (&winSize, 0, sizeof (winSize)); winSize.ws_row = (unsigned short) lines; winSize.ws_col = (unsigned short) columns; return ioctl (d->masterFd, TIOCSWINSZ, (char *) &winSize) == 0; } bool KPty::setEcho (bool echo) { struct::termios ttmode; if (!tcGetAttr (&ttmode)) return false; if (!echo) ttmode.c_lflag &= ~ECHO; else ttmode.c_lflag |= ECHO; return tcSetAttr (&ttmode); } const char * KPty::ttyName () const { Q_D (const KPty); return d->ttyName.data (); } int KPty::masterFd () const { Q_D (const KPty); return d->masterFd; } int KPty::slaveFd () const { Q_D (const KPty); return d->slaveFd; }