changeset 13647:ac3d9480292d

Renamed file.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Tue, 23 Aug 2011 18:22:27 +0200
parents 2e1f54803758
children da69cec2459f
files gui/octave-gui.pro gui/src/terminal/KPty.cpp gui/src/terminal/KPty.h gui/src/terminal/KPtyDevice.cpp gui/src/terminal/KPtyDevice.h gui/src/terminal/LinuxTerminalEmulation.h gui/src/terminal/kpty.cpp gui/src/terminal/kpty.h gui/src/terminal/kpty_p.h gui/src/terminal/kptydevice.cpp gui/src/terminal/kptydevice.h
diffstat 11 files changed, 1222 insertions(+), 1270 deletions(-) [+]
line wrap: on
line diff
--- a/gui/octave-gui.pro	Tue Aug 23 18:06:45 2011 +0200
+++ b/gui/octave-gui.pro	Tue Aug 23 18:22:27 2011 +0200
@@ -58,8 +58,6 @@
 # Files associated with the project:
 SOURCES +=\
         src/lexer/lexeroctavegui.cpp \
-        src/terminal/kpty.cpp \
-        src/terminal/kptydevice.cpp \
         src/MainWindow.cpp \
     	  src/OctaveTerminal.cpp \
     	  src/VariablesDockWidget.cpp \
@@ -79,13 +77,12 @@
     src/qirc/IRCClientImpl.cpp \
     src/terminal/TerminalEmulation.cpp \
     src/terminal/LinuxTerminalEmulation.cpp \
-    src/backend/ReadlineAdapter.cpp
+    src/backend/ReadlineAdapter.cpp \
+    src/terminal/KPty.cpp \
+    src/terminal/KPtyDevice.cpp
 
 HEADERS += \
         src/lexer/lexeroctavegui.h \
-        src/terminal/kpty.h \
-        src/terminal/kpty_p.h \
-        src/terminal/kptydevice.h \
     	  src/MainWindow.h \
     	  src/OctaveTerminal.h \
     	  src/VariablesDockWidget.h \
@@ -105,7 +102,9 @@
     src/qirc/IRCClientImpl.h \
     src/terminal/TerminalEmulation.h \
     src/terminal/LinuxTerminalEmulation.h \
