• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Konsole

Pty.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of Konsole, an X terminal.
00003     Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018     02110-1301  USA.
00019 */
00020 
00021 // Own
00022 #include "Pty.h"
00023 
00024 // System
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <unistd.h>
00028 #include <errno.h>
00029 #include <termios.h>
00030 #include <signal.h>
00031 
00032 // Qt
00033 #include <QtCore/QStringList>
00034 
00035 // KDE
00036 #include <KStandardDirs>
00037 #include <KLocale>
00038 #include <KDebug>
00039 #include <KPty>
00040 #include <KPtyDevice>
00041 
00042 using namespace Konsole;
00043 
00044 void Pty::setWindowSize(int lines, int cols)
00045 {
00046   _windowColumns = cols;
00047   _windowLines = lines;
00048 
00049   if (pty()->masterFd() >= 0)
00050     pty()->setWinSize(lines, cols);
00051 }
00052 QSize Pty::windowSize() const
00053 {
00054     return QSize(_windowColumns,_windowLines);
00055 }
00056 
00057 void Pty::setFlowControlEnabled(bool enable)
00058 {
00059   _xonXoff = enable;
00060 
00061   if (pty()->masterFd() >= 0)
00062   {
00063     struct ::termios ttmode;
00064     pty()->tcGetAttr(&ttmode);
00065     if (!enable)
00066       ttmode.c_iflag &= ~(IXOFF | IXON);
00067     else
00068       ttmode.c_iflag |= (IXOFF | IXON);
00069     if (!pty()->tcSetAttr(&ttmode))
00070       kWarning() << "Unable to set terminal attributes.";
00071   }
00072 }
00073 bool Pty::flowControlEnabled() const
00074 {
00075     if (pty()->masterFd() >= 0)
00076     {
00077         struct ::termios ttmode;
00078         pty()->tcGetAttr(&ttmode);
00079         return ttmode.c_iflag & IXOFF &&
00080                ttmode.c_iflag & IXON;
00081     }  
00082     kWarning() << "Unable to get flow control status, terminal not connected.";
00083     return false;
00084 }
00085 
00086 void Pty::setUtf8Mode(bool enable)
00087 {
00088 #ifdef IUTF8 // XXX not a reasonable place to check it.
00089   _utf8 = enable;
00090 
00091   if (pty()->masterFd() >= 0)
00092   {
00093     struct ::termios ttmode;
00094     pty()->tcGetAttr(&ttmode);
00095     if (!enable)
00096       ttmode.c_iflag &= ~IUTF8;
00097     else
00098       ttmode.c_iflag |= IUTF8;
00099     if (!pty()->tcSetAttr(&ttmode))
00100       kWarning() << "Unable to set terminal attributes.";
00101   }
00102 #endif
00103 }
00104 
00105 void Pty::setErase(char erase)
00106 {
00107   _eraseChar = erase;
00108   
00109   if (pty()->masterFd() >= 0)
00110   {
00111     struct ::termios ttmode;
00112     pty()->tcGetAttr(&ttmode);
00113     ttmode.c_cc[VERASE] = erase;
00114     if (!pty()->tcSetAttr(&ttmode))
00115       kWarning() << "Unable to set terminal attributes.";
00116   }
00117 }
00118 
00119 char Pty::erase() const
00120 {
00121     if (pty()->masterFd() >= 0)
00122     {
00123         struct ::termios ttyAttributes;
00124         pty()->tcGetAttr(&ttyAttributes);
00125         return ttyAttributes.c_cc[VERASE];
00126     }
00127 
00128     return _eraseChar;
00129 }
00130 
00131 void Pty::addEnvironmentVariables(const QStringList& environment)
00132 {
00133     QListIterator<QString> iter(environment);
00134     while (iter.hasNext())
00135     {
00136         QString pair = iter.next();
00137 
00138         // split on the first '=' character
00139         int pos = pair.indexOf('=');
00140         
00141         if ( pos >= 0 )
00142         {
00143             QString variable = pair.left(pos);
00144             QString value = pair.mid(pos+1);
00145 
00146             setEnv(variable,value);
00147         }
00148     }
00149 }
00150 
00151 int Pty::start(const QString& program, 
00152                const QStringList& programArguments, 
00153                const QStringList& environment, 
00154                ulong winid, 
00155                bool addToUtmp,
00156                const QString& dbusService, 
00157                const QString& dbusSession)
00158 {
00159   clearProgram();
00160 
00161   // For historical reasons, the first argument in programArguments is the 
00162   // name of the program to execute, so create a list consisting of all
00163   // but the first argument to pass to setProgram()
00164   Q_ASSERT(programArguments.count() >= 1);
00165   setProgram(program.toLatin1(),programArguments.mid(1));
00166 
00167   addEnvironmentVariables(environment);
00168 
00169   if ( !dbusService.isEmpty() )
00170      setEnv("KONSOLE_DBUS_SERVICE",dbusService);
00171   if ( !dbusSession.isEmpty() )
00172      setEnv("KONSOLE_DBUS_SESSION", dbusSession);
00173 
00174   setEnv("WINDOWID", QString::number(winid));
00175 
00176   // unless the LANGUAGE environment variable has been set explicitly
00177   // set it to a null string
00178   // this fixes the problem where KCatalog sets the LANGUAGE environment
00179   // variable during the application's startup to something which
00180   // differs from LANG,LC_* etc. and causes programs run from
00181   // the terminal to display messages in the wrong language
00182   //
00183   // this can happen if LANG contains a language which KDE
00184   // does not have a translation for
00185   //
00186   // BR:149300
00187   setEnv("LANGUAGE",QString(),false /* do not overwrite existing value if any */);
00188 
00189   setUseUtmp(addToUtmp);
00190 
00191   struct ::termios ttmode;
00192   pty()->tcGetAttr(&ttmode);
00193   if (!_xonXoff)
00194     ttmode.c_iflag &= ~(IXOFF | IXON);
00195   else
00196     ttmode.c_iflag |= (IXOFF | IXON);
00197 #ifdef IUTF8 // XXX not a reasonable place to check it.
00198   if (!_utf8)
00199     ttmode.c_iflag &= ~IUTF8;
00200   else
00201     ttmode.c_iflag |= IUTF8;
00202 #endif
00203 
00204   if (_eraseChar != 0)
00205     ttmode.c_cc[VERASE] = _eraseChar;
00206   
00207   if (!pty()->tcSetAttr(&ttmode))
00208     kWarning() << "Unable to set terminal attributes.";
00209   
00210   pty()->setWinSize(_windowLines, _windowColumns);
00211 
00212   KProcess::start();
00213 
00214   if (!waitForStarted())
00215     return -1;
00216 
00217   return 0;
00218 }
00219 
00220 void Pty::setWriteable(bool writeable)
00221 {
00222   struct stat sbuf;
00223   stat(pty()->ttyName(), &sbuf);
00224   if (writeable)
00225     chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
00226   else
00227     chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
00228 }
00229 
00230 Pty::Pty(int masterFd, QObject* parent)
00231     : KPtyProcess(masterFd,parent)
00232 {
00233     init();
00234 }
00235 Pty::Pty(QObject* parent)
00236     : KPtyProcess(parent)
00237 {
00238     init();
00239 }
00240 void Pty::init()
00241 {
00242   _windowColumns = 0;
00243   _windowLines = 0;
00244   _eraseChar = 0;
00245   _xonXoff = true;
00246   _utf8 =true;
00247 
00248   connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
00249   setPtyChannels(KPtyProcess::AllChannels);
00250 }
00251 
00252 Pty::~Pty()
00253 {
00254 }
00255 
00256 void Pty::sendData(const char* data, int length)
00257 {
00258   if (!length)
00259     return;
00260   
00261   if (!pty()->write(data,length)) 
00262   {
00263     kWarning() << "Pty::doSendJobs - Could not send input data to terminal process.";
00264     return;
00265   }
00266 }
00267 
00268 void Pty::dataReceived() 
00269 {
00270     QByteArray data = pty()->readAll();
00271     emit receivedData(data.constData(),data.count());
00272 }
00273 
00274 void Pty::lockPty(bool lock)
00275 {
00276 #warning "TODO: Support for locking the Pty"
00277   //if (lock)
00278     //suspend();
00279   //else
00280     //resume();
00281 }
00282 
00283 int Pty::foregroundProcessGroup() const
00284 {
00285     int pid = tcgetpgrp(pty()->masterFd());
00286 
00287     if ( pid != -1 )
00288     {
00289         return pid;
00290     } 
00291 
00292     return 0;
00293 }
00294 
00295 void Pty::setupChildProcess()
00296 {
00297     KPtyProcess::setupChildProcess();
00298     
00299     // reset all signal handlers
00300     // this ensures that terminal applications respond to 
00301     // signals generated via key sequences such as Ctrl+C
00302     // (which sends SIGINT)
00303     struct sigaction action;
00304     sigemptyset(&action.sa_mask);
00305     action.sa_handler = SIG_DFL;
00306     action.sa_flags = 0;
00307     for (int signal=1;signal < NSIG; signal++)
00308         sigaction(signal,&action,0L);
00309 }
00310 
00311 
00312 #include "Pty.moc"

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal