Konsole
Pty.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "Pty.h"
00023
00024
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
00033 #include <QtCore/QStringList>
00034
00035
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
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
00162
00163
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
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 setEnv("LANGUAGE",QString(),false );
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
00278
00279
00280
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
00300
00301
00302
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"