-    src/backend/ReadlineAdapter.h
+    src/backend/ReadlineAdapter.h \
+    src/terminal/KPtyDevice.h \
+    src/terminal/KPty.h
 
 FORMS += \
     src/SettingsDialog.ui
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/terminal/KPty.cpp	Tue Aug 23 18:22:27 2011 +0200
@@ -0,0 +1,342 @@
+/*
+
+   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.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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/terminal/KPty.h	Tue Aug 23 18:22:27 2011 +0200
@@ -0,0 +1,219 @@
+/* This file is part of the KDE libraries
+
+    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@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.
+*/
+
+#ifndef kpty_h
+#define kpty_h
+
+#include <QtCore/qglobal.h>
+#include <QByteArray>
+
+class KPty;
+struct KPtyPrivate
+{
+  Q_DECLARE_PUBLIC (KPty) KPtyPrivate (KPty * parent);
+  virtual ~ KPtyPrivate ();
+  bool chownpty (bool grant);
+
+  int masterFd;
+  int slaveFd;
+  bool ownMaster:1;
+
+  QByteArray ttyName;
+
+  KPty *q_ptr;
+};
+
+struct termios;
+
+/**
+ * Provides primitives for opening & closing a pseudo TTY pair, assigning the
+ * controlling TTY, utmp registration and setting various terminal attributes.
+ */
+class KPty
+{
+Q_DECLARE_PRIVATE (KPty) public:
+
+  /**
+   * Constructor
+   */
+  KPty ();
+
+  /**
+   * Destructor:
+   *
+   *  If the pty is still open, it will be closed. Note, however, that
+   *  an utmp registration is @em not undone.
+  */
+  ~KPty ();
+
+  /**
+   * Create a pty master/slave pair.
+   *
+   * @return true if a pty pair was successfully opened
+   */
+  bool open ();
+
+  /**
+   * Open using an existing pty master.
+   *
+   * @param fd an open pty master file descriptor.
+   *   The ownership of the fd remains with the caller;
+   *   it will not be automatically closed at any point.
+   * @return true if a pty pair was successfully opened
+   */
+  bool open (int fd);
+
+  /**
+   * Close the pty master/slave pair.
+   */
+  void close ();
+
+  /**
+   * Close the pty slave descriptor.
+   *
+   * When creating the pty, KPty also opens the slave and keeps it open.
+   * Consequently the master will never receive an EOF notification.
+   * Usually this is the desired behavior, as a closed pty slave can be
+   * reopened any time - unlike a pipe or socket. However, in some cases
+   * pipe-alike behavior might be desired.
+   *
+   * After this function was called, slaveFd() and setCTty() cannot be
+   * used.
+   */
+  void closeSlave ();
+
+  /**
+   * Open the pty slave descriptor.
+   *
+   * This undoes the effect of closeSlave().
+   *
+   * @return true if the pty slave was successfully opened
+   */
+  bool openSlave ();
+
+  /**
+   * Creates a new session and process group and makes this pty the
+   * controlling tty.
+   */
+  void setCTty ();
+
+  /**
+   * Creates an utmp entry for the tty.
+   * This function must be called after calling setCTty and
+   * making this pty the stdin.
+   * @param user the user to be logged on
+   * @param remotehost the host from which the login is coming. This is
+   *  @em not the local host. For remote logins it should be the hostname
+   *  of the client. For local logins from inside an X session it should
+   *  be the name of the X display. Otherwise it should be empty.
+   */
+  void login (const char *user = 0, const char *remotehost = 0);
+
+  /**
+   * Removes the utmp entry for this tty.
+   */
+  void logout ();
+
+  /**
+   * Wrapper around tcgetattr(3).
+   *
+   * This function can be used only while the PTY is open.
+   * You will need an #include &lt;termios.h&gt; to do anything useful
+   * with it.
+   *
+   * @param ttmode a pointer to a termios structure.
+   *  Note: when declaring ttmode, @c struct @c ::termios must be used -
+   *  without the '::' some version of HP-UX thinks, this declares
+   *  the struct in your class, in your method.
+   * @return @c true on success, false otherwise
+   */
+  bool tcGetAttr (struct::termios * ttmode) const;
+
+  /**
+   * Wrapper around tcsetattr(3) with mode TCSANOW.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param ttmode a pointer to a termios structure.
+   * @return @c true on success, false otherwise. Note that success means
+   *  that @em at @em least @em one attribute could be set.
+   */
+  bool tcSetAttr (struct::termios * ttmode);
+
+  /**
+   * Change the logical (screen) size of the pty.
+   * The default is 24 lines by 80 columns.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param lines the number of rows
+   * @param columns the number of columns
+   * @return @c true on success, false otherwise
+   */
+  bool setWinSize (int lines, int columns);
+
+  /**
+   * Set whether the pty should echo input.
+   *
+   * Echo is on by default.
+   * If the output of automatically fed (non-interactive) PTY clients
+   * needs to be parsed, disabling echo often makes it much simpler.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param echo true if input should be echoed.
+   * @return @c true on success, false otherwise
+   */
+  bool setEcho (bool echo);
+
+  /**
+   * @return the name of the slave pty device.
+   *
+   * This function should be called only while the pty is open.
+   */
+  const char *ttyName () const;
+
+  /**
+   * @return the file descriptor of the master pty
+   *
+   * This function should be called only while the pty is open.
+   */
+  int masterFd () const;
+
+  /**
+   * @return the file descriptor of the slave pty
+   *
+   * This function should be called only while the pty slave is open.
+   */
+  int slaveFd () const;
+
+protected:
+  /**
+   * @internal
+   */
+    KPty (KPtyPrivate * d);
+
+  /**
+   * @internal
+   */
+  KPtyPrivate *const d_ptr;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/terminal/KPtyDevice.cpp	Tue Aug 23 18:22:27 2011 +0200
@@ -0,0 +1,340 @@
+/*
+
+   This file is part of the KDE libraries
+   Copyright (C) 2007 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 "KPtyDevice.h"
+
+#include <QtCore/QSocketNotifier>
+
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#define PTY_BYTES_AVAILABLE TIOCINQ
+
+//////////////////
+// private data //
+//////////////////
+
+// Lifted from Qt. I don't think they would mind. ;)
+// Re-lift again from Qt whenever a proper replacement for pthread_once appears
+static void
+qt_ignore_sigpipe ()
+{
+  static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER (0);
+  if (atom.testAndSetRelaxed (0, 1))
+    {
+      struct sigaction noaction;
+      memset (&noaction, 0, sizeof (noaction));
+      noaction.sa_handler = SIG_IGN;
+      sigaction (SIGPIPE, &noaction, 0);
+    }
+}
+
+#define NO_INTR(ret,func) do { ret = func; } while (ret < 0 && errno == EINTR)
+
+bool
+KPtyDevicePrivate::_k_canRead ()
+{
+  Q_Q (KPtyDevice);
+  qint64 readBytes = 0;
+
+
+  int available;
+  if (!::ioctl (q->masterFd (), PTY_BYTES_AVAILABLE, (char *) &available))
+    {
+      char *ptr = readBuffer.reserve (available);
+	// Useless block braces except in Solaris
+	{
+	  NO_INTR (readBytes, read (q->masterFd (), ptr, available));
+	}
+      if (readBytes < 0)
+	{
+	  readBuffer.unreserve (available);
+	  return false;
+	}
+      readBuffer.unreserve (available - readBytes);	// *should* be a no-op
+    }
+
+  if (!readBytes)
+    {
+      readNotifier->setEnabled (false);
+      return false;
+    }
+  else
+    {
+      if (!emittedReadyRead)
+	{
+	  emittedReadyRead = true;
+	  emit q->readyRead ();
+	  emittedReadyRead = false;
+	}
+      return true;
+    }
+}
+
+bool
+KPtyDevicePrivate::_k_canWrite ()
+{
+  Q_Q (KPtyDevice);
+
+  writeNotifier->setEnabled (false);
+  if (writeBuffer.isEmpty ())
+    return false;
+
+  qt_ignore_sigpipe ();
+  int wroteBytes;
+  NO_INTR (wroteBytes,
+	   write (q->masterFd (),
+		  writeBuffer.readPointer (), writeBuffer.readSize ()));
+  if (wroteBytes < 0)
+    {
+      return false;
+    }
+  writeBuffer.free (wroteBytes);
+
+  if (!emittedBytesWritten)
+    {
+      emittedBytesWritten = true;
+      emit q->bytesWritten (wroteBytes);
+      emittedBytesWritten = false;
+    }
+
+  if (!writeBuffer.isEmpty ())
+    writeNotifier->setEnabled (true);
+  return true;
+}
+
+#ifndef timeradd
+// Lifted from GLIBC
+#define timeradd(a, b, result) \
+    do { \
+        (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+        (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+        if ((result)->tv_usec >= 1000000) { \
+            ++(result)->tv_sec; \
+            (result)->tv_usec -= 1000000; \
+        } \
+    } while (0)
+#define timersub(a, b, result) \
+    do { \
+        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+        if ((result)->tv_usec < 0) { \
+            --(result)->tv_sec; \
+            (result)->tv_usec += 1000000; \
+        } \
+    } while (0)
+#endif
+
+bool
+KPtyDevicePrivate::doWait (int msecs, bool reading)
+{
+  Q_Q (KPtyDevice);
+  struct timeval tv, *tvp;
+
+  if (msecs < 0)
+    tvp = 0;
+  else
+    {
+      tv.tv_sec = msecs / 1000;
+      tv.tv_usec = (msecs % 1000) * 1000;
+      tvp = &tv;
+    }
+
+  while (reading ? readNotifier->isEnabled () : !writeBuffer.isEmpty ())
+    {
+      fd_set rfds;
+      fd_set wfds;
+
+      FD_ZERO (&rfds);
+      FD_ZERO (&wfds);
+
+      if (readNotifier->isEnabled ())
+	FD_SET (q->masterFd (), &rfds);
+      if (!writeBuffer.isEmpty ())
+	FD_SET (q->masterFd (), &wfds);
+
+      switch (select (q->masterFd () + 1, &rfds, &wfds, 0, tvp))
+	{
+	case -1:
+	  if (errno == EINTR)
+	    break;
+	  return false;
+	case 0:
+	  return false;
+	default:
+	  if (FD_ISSET (q->masterFd (), &rfds))
+	    {
+	      bool canRead = _k_canRead ();
+	      if (reading && canRead)
+		return true;
+	    }
+	  if (FD_ISSET (q->masterFd (), &wfds))
+	    {
+	      bool canWrite = _k_canWrite ();
+	      if (!reading)
+		return canWrite;
+	    }
+	  break;
+	}
+    }
+  return false;
+}
+
+void
+KPtyDevicePrivate::finishOpen (QIODevice::OpenMode mode)
+{
+  Q_Q (KPtyDevice);
+
+  q->QIODevice::open (mode);
+  fcntl (q->masterFd (), F_SETFL, O_NONBLOCK);
+  readBuffer.clear ();
+  readNotifier =
+    new QSocketNotifier (q->masterFd (), QSocketNotifier::Read, q);
+  writeNotifier =
+    new QSocketNotifier (q->masterFd (), QSocketNotifier::Write, q);
+  QObject::connect (readNotifier, SIGNAL (activated (int)), q,
+		    SLOT (_k_canRead ()));
+  QObject::connect (writeNotifier, SIGNAL (activated (int)), q,
+		    SLOT (_k_canWrite ()));
+  readNotifier->setEnabled (true);
+}
+
+KPtyDevice::KPtyDevice (QObject * parent):
+QIODevice (parent), KPty (new KPtyDevicePrivate (this))
+{
+}
+
+KPtyDevice::~KPtyDevice ()
+{
+  close ();
+}
+
+bool
+KPtyDevice::open (OpenMode mode)
+{
+  Q_D (KPtyDevice);
+
+  if (masterFd () >= 0)
+    return true;
+
+  if (!KPty::open ())
+    {
+      return false;
+    }
+
+  d->finishOpen (mode);
+
+  return true;
+}
+
+bool
+KPtyDevice::open (int fd, OpenMode mode)
+{
+  Q_D (KPtyDevice);
+
+  if (!KPty::open (fd))
+    {
+      return false;
+    }
+
+  d->finishOpen (mode);
+
+  return true;
+}
+
+void
+KPtyDevice::close ()
+{
+  Q_D (KPtyDevice);
+
+  if (masterFd () < 0)
+    return;
+
+  delete d->readNotifier;
+  delete d->writeNotifier;
+
+  QIODevice::close ();
+
+  KPty::close ();
+}
+
+bool
+KPtyDevice::canReadLine () const
+{
+  Q_D (const KPtyDevice);
+  return QIODevice::canReadLine () || d->readBuffer.canReadLine ();
+}
+
+bool
+KPtyDevice::atEnd () const
+{
+  Q_D (const KPtyDevice);
+  return QIODevice::atEnd () && d->readBuffer.isEmpty ();
+}
+
+qint64
+KPtyDevice::bytesAvailable () const
+{
+  Q_D (const KPtyDevice);
+  return QIODevice::bytesAvailable () + d->readBuffer.size ();
+}
+
+qint64
+KPtyDevice::bytesToWrite () const
+{
+  Q_D (const KPtyDevice);
+  return d->writeBuffer.size ();
+}
+
+// protected
+qint64
+KPtyDevice::readData (char *data, qint64 maxlen)
+{
+  Q_D (KPtyDevice);
+  return d->readBuffer.read (data, (int) qMin < qint64 > (maxlen, KMAXINT));
+}
+
+// protected
+qint64
+KPtyDevice::readLineData (char *data, qint64 maxlen)
+{
+  Q_D (KPtyDevice);
+  return d->readBuffer.readLine (data,
+				 (int) qMin < qint64 > (maxlen, KMAXINT));
+}
+
+// protected
+qint64
+KPtyDevice::writeData (const char *data, qint64 len)
+{
+  Q_D (KPtyDevice);
+  Q_ASSERT (len <= KMAXINT);
+
+  d->writeBuffer.write (data, len);
+  d->writeNotifier->setEnabled (true);
+  return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/terminal/KPtyDevice.h	Tue Aug 23 18:22:27 2011 +0200
@@ -0,0 +1,314 @@
+/* This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@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.
+*/
+
+#ifndef kptydev_h
+#define kptydev_h
+
+struct KPtyDevicePrivate;
+
+#include "KPty.h"
+#include <QtCore/QIODevice>
+#include <QSocketNotifier>
+
+#define Q_DECLARE_PRIVATE_MI(Class, SuperClass) \
+    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(SuperClass::d_ptr); } \
+    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(SuperClass::d_ptr); } \
+    friend class Class##Private;
+
+/**
+ * Encapsulates KPty into a QIODevice, so it can be used with Q*Stream, etc.
+ */
+class KPtyDevice:public QIODevice, public KPty
+{
+Q_OBJECT Q_DECLARE_PRIVATE_MI (KPtyDevice, KPty) public:
+
+    /**
+     * Constructor
+     */
+  KPtyDevice (QObject * parent = 0);
+
+    /**
+     * Destructor:
+     *
+     *  If the pty is still open, it will be closed. Note, however, that
+     *  an utmp registration is @em not undone.
+     */
+  virtual ~ KPtyDevice ();
+
+    /**
+     * Create a pty master/slave pair.
+     *
+     * @return true if a pty pair was successfully opened
+     */
+  virtual bool open (OpenMode mode = ReadWrite | Unbuffered);
+
+    /**
+     * Open using an existing pty master. The ownership of the fd
+     * remains with the caller, i.e., close() will not close the fd.
+     *
+     * This is useful if you wish to attach a secondary "controller" to an
+     * existing pty device such as a terminal widget.
+     * Note that you will need to use setSuspended() on both devices to
+     * control which one gets the incoming data from the pty.
+     *
+     * @param fd an open pty master file descriptor.
+     * @param mode the device mode to open the pty with.
+     * @return true if a pty pair was successfully opened
+     */
+  bool open (int fd, OpenMode mode = ReadWrite | Unbuffered);
+
+    /**
+     * Close the pty master/slave pair.
+     */
+  virtual void close ();
+
+    /**
+     * @reimp
+     */
+  bool canReadLine () const;
+
+    /**
+     * @reimp
+     */
+  bool atEnd () const;
+
+    /**
+     * @reimp
+     */
+  qint64 bytesAvailable () const;
+
+    /**
+     * @reimp
+     */
+  qint64 bytesToWrite () const;
+
+protected:
+  virtual qint64 readData (char *data, qint64 maxSize);
+  virtual qint64 readLineData (char *data, qint64 maxSize);
+  virtual qint64 writeData (const char *data, qint64 maxSize);
+
+private:
+  Q_PRIVATE_SLOT (d_func (), bool _k_canRead ())
+  Q_PRIVATE_SLOT (d_func (), bool _k_canWrite ())};
+
+#define KMAXINT ((int)(~0U >> 1))
+
+/////////////////////////////////////////////////////
+// Helper. Remove when QRingBuffer becomes public. //
+/////////////////////////////////////////////////////
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qlinkedlist.h>
+
+#define CHUNKSIZE 4096
+
+class KRingBuffer
+{
+public:
+  KRingBuffer ()
+  {
+    clear ();
+  }
+
+  void clear ()
+  {
+    buffers.clear ();
+    QByteArray tmp;
+    tmp.resize (CHUNKSIZE);
+    buffers << tmp;
+    head = tail = 0;
+    totalSize = 0;
+  }
+
+  inline bool isEmpty () const
+  {
+    return buffers.count () == 1 && !tail;
+  }
+
+  inline int size () const
+  {
+    return totalSize;
+  }
+
+  inline int readSize () const
+  {
+    return (buffers.count () == 1 ? tail : buffers.first ().size ()) - head;
+  }
+
+  inline const char *readPointer () const
+  {
+    Q_ASSERT (totalSize > 0);
+    return buffers.first ().constData () + head;
+  }
+
+  void free (int bytes)
+  {
+    totalSize -= bytes;
+    Q_ASSERT (totalSize >= 0);
+
+    forever
+    {
+      int nbs = readSize ();
+
+      if (bytes < nbs)
+	{
+	  head += bytes;
+	  if (head == tail && buffers.count () == 1)
+	    {
+	      buffers.first ().resize (CHUNKSIZE);
+	      head = tail = 0;
+	    }
+	  break;
+	}
+
+      bytes -= nbs;
+      if (buffers.count () == 1)
+	{
+	  buffers.first ().resize (CHUNKSIZE);
+	  head = tail = 0;
+	  break;
+	}
+
+      buffers.removeFirst ();
+      head = 0;
+    }
+  }
+
+  char *reserve (int bytes)
+  {
+    totalSize += bytes;
+
+    char *ptr;
+    if (tail + bytes <= buffers.last ().size ())
+      {
+	ptr = buffers.last ().data () + tail;
+	tail += bytes;
+      }
+    else
+      {
+	buffers.last ().resize (tail);
+	QByteArray tmp;
+	tmp.resize (qMax (CHUNKSIZE, bytes));
+	ptr = tmp.data ();
+	buffers << tmp;
+	tail = bytes;
+      }
+    return ptr;
+  }
+
+  // release a trailing part of the last reservation
+  inline void unreserve (int bytes)
+  {
+    totalSize -= bytes;
+    tail -= bytes;
+  }
+
+  inline void write (const char *data, int len)
+  {
+    memcpy (reserve (len), data, len);
+  }
+
+  // Find the first occurrence of c and return the index after it.
+  // If c is not found until maxLength, maxLength is returned, provided
+  // it is smaller than the buffer size. Otherwise -1 is returned.
+  int indexAfter (char c, int maxLength = KMAXINT) const
+  {
+    int index = 0;
+    int start = head;
+      QLinkedList < QByteArray >::ConstIterator it = buffers.begin ();
+      forever
+    {
+      if (!maxLength)
+	return index;
+      if (index == size ())
+	return -1;
+      const QByteArray & buf = *it;
+      ++it;
+      int len = qMin ((it == buffers.end ()? tail : buf.size ()) - start,
+		      maxLength);
+      const char *ptr = buf.data () + start;
+      if (const char *rptr = (const char *)memchr (ptr, c, len))
+	return index + (rptr - ptr) + 1;
+        index += len;
+        maxLength -= len;
+        start = 0;
+    }
+  }
+
+  inline int lineSize (int maxLength = KMAXINT) const
+  {
+    return indexAfter ('\n', maxLength);
+  }
+
+  inline bool canReadLine () const
+  {
+    return lineSize () != -1;
+  }
+
+  int read (char *data, int maxLength)
+  {
+    int bytesToRead = qMin (size (), maxLength);
+    int readSoFar = 0;
+    while (readSoFar < bytesToRead)
+      {
+	const char *ptr = readPointer ();
+	int bs = qMin (bytesToRead - readSoFar, readSize ());
+	memcpy (data + readSoFar, ptr, bs);
+	readSoFar += bs;
+	free (bs);
+      }
+    return readSoFar;
+  }
+
+  int readLine (char *data, int maxLength)
+  {
+    return read (data, lineSize (qMin (maxLength, size ())));
+  }
+
+private:
+  QLinkedList < QByteArray > buffers;
+  int head, tail;
+  int totalSize;
+};
+
+struct KPtyDevicePrivate:public KPtyPrivate
+{
+  Q_DECLARE_PUBLIC (KPtyDevice)
+    KPtyDevicePrivate (KPty * parent):KPtyPrivate (parent),
+    emittedReadyRead (false), emittedBytesWritten (false),
+    readNotifier (0), writeNotifier (0)
+  {
+  }
+
+  bool _k_canRead ();
+  bool _k_canWrite ();
+
+  bool doWait (int msecs, bool reading);
+  void finishOpen (QIODevice::OpenMode mode);
+
+  bool emittedReadyRead;
+  bool emittedBytesWritten;
+  QSocketNotifier *readNotifier;
+  QSocketNotifier *writeNotifier;
+  KRingBuffer readBuffer;
+  KRingBuffer writeBuffer;
+};
+
+#endif
--- a/gui/src/terminal/LinuxTerminalEmulation.h	Tue Aug 23 18:06:45 2011 +0200
+++ b/gui/src/terminal/LinuxTerminalEmulation.h	Tue Aug 23 18:22:27 2011 +0200
@@ -6,7 +6,7 @@
 #include "unistd.h"
 #include <assert.h>
 #include <cstdio>
