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 #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
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
00163
00164
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
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 setEnv("LANGUAGE",QString(),false );
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
00281
00282
00283
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
00303
00304
00305
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"