• Skip to content
  • Skip to link menu
KDE 4.2 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 #include <kde_file.h>
00042 
00043 using namespace Konsole;
00044 
00045 void Pty::setWindowSize(int lines, int cols)
00046 {
00047   _windowColumns = cols;
00048   _windowLines = lines;
00049 
00050   if (pty()->masterFd() >= 0)
00051     pty()->setWinSize(lines, cols);
00052 }
00053 QSize Pty::windowSize() const
00054 {
00055     return QSize(_windowColumns,_windowLines);
00056 }
00057 
00058 void Pty::setFlowControlEnabled(bool enable)
00059 {
00060   _xonXoff = enable;
00061 
00062   if (pty()->masterFd() >= 0)
00063   {
00064     struct ::termios ttmode;
00065     pty()->tcGetAttr(&ttmode);
00066     if (!enable)
00067       ttmode.c_iflag &= ~(IXOFF | IXON);
00068     else
00069       ttmode.c_iflag |= (IXOFF | IXON);
00070     if (!pty()->tcSetAttr(&ttmode))
00071       kWarning() << "Unable to set terminal attributes.";
00072   }
00073 }
00074 bool Pty::flowControlEnabled() const
00075 {
00076     if (pty()->masterFd() >= 0)
00077     {
00078         struct ::termios ttmode;
00079         pty()->tcGetAttr(&ttmode);
00080         return ttmode.c_iflag & IXOFF &&
00081                ttmode.c_iflag & IXON;
00082     }  
00083     kWarning() << "Unable to get flow control status, terminal not connected.";
00084     return false;
00085 }
00086 
00087 void Pty::setUtf8Mode(bool enable)
00088 {
00089 #ifdef IUTF8 // XXX not a reasonable place to check it.
00090   _utf8 = enable;
00091 
00092   if (pty()->masterFd() >= 0)
00093   {
00094     struct ::termios ttmode;
00095     pty()->tcGetAttr(&ttmode);
00096     if (!enable)
00097       ttmode.c_iflag &= ~IUTF8;
00098     else
00099       ttmode.c_iflag |= IUTF8;
00100     if (!pty()->tcSetAttr(&ttmode))
00101       kWarning() << "Unable to set terminal attributes.";
00102   }
00103 #endif
00104 }
00105 
00106 void Pty::setErase(char erase)
00107 {
00108   _eraseChar = erase;
00109   
00110   if (pty()->masterFd() >= 0)
00111   {
00112     struct ::termios ttmode;
00113     pty()->tcGetAttr(&ttmode);
00114     ttmode.c_cc[VERASE] = erase;
00115     if (!pty()->tcSetAttr(&ttmode))
00116       kWarning() << "Unable to set terminal attributes.";
00117   }
00118 }
00119 
00120 char Pty::erase() const
00121 {
00122     if (pty()->masterFd() >= 0)
00123     {
00124         struct ::termios ttyAttributes;
00125         pty()->tcGetAttr(&ttyAttributes);
00126         return ttyAttributes.c_cc[VERASE];
00127     }
00128 
00129     return _eraseChar;
00130 }
00131 
00132 void Pty::addEnvironmentVariables(const QStringList& environment)
00133 {
00134     QListIterator<QString> iter(environment);
00135     while (iter.hasNext())
00136     {
00137         QString pair = iter.next();
00138 
00139         // split on the first '=' character
00140         int pos = pair.indexOf('=');
00141         
00142         if ( pos >= 0 )
00143         {
00144             QString variable = pair.left(pos);
00145             QString value = pair.mid(pos+1);
00146 
00147             setEnv(variable,value);
00148         }
00149     }
00150 }
00151 
00152 int Pty::start(const QString& program, 
00153                const QStringList& programArguments, 
00154                const QStringList& environment, 
00155                ulong winid, 
00156                bool addToUtmp,
00157                const QString& dbusService, 
00158                const QString& dbusSession)
00159 {
00160   clearProgram();
00161 
00162   // For historical reasons, the first argument in programArguments is the 
00163   // name of the program to execute, so create a list consisting of all
00164   // but the first argument to pass to setProgram()
00165   Q_ASSERT(programArguments.count() >= 1);
00166   setProgram(program.toLatin1(),programArguments.mid(1));
00167 
00168   addEnvironmentVariables(environment);
00169 
00170   if ( !dbusService.isEmpty() )
00171      setEnv("KONSOLE_DBUS_SERVICE",dbusService);
00172   if ( !dbusSession.isEmpty() )
00173      setEnv("KONSOLE_DBUS_SESSION", dbusSession);
00174 
00175   setEnv("WINDOWID", QString::number(winid));
00176 
00177   // unless the LANGUAGE environment variable has been set explicitly
00178   // set it to a null string
00179   // this fixes the problem where KCatalog sets the LANGUAGE environment
00180   // variable during the application's startup to something which
00181   // differs from LANG,LC_* etc. and causes programs run from
00182   // the terminal to display messages in the wrong language
00183   //
00184   // this can happen if LANG contains a language which KDE
00185   // does not have a translation for
00186   //
00187   // BR:149300
00188   setEnv("LANGUAGE",QString(),false /* do not overwrite existing value if any */);
00189 
00190   setUseUtmp(addToUtmp);
00191 
00192   struct ::termios ttmode;
00193   pty()->tcGetAttr(&ttmode);
00194   if (!_xonXoff)
00195     ttmode.c_iflag &= ~(IXOFF | IXON);
00196   else
00197     ttmode.c_iflag |= (IXOFF | IXON);
00198 #ifdef IUTF8 // XXX not a reasonable place to check it.
00199   if (!_utf8)
00200     ttmode.c_iflag &= ~IUTF8;
00201   else
00202     ttmode.c_iflag |= IUTF8;
00203 #endif
00204 
00205   if (_eraseChar != 0)
00206       ttmode.c_cc[VERASE] = _eraseChar;
00207   
00208   if (!pty()->tcSetAttr(&ttmode))
00209     kWarning() << "Unable to set terminal attributes.";
00210   
00211   pty()->setWinSize(_windowLines, _windowColumns);
00212 
00213   KProcess::start();
00214 
00215   if (!waitForStarted())
00216       return -1;
00217 
00218   return 0;
00219 }
00220 
00221 void Pty::setWriteable(bool writeable)
00222 {
00223   KDE_struct_stat sbuf;
00224   KDE_stat(pty()->ttyName(), &sbuf);
00225   if (writeable)
00226     chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
00227   else
00228     chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
00229 }
00230 
00231 Pty::Pty(int masterFd, QObject* parent)
00232     : KPtyProcess(masterFd,parent)
00233 {
00234     init();
00235 }
00236 Pty::Pty(QObject* parent)
00237     : KPtyProcess(parent)
00238 {
00239     init();
00240 }
00241 void Pty::init()
00242 {
00243   _windowColumns = 0;
00244   _windowLines = 0;
00245   _eraseChar = 0;
00246   _xonXoff = true;
00247   _utf8 =true;
00248 
00249   connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
00250   setPtyChannels(KPtyProcess::AllChannels);
00251 }
00252 
00253 Pty::~Pty()
00254 {
00255 }
00256 
00257 void Pty::sendData(const char* data, int length)
00258 {
00259   if (!length)
00260       return;
00261   
00262   if (!pty()->write(data,length)) 
00263   {
00264     kWarning() << "Pty::doSendJobs - Could not send input data to terminal process.";
00265     return;
00266   }
00267 }
00268 
00269 void Pty::dataReceived() 
00270 {
00271      QByteArray data = pty()->readAll();
00272     emit receivedData(data.constData(),data.count());
00273 }
00274 
00275 void Pty::lockPty(bool lock)
00276 {
00277 #ifdef __GNUC__
00278 #warning "TODO: Support for locking the Pty"
00279 #endif
00280   //if (lock)
00281     //suspend();
00282   //else
00283     //resume();
00284 }
00285 
00286 int Pty::foregroundProcessGroup() const
00287 {
00288     int pid = tcgetpgrp(pty()->masterFd());
00289 
00290     if ( pid != -1 )
00291     {
00292         return pid;
00293     } 
00294 
00295     return 0;
00296 }
00297 
00298 void Pty::setupChildProcess()
00299 {
00300     KPtyProcess::setupChildProcess();
00301     
00302     // reset all signal handlers
00303     // this ensures that terminal applications respond to 
00304     // signals generated via key sequences such as Ctrl+C
00305     // (which sends SIGINT)
00306     struct sigaction action;
00307     sigemptyset(&action.sa_mask);
00308     action.sa_handler = SIG_DFL;
00309     action.sa_flags = 0;
00310     for (int signal=1;signal < NSIG; signal++)
00311         sigaction(signal,&action,0L);
00312 }
00313 
00314 
00315 #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.7
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