-#include "kptydevice.h"
+#include "KPtyDevice.h"
 
 class LinuxTerminalEmulation : public TerminalEmulation
 {
--- a/gui/src/terminal/kpty.cpp	Tue Aug 23 18:06:45 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-/*
-
-   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;
-}
--- a/gui/src/terminal/kpty.h	Tue Aug 23 18:06:45 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/* This file is part of the KDE libraries
-
-    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@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.
-*/
-
-#ifndef kpty_h
-#define kpty_h
-#include <QtCore/qglobal.h>
-
-struct KPtyPrivate;
-struct termios;
-
-/**
- * Provides primitives for opening & closing a pseudo TTY pair, assigning the
- * controlling TTY, utmp registration and setting various terminal attributes.
- */
-class KPty
-{
-Q_DECLARE_PRIVATE (KPty) public:
-
-  /**
-   * Constructor
-   */
-  KPty ();
-
-  /**
-   * Destructor:
-   *
-   *  If the pty is still open, it will be closed. Note, however, that
-   *  an utmp registration is @em not undone.
-  */
-  ~KPty ();
-
-  /**
-   * Create a pty master/slave pair.
-   *
-   * @return true if a pty pair was successfully opened
-   */
-  bool open ();
-
-  /**
-   * Open using an existing pty master.
-   *
-   * @param fd an open pty master file descriptor.
-   *   The ownership of the fd remains with the caller;
-   *   it will not be automatically closed at any point.
-   * @return true if a pty pair was successfully opened
-   */
-  bool open (int fd);
-
-  /**
-   * Close the pty master/slave pair.
-   */
-  void close ();
-
-  /**
-   * Close the pty slave descriptor.
-   *
-   * When creating the pty, KPty also opens the slave and keeps it open.
-   * Consequently the master will never receive an EOF notification.
-   * Usually this is the desired behavior, as a closed pty slave can be
-   * reopened any time - unlike a pipe or socket. However, in some cases
-   * pipe-alike behavior might be desired.
-   *
-   * After this function was called, slaveFd() and setCTty() cannot be
-   * used.
-   */
-  void closeSlave ();
-
-  /**
-   * Open the pty slave descriptor.
-   *
-   * This undoes the effect of closeSlave().
-   *
-   * @return true if the pty slave was successfully opened
-   */
-  bool openSlave ();
-
-  /**
-   * Creates a new session and process group and makes this pty the
-   * controlling tty.
-   */
-  void setCTty ();
-
-  /**
-   * Creates an utmp entry for the tty.
-   * This function must be called after calling setCTty and
-   * making this pty the stdin.
-   * @param user the user to be logged on
-   * @param remotehost the host from which the login is coming. This is
-   *  @em not the local host. For remote logins it should be the hostname
-   *  of the client. For local logins from inside an X session it should
-   *  be the name of the X display. Otherwise it should be empty.
-   */
-  void login (const char *user = 0, const char *remotehost = 0);
-
-  /**
-   * Removes the utmp entry for this tty.
-   */
-  void logout ();
-
-  /**
-   * Wrapper around tcgetattr(3).
-   *
-   * This function can be used only while the PTY is open.
-   * You will need an #include &lt;termios.h&gt; to do anything useful
-   * with it.
-   *
-   * @param ttmode a pointer to a termios structure.
-   *  Note: when declaring ttmode, @c struct @c ::termios must be used -
-   *  without the '::' some version of HP-UX thinks, this declares
-   *  the struct in your class, in your method.
-   * @return @c true on success, false otherwise
-   */
-  bool tcGetAttr (struct::termios * ttmode) const;
-
-  /**
-   * Wrapper around tcsetattr(3) with mode TCSANOW.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param ttmode a pointer to a termios structure.
-   * @return @c true on success, false otherwise. Note that success means
-   *  that @em at @em least @em one attribute could be set.
-   */
-  bool tcSetAttr (struct::termios * ttmode);
-
-  /**
-   * Change the logical (screen) size of the pty.
-   * The default is 24 lines by 80 columns.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param lines the number of rows
-   * @param columns the number of columns
-   * @return @c true on success, false otherwise
-   */
-  bool setWinSize (int lines, int columns);
-
-  /**
-   * Set whether the pty should echo input.
-   *
-   * Echo is on by default.
-   * If the output of automatically fed (non-interactive) PTY clients
-   * needs to be parsed, disabling echo often makes it much simpler.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param echo true if input should be echoed.
-   * @return @c true on success, false otherwise
-   */
-  bool setEcho (bool echo);
-
-  /**
-   * @return the name of the slave pty device.
-   *
-   * This function should be called only while the pty is open.
-   */
-  const char *ttyName () const;
-
-  /**
-   * @return the file descriptor of the master pty
-   *
-   * This function should be called only while the pty is open.
-   */
-  int masterFd () const;
-
-  /**
-   * @return the file descriptor of the slave pty
-   *
-   * This function should be called only while the pty slave is open.
-   */
-  int slaveFd () const;
-
-protected:
-  /**
-   * @internal
-   */
-    KPty (KPtyPrivate * d);
-
-  /**
-   * @internal
-   */
-  KPtyPrivate *const d_ptr;
-};
-
-#endif
--- a/gui/src/terminal/kpty_p.h	Tue Aug 23 18:06:45 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/* This file is part of the KDE libraries
-
-    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@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.
-*/
-
-#ifndef kpty_p_h
-#define kpty_p_h
-
-#include "kpty.h"
-
-#if defined(Q_OS_MAC)
-#define HAVE_UTIL_H
-#define HAVE_UTMPX
-#define _UTMPX_COMPAT
-#define HAVE_PTSNAME
-#define HAVE_SYS_TIME_H
-#else
-#define HAVE_PTY_H
-#endif
-
-#define HAVE_OPENPTY
-
-#include <QtCore/QByteArray>
-
-struct KPtyPrivate
-{
-  Q_DECLARE_PUBLIC (KPty) KPtyPrivate (KPty * parent);
-  virtual ~ KPtyPrivate ();
-#ifndef HAVE_OPENPTY
-  bool chownpty (bool grant);
-#endif
-
-  int masterFd;
-  int slaveFd;
-  bool ownMaster:1;
-
-  QByteArray ttyName;
-
-  KPty *q_ptr;
-};
-
-#endif
--- a/gui/src/terminal/kptydevice.cpp	Tue Aug 23 18:06:45 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-/*
-
-   This file is part of the KDE libraries
-   Copyright (C) 2007 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 "kptydevice.h"
-#include "kpty_p.h"
-#define i18n
-
-#include <QtCore/QSocketNotifier>
-
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#define PTY_BYTES_AVAILABLE TIOCINQ
-
-//////////////////
-// private data //
-//////////////////
-
-// Lifted from Qt. I don't think they would mind. ;)
-// Re-lift again from Qt whenever a proper replacement for pthread_once appears
-static void
-qt_ignore_sigpipe ()
-{
-  static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER (0);
-  if (atom.testAndSetRelaxed (0, 1))
-    {
-      struct sigaction noaction;
-      memset (&noaction, 0, sizeof (noaction));
-      noaction.sa_handler = SIG_IGN;
-      sigaction (SIGPIPE, &noaction, 0);
-    }
-}
-
-#define NO_INTR(ret,func) do { ret = func; } while (ret < 0 && errno == EINTR)
-
-bool
-KPtyDevicePrivate::_k_canRead ()
-{
-  Q_Q (KPtyDevice);
-  qint64 readBytes = 0;
-
-
-  int available;
-  if (!::ioctl (q->masterFd (), PTY_BYTES_AVAILABLE, (char *) &available))
-    {
-      char *ptr = readBuffer.reserve (available);
-	// Useless block braces except in Solaris
-	{
-	  NO_INTR (readBytes, read (q->masterFd (), ptr, available));
-	}
-      if (readBytes < 0)
-	{
-	  readBuffer.unreserve (available);
-	  q->setErrorString (i18n ("Error reading from PTY"));
-	  return false;
-	}
-      readBuffer.unreserve (available - readBytes);	// *should* be a no-op
-    }
-
-  if (!readBytes)
-    {
-      readNotifier->setEnabled (false);
-      return false;
-    }
-  else
-    {
-      if (!emittedReadyRead)
-	{
-	  emittedReadyRead = true;
-	  emit q->readyRead ();
-	  emittedReadyRead = false;
-	}
-      return true;
-    }
-}
-
-bool
-KPtyDevicePrivate::_k_canWrite ()
-{
-  Q_Q (KPtyDevice);
-
-  writeNotifier->setEnabled (false);
-  if (writeBuffer.isEmpty ())
-    return false;
-
-  qt_ignore_sigpipe ();
-  int wroteBytes;
-  NO_INTR (wroteBytes,
-	   write (q->masterFd (),
-		  writeBuffer.readPointer (), writeBuffer.readSize ()));
-  if (wroteBytes < 0)
-    {
-      q->setErrorString (i18n ("Error writing to PTY"));
-      return false;
-    }
-  writeBuffer.free (wroteBytes);
-
-  if (!emittedBytesWritten)
-    {
-      emittedBytesWritten = true;
-      emit q->bytesWritten (wroteBytes);
-      emittedBytesWritten = false;
-    }
-
-  if (!writeBuffer.isEmpty ())
-    writeNotifier->setEnabled (true);
-  return true;
-}
-
-#ifndef timeradd
-// Lifted from GLIBC
-#define timeradd(a, b, result) \
-    do { \
-        (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
-        (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
-        if ((result)->tv_usec >= 1000000) { \
-            ++(result)->tv_sec; \
-            (result)->tv_usec -= 1000000; \
-        } \
-    } while (0)
-#define timersub(a, b, result) \
-    do { \
-        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
-        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
-        if ((result)->tv_usec < 0) { \
-            --(result)->tv_sec; \
-            (result)->tv_usec += 1000000; \
-        } \
-    } while (0)
-#endif
-
-bool
-KPtyDevicePrivate::doWait (int msecs, bool reading)
-{
-  Q_Q (KPtyDevice);
-  struct timeval tv, *tvp;
-
-  if (msecs < 0)
-    tvp = 0;
-  else
-    {
-      tv.tv_sec = msecs / 1000;
-      tv.tv_usec = (msecs % 1000) * 1000;
-      tvp = &tv;
-    }
-
-  while (reading ? readNotifier->isEnabled () : !writeBuffer.isEmpty ())
-    {
-      fd_set rfds;
-      fd_set wfds;
-
-      FD_ZERO (&rfds);
-      FD_ZERO (&wfds);
-
-      if (readNotifier->isEnabled ())
-	FD_SET (q->masterFd (), &rfds);
-      if (!writeBuffer.isEmpty ())
-	FD_SET (q->masterFd (), &wfds);
-
-      switch (select (q->masterFd () + 1, &rfds, &wfds, 0, tvp))
-	{
-	case -1:
-	  if (errno == EINTR)
-	    break;
-	  return false;
-	case 0:
-	  q->setErrorString (i18n ("PTY operation timed out"));
-	  return false;
-	default:
-	  if (FD_ISSET (q->masterFd (), &rfds))
-	    {
-	      bool canRead = _k_canRead ();
-	      if (reading && canRead)
-		return true;
-	    }
-	  if (FD_ISSET (q->masterFd (), &wfds))
-	    {
-	      bool canWrite = _k_canWrite ();
-	      if (!reading)
-		return canWrite;
-	    }
-	  break;
-	}
-    }
-  return false;
-}
-
-void
-KPtyDevicePrivate::finishOpen (QIODevice::OpenMode mode)
-{
-  Q_Q (KPtyDevice);
-
-  q->QIODevice::open (mode);
-  fcntl (q->masterFd (), F_SETFL, O_NONBLOCK);
-  readBuffer.clear ();
-  readNotifier =
-    new QSocketNotifier (q->masterFd (), QSocketNotifier::Read, q);
-  writeNotifier =
-    new QSocketNotifier (q->masterFd (), QSocketNotifier::Write, q);
-  QObject::connect (readNotifier, SIGNAL (activated (int)), q,
-		    SLOT (_k_canRead ()));
-  QObject::connect (writeNotifier, SIGNAL (activated (int)), q,
-		    SLOT (_k_canWrite ()));
-  readNotifier->setEnabled (true);
-}
-
-KPtyDevice::KPtyDevice (QObject * parent):
-QIODevice (parent), KPty (new KPtyDevicePrivate (this))
-{
-}
-
-KPtyDevice::~KPtyDevice ()
-{
-  close ();
-}
-
-bool
-KPtyDevice::open (OpenMode mode)
-{
-  Q_D (KPtyDevice);
-
-  if (masterFd () >= 0)
-    return true;
-
-  if (!KPty::open ())
-    {
-      setErrorString (i18n ("Error opening PTY"));
-      return false;
-    }
-
-  d->finishOpen (mode);
-
-  return true;
-}
-
-bool
-KPtyDevice::open (int fd, OpenMode mode)
-{
-  Q_D (KPtyDevice);
-
-  if (!KPty::open (fd))
-    {
-      setErrorString (i18n ("Error opening PTY"));
-      return false;
-    }
-
-  d->finishOpen (mode);
-
-  return true;
-}
-
-void
-KPtyDevice::close ()
-{
-  Q_D (KPtyDevice);
-
-  if (masterFd () < 0)
-    return;
-
-  delete d->readNotifier;
-  delete d->writeNotifier;
-
-  QIODevice::close ();
-
-  KPty::close ();
-}
-
-bool
-KPtyDevice::canReadLine () const
-{
-  Q_D (const KPtyDevice);
-  return QIODevice::canReadLine () || d->readBuffer.canReadLine ();
-}
-
-bool
-KPtyDevice::atEnd () const
-{
-  Q_D (const KPtyDevice);
-  return QIODevice::atEnd () && d->readBuffer.isEmpty ();
-}
-
-qint64
-KPtyDevice::bytesAvailable () const
-{
-  Q_D (const KPtyDevice);
-  return QIODevice::bytesAvailable () + d->readBuffer.size ();
-}
-
-qint64
-KPtyDevice::bytesToWrite () const
-{
-  Q_D (const KPtyDevice);
-  return d->writeBuffer.size ();
-}
-
-// protected
-qint64
-KPtyDevice::readData (char *data, qint64 maxlen)
-{
-  Q_D (KPtyDevice);
-  return d->readBuffer.read (data, (int) qMin < qint64 > (maxlen, KMAXINT));
-}
-
-// protected
-qint64
-KPtyDevice::readLineData (char *data, qint64 maxlen)
-{
-  Q_D (KPtyDevice);
-  return d->readBuffer.readLine (data,
-				 (int) qMin < qint64 > (maxlen, KMAXINT));
-}
-
-// protected
-qint64
-KPtyDevice::writeData (const char *data, qint64 len)
-{
-  Q_D (KPtyDevice);
-  Q_ASSERT (len <= KMAXINT);
-
-  d->writeBuffer.write (data, len);
-  d->writeNotifier->setEnabled (true);
-  return len;
-}
--- a/gui/src/terminal/kptydevice.h	Tue Aug 23 18:06:45 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-/* This file is part of the KDE libraries
-
-    Copyright (C) 2007 Oswald Buddenhagen <ossi@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.
-*/
-
-#ifndef kptydev_h
-#define kptydev_h
-
-struct KPtyPrivate;
-struct KPtyDevicePrivate;
-
-#include "kpty.h"
-#include "kpty_p.h"
-#include <QtCore/QIODevice>
-#include <QSocketNotifier>
-
-#define Q_DECLARE_PRIVATE_MI(Class, SuperClass) \
-    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(SuperClass::d_ptr); } \
-    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(SuperClass::d_ptr); } \
-    friend class Class##Private;
-
-/**
- * Encapsulates KPty into a QIODevice, so it can be used with Q*Stream, etc.
- */
-class KPtyDevice:public QIODevice, public KPty
-{
-Q_OBJECT Q_DECLARE_PRIVATE_MI (KPtyDevice, KPty) public:
-
-    /**
-     * Constructor
-     */
-  KPtyDevice (QObject * parent = 0);
-
-    /**
-     * Destructor:
-     *
-     *  If the pty is still open, it will be closed. Note, however, that
-     *  an utmp registration is @em not undone.
-     */
-  virtual ~ KPtyDevice ();
-
-    /**
-     * Create a pty master/slave pair.
-     *
-     * @return true if a pty pair was successfully opened
-     */
-  virtual bool open (OpenMode mode = ReadWrite | Unbuffered);
-
-    /**
-     * Open using an existing pty master. The ownership of the fd
-     * remains with the caller, i.e., close() will not close the fd.
-     *
-     * This is useful if you wish to attach a secondary "controller" to an
-     * existing pty device such as a terminal widget.
-     * Note that you will need to use setSuspended() on both devices to
-     * control which one gets the incoming data from the pty.
-     *
-     * @param fd an open pty master file descriptor.
-     * @param mode the device mode to open the pty with.
-     * @return true if a pty pair was successfully opened
-     */
-  bool open (int fd, OpenMode mode = ReadWrite | Unbuffered);
-
-    /**
-     * Close the pty master/slave pair.
-     */
-  virtual void close ();
-
-    /**
-     * @reimp
-     */
-  bool canReadLine () const;
-
-    /**
-     * @reimp
-     */
-  bool atEnd () const;
-
-    /**
-     * @reimp
-     */
-  qint64 bytesAvailable () const;
-
-    /**
-     * @reimp
-     */
-  qint64 bytesToWrite () const;
-
-protected:
-  virtual qint64 readData (char *data, qint64 maxSize);
-  virtual qint64 readLineData (char *data, qint64 maxSize);
-  virtual qint64 writeData (const char *data, qint64 maxSize);
-
-private:
-  Q_PRIVATE_SLOT (d_func (), bool _k_canRead ())
-  Q_PRIVATE_SLOT (d_func (), bool _k_canWrite ())};
-
-#define KMAXINT ((int)(~0U >> 1))
-
-/////////////////////////////////////////////////////
-// Helper. Remove when QRingBuffer becomes public. //
-/////////////////////////////////////////////////////
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qlinkedlist.h>
-
-#define CHUNKSIZE 4096
-
-class KRingBuffer
-{
-public:
-  KRingBuffer ()
-  {
-    clear ();
-  }
-
-  void clear ()
-  {
-    buffers.clear ();
-    QByteArray tmp;
-    tmp.resize (CHUNKSIZE);
-    buffers << tmp;
-    head = tail = 0;
-    totalSize = 0;
-  }
-
-  inline bool isEmpty () const
-  {
-    return buffers.count () == 1 && !tail;
-  }
-
-  inline int size () const
-  {
-    return totalSize;
-  }
-
-  inline int readSize () const
-  {
-    return (buffers.count () == 1 ? tail : buffers.first ().size ()) - head;
-  }
-
-  inline const char *readPointer () const
-  {
-    Q_ASSERT (totalSize > 0);
-    return buffers.first ().constData () + head;
-  }
-
-  void free (int bytes)
-  {
-    totalSize -= bytes;
-    Q_ASSERT (totalSize >= 0);
-
-    forever
-    {
-      int nbs = readSize ();
-
-      if (bytes < nbs)
-	{
-	  head += bytes;
-	  if (head == tail && buffers.count () == 1)
-	    {
-	      buffers.first ().resize (CHUNKSIZE);
-	      head = tail = 0;
-	    }
-	  break;
-	}
-
-      bytes -= nbs;
-      if (buffers.count () == 1)
-	{
-	  buffers.first ().resize (CHUNKSIZE);
-	  head = tail = 0;
-	  break;
-	}
-
-      buffers.removeFirst ();
-      head = 0;
-    }
-  }
-
-  char *reserve (int bytes)
-  {
-    totalSize += bytes;
-
-    char *ptr;
-    if (tail + bytes <= buffers.last ().size ())
-      {
-	ptr = buffers.last ().data () + tail;
-	tail += bytes;
-      }
-    else
-      {
-	buffers.last ().resize (tail);
-	QByteArray tmp;
-	tmp.resize (qMax (CHUNKSIZE, bytes));
-	ptr = tmp.data ();
-	buffers << tmp;
-	tail = bytes;
-      }
-    return ptr;
-  }
-
-  // release a trailing part of the last reservation
-  inline void unreserve (int bytes)
-  {
-    totalSize -= bytes;
-    tail -= bytes;
-  }
-
-  inline void write (const char *data, int len)
-  {
-    memcpy (reserve (len), data, len);
-  }
-
-  // Find the first occurrence of c and return the index after it.
-  // If c is not found until maxLength, maxLength is returned, provided
-  // it is smaller than the buffer size. Otherwise -1 is returned.
-  int indexAfter (char c, int maxLength = KMAXINT) const
-  {
-    int index = 0;
-    int start = head;
-      QLinkedList < QByteArray >::ConstIterator it = buffers.begin ();
-      forever
-    {
-      if (!maxLength)
-	return index;
-      if (index == size ())
-	return -1;
-      const QByteArray & buf = *it;
-      ++it;
-      int len = qMin ((it == buffers.end ()? tail : buf.size ()) - start,
-		      maxLength);
-      const char *ptr = buf.data () + start;
-      if (const char *rptr = (const char *)memchr (ptr, c, len))
-	return index + (rptr - ptr) + 1;
-        index += len;
-        maxLength -= len;
-        start = 0;
-    }
-  }
-
-  inline int lineSize (int maxLength = KMAXINT) const
-  {
-    return indexAfter ('\n', maxLength);
-  }
-
-  inline bool canReadLine () const
-  {
-    return lineSize () != -1;
-  }
-
-  int read (char *data, int maxLength)
-  {
-    int bytesToRead = qMin (size (), maxLength);
-    int readSoFar = 0;
-    while (readSoFar < bytesToRead)
-      {
-	const char *ptr = readPointer ();
-	int bs = qMin (bytesToRead - readSoFar, readSize ());
-	memcpy (data + readSoFar, ptr, bs);
-	readSoFar += bs;
-	free (bs);
-      }
-    return readSoFar;
-  }
-
-  int readLine (char *data, int maxLength)
-  {
-    return read (data, lineSize (qMin (maxLength, size ())));
-  }
-
-private:
-  QLinkedList < QByteArray > buffers;
-  int head, tail;
-  int totalSize;
-};
-
-struct KPtyDevicePrivate:public KPtyPrivate
-{
-  Q_DECLARE_PUBLIC (KPtyDevice)
-    KPtyDevicePrivate (KPty * parent):KPtyPrivate (parent),
-    emittedReadyRead (false), emittedBytesWritten (false),
-    readNotifier (0), writeNotifier (0)
-  {
-  }
-
-  bool _k_canRead ();
-  bool _k_canWrite ();
-
-  bool doWait (int msecs, bool reading);
-  void finishOpen (QIODevice::OpenMode mode);
-
-  bool emittedReadyRead;
-  bool emittedBytesWritten;
-  QSocketNotifier *readNotifier;
-  QSocketNotifier *writeNotifier;
-  KRingBuffer readBuffer;
-  KRingBuffer writeBuffer;
-};
-
-#endif