# HG changeset patch # User Jacob Dawid # Date 1327354025 -3600 # Node ID a89e968265e84be4def1be658a6560325e6a619e # Parent 3524352c7382ca0c7b8a292834ce1da322e70db5 Intermediate commit. diff -r 3524352c7382 -r a89e968265e8 libqterminal/Pty.cpp --- a/libqterminal/Pty.cpp Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/Pty.cpp Mon Jan 23 22:27:05 2012 +0100 @@ -152,8 +152,10 @@ const QStringList& programArguments, const QStringList& environment, ulong winid, - bool addToUtmp -// const QString& dbusService, + bool addToUtmp, + int masterFd, + int slaveFd +// const QString& dbusService, // const QString& dbusSession) ) { @@ -188,7 +190,7 @@ if (!environment.contains("LANGUAGE")) setEnvironment("LANGUAGE",QString()); - setUsePty(All, addToUtmp); + setUsePty(All, addToUtmp, masterFd, slaveFd); pty()->open(); @@ -247,7 +249,26 @@ this, SLOT(writeReady())); _pty = new KPty; - setUsePty(All, false); // utmp will be overridden later + setUsePty(All, false, -1, -1); // utmp will be overridden later +} + +Pty::Pty(int masterFd, int slaveFd) + : _bufferFull(false), + _windowColumns(0), + _windowLines(0), + _eraseChar(0), + _xonXoff(true), + _utf8(true) +{ + connect(this, SIGNAL(receivedStdout(K3Process *, char *, int )), + this, SLOT(dataReceived(K3Process *,char *, int))); + connect(this, SIGNAL(processExited(K3Process *)), + this, SLOT(donePty())); + connect(this, SIGNAL(wroteStdin(K3Process *)), + this, SLOT(writeReady())); + _pty = new KPty(masterFd, slaveFd); + + setUsePty(All, false, masterFd, slaveFd); // utmp will be overridden later } Pty::~Pty() diff -r 3524352c7382 -r a89e968265e8 libqterminal/Pty.h --- a/libqterminal/Pty.h Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/Pty.h Mon Jan 23 22:27:05 2012 +0100 @@ -66,6 +66,8 @@ * name of the program to start and appropriate arguments. */ Pty(); + Pty(int masterFd, int slaveFd); + ~Pty(); /** @@ -92,7 +94,9 @@ const QStringList& arguments, const QStringList& environment, ulong winid, - bool addToUtmp + bool addToUtmp, + int masterFd, + int slaveFd // const QString& dbusService, // const QString& dbusSession ); diff -r 3524352c7382 -r a89e968265e8 libqterminal/QTerminal.cpp --- a/libqterminal/QTerminal.cpp Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/QTerminal.cpp Mon Jan 23 22:27:05 2012 +0100 @@ -18,6 +18,7 @@ #include "QTerminal.h" +#include "pty.h" using namespace Konsole; @@ -33,7 +34,15 @@ void QTerminal::init() { - m_session = new Session(); + int fdm; + int fds; + openpty (&fdm, &fds, 0, 0, 0); + + dup2 (fds, 0); + dup2 (fds, 1); + dup2 (fds, 2); + + m_session = new Session(fdm, fds); m_session->setTitle(Session::NameRole, "QTermWidget"); m_session->setProgram("/bin/bash"); diff -r 3524352c7382 -r a89e968265e8 libqterminal/Session.cpp --- a/libqterminal/Session.cpp Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/Session.cpp Mon Jan 23 22:27:05 2012 +0100 @@ -47,49 +47,56 @@ int Session::lastSessionId = 0; -Session::Session() : +Session::Session(int masterFd, int slaveFd) : _shellProcess(0) - , _emulation(0) - , _monitorActivity(false) - , _monitorSilence(false) - , _notifiedActivity(false) - , _autoClose(true) - , _wantedClose(false) - , _silenceSeconds(10) - , _addToUtmp(false) // disabled by default because of a bug encountered on certain systems - // which caused Konsole to hang when closing a tab and then opening a new - // one. A 'QProcess destroyed while still running' warning was being - // printed to the terminal. Likely a problem in KPty::logout() - // or KPty::login() which uses a QProcess to start /usr/bin/utempter - , _flowControl(true) - , _fullScripting(false) - , _sessionId(0) -// , _zmodemBusy(false) -// , _zmodemProc(0) -// , _zmodemProgress(0) - , _hasDarkBackground(false) + , _emulation(0) + , _monitorActivity(false) + , _monitorSilence(false) + , _notifiedActivity(false) + , _autoClose(true) + , _wantedClose(false) + , _silenceSeconds(10) + , _addToUtmp(false) // disabled by default because of a bug encountered on certain systems + // which caused Konsole to hang when closing a tab and then opening a new + // one. A 'QProcess destroyed while still running' warning was being + // printed to the terminal. Likely a problem in KPty::logout() + // or KPty::login() which uses a QProcess to start /usr/bin/utempter + , _flowControl(true) + , _fullScripting(false) + , _sessionId(0) + // , _zmodemBusy(false) + // , _zmodemProc(0) + // , _zmodemProgress(0) + , _hasDarkBackground(false) { + _masterFd = masterFd; + _slaveFd = slaveFd; + //prepare DBus communication -// new SessionAdaptor(this); + // new SessionAdaptor(this); _sessionId = ++lastSessionId; -// QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this); + // QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this); //create teletype for I/O with shell process - _shellProcess = new Pty(); + if(_masterFd >= 0) { + _shellProcess = new Pty(_masterFd, _slaveFd); + } else { + _shellProcess = new Pty(); + } //create emulation backend _emulation = new Vt102Emulation(); connect( _emulation, SIGNAL( titleChanged( int, const QString & ) ), - this, SLOT( setUserTitle( int, const QString & ) ) ); + this, SLOT( setUserTitle( int, const QString & ) ) ); connect( _emulation, SIGNAL( stateSet(int) ), - this, SLOT( activityStateSet(int) ) ); -// connect( _emulation, SIGNAL( zmodemDetected() ), this , -// SLOT( fireZModemDetected() ) ); + this, SLOT( activityStateSet(int) ) ); + // connect( _emulation, SIGNAL( zmodemDetected() ), this , + // SLOT( fireZModemDetected() ) ); connect( _emulation, SIGNAL( changeTabTextColorRequest( int ) ), - this, SIGNAL( changeTabTextColorRequest( int ) ) ); + this, SIGNAL( changeTabTextColorRequest( int ) ) ); connect( _emulation, SIGNAL(profileChangeCommandReceived(const QString&)), - this, SIGNAL( profileChangeCommandReceived(const QString&)) ); + this, SIGNAL( profileChangeCommandReceived(const QString&)) ); // TODO // connect( _emulation,SIGNAL(imageSizeChanged(int,int)) , this , // SLOT(onEmulationSizeChange(int,int)) ); @@ -98,9 +105,9 @@ _shellProcess->setUtf8Mode(_emulation->utf8()); connect( _shellProcess,SIGNAL(receivedData(const char*,int)),this, - SLOT(onReceiveBlock(const char*,int)) ); + SLOT(onReceiveBlock(const char*,int)) ); connect( _emulation,SIGNAL(sendData(const char*,int)),_shellProcess, - SLOT(sendData(const char*,int)) ); + SLOT(sendData(const char*,int)) ); connect( _emulation,SIGNAL(lockPtyRequest(bool)),_shellProcess,SLOT(lockPty(bool)) ); connect( _emulation,SIGNAL(useUtf8Request(bool)),_shellProcess,SLOT(setUtf8Mode(bool)) ); @@ -128,7 +135,7 @@ // returned if ( _views.count() == 0 ) - return 0; + return 0; else { QWidget* window = _views.first(); @@ -180,7 +187,7 @@ void Session::addView(TerminalDisplay* widget) { - Q_ASSERT( !_views.contains(widget) ); + Q_ASSERT( !_views.contains(widget) ); _views.append(widget); @@ -188,16 +195,16 @@ { // connect emulation - view signals and slots connect( widget , SIGNAL(keyPressedSignal(QKeyEvent*)) , _emulation , - SLOT(sendKeyEvent(QKeyEvent*)) ); + SLOT(sendKeyEvent(QKeyEvent*)) ); connect( widget , SIGNAL(mouseSignal(int,int,int,int)) , _emulation , - SLOT(sendMouseEvent(int,int,int,int)) ); + SLOT(sendMouseEvent(int,int,int,int)) ); connect( widget , SIGNAL(sendStringToEmu(const char*)) , _emulation , - SLOT(sendString(const char*)) ); + SLOT(sendString(const char*)) ); // allow emulation to notify view when the foreground process // indicates whether or not it is interested in mouse signals connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget , - SLOT(setUsesMouse(bool)) ); + SLOT(setUsesMouse(bool)) ); widget->setUsesMouse( _emulation->programUsesMouse() ); @@ -206,11 +213,11 @@ //connect view signals and slots QObject::connect( widget ,SIGNAL(changedContentSizeSignal(int,int)),this, - SLOT(onViewSizeChange(int,int))); + SLOT(onViewSizeChange(int,int))); QObject::connect( widget ,SIGNAL(destroyed(QObject*)) , this , - SLOT(viewDestroyed(QObject*)) ); -//slot for close + SLOT(viewDestroyed(QObject*)) ); + //slot for close QObject::connect(this, SIGNAL(finished()), widget, SLOT(close())); } @@ -228,7 +235,7 @@ { _views.removeAll(widget); - disconnect(widget,0,this,0); + disconnect(widget,0,this,0); if ( _emulation != 0 ) { @@ -244,141 +251,143 @@ disconnect( _emulation , 0 , widget , 0); } - // close the session automatically when the last view is removed - if ( _views.count() == 0 ) - { - close(); - } + // close the session automatically when the last view is removed + if ( _views.count() == 0 ) + { + close(); + } } void Session::run() { - //check that everything is in place to run the session - if (_program.isEmpty()) - qDebug() << "Session::run() - program to run not set."; - if (_arguments.isEmpty()) - qDebug() << "Session::run() - no command line arguments specified."; + //check that everything is in place to run the session + if (_program.isEmpty()) + qDebug() << "Session::run() - program to run not set."; + if (_arguments.isEmpty()) + qDebug() << "Session::run() - no command line arguments specified."; - // Upon a KPty error, there is no description on what that error was... - // Check to see if the given program is executable. - QString exec = QFile::encodeName(_program); + // Upon a KPty error, there is no description on what that error was... + // Check to see if the given program is executable. + QString exec = QFile::encodeName(_program); - // if 'exec' is not specified, fall back to default shell. if that - // is not set then fall back to /bin/sh - if ( exec.isEmpty() ) - exec = getenv("SHELL"); - if ( exec.isEmpty() ) - exec = "/bin/sh"; + // if 'exec' is not specified, fall back to default shell. if that + // is not set then fall back to /bin/sh + if ( exec.isEmpty() ) + exec = getenv("SHELL"); + if ( exec.isEmpty() ) + exec = "/bin/sh"; - // if no arguments are specified, fall back to shell - QStringList arguments = _arguments.join(QChar(' ')).isEmpty() ? - QStringList() << exec : _arguments; - QString pexec = exec; + // if no arguments are specified, fall back to shell + QStringList arguments = _arguments.join(QChar(' ')).isEmpty() ? + QStringList() << exec : _arguments; + QString pexec = exec; - if ( pexec.isEmpty() ) { - qDebug()<<"can not execute "<setWorkingDirectory(_initialWorkingDir); - else - _shellProcess->setWorkingDirectory(cwd); -// _shellProcess->setWorkingDirectory(QDir::homePath()); + // QString cwd_save = QDir::currentPath(); + QString cwd = QDir::currentPath(); + if (!_initialWorkingDir.isEmpty()) + _shellProcess->setWorkingDirectory(_initialWorkingDir); + else + _shellProcess->setWorkingDirectory(cwd); + // _shellProcess->setWorkingDirectory(QDir::homePath()); - _shellProcess->setXonXoff(_flowControl); - _shellProcess->setErase(_emulation->getErase()); + _shellProcess->setXonXoff(_flowControl); + _shellProcess->setErase(_emulation->getErase()); + + // this is not strictly accurate use of the COLORFGBG variable. This does not + // tell the terminal exactly which colors are being used, but instead approximates + // the color scheme as "black on white" or "white on black" depending on whether + // the background color is deemed dark or not + QString backgroundColorHint = _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15"; - // this is not strictly accurate use of the COLORFGBG variable. This does not - // tell the terminal exactly which colors are being used, but instead approximates - // the color scheme as "black on white" or "white on black" depending on whether - // the background color is deemed dark or not - QString backgroundColorHint = _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15"; + int result = _shellProcess->start(QFile::encodeName(_program), + arguments, + _environment << backgroundColorHint, + windowId(), + _addToUtmp, + _masterFd, + _slaveFd); - int result = _shellProcess->start(QFile::encodeName(_program), - arguments, - _environment << backgroundColorHint, - windowId(), - _addToUtmp); + if (result < 0) + { + return; + } - if (result < 0) - { - return; - } + _shellProcess->setWriteable(false); // We are reachable via kwrited. - _shellProcess->setWriteable(false); // We are reachable via kwrited. - - emit started(); + emit started(); } void Session::setUserTitle( int what, const QString &caption ) { //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) - bool modified = false; + bool modified = false; // (btw: what=0 changes _userTitle and icon, what=1 only icon, what=2 only _nameTitle if ((what == 0) || (what == 2)) { if ( _userTitle != caption ) { - _userTitle = caption; - modified = true; - } + _userTitle = caption; + modified = true; + } } if ((what == 0) || (what == 1)) - { - if ( _iconText != caption ) { - _iconText = caption; - modified = true; - } - } + { + if ( _iconText != caption ) { + _iconText = caption; + modified = true; + } + } if (what == 11) { - QString colorString = caption.section(';',0,0); - qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString; - QColor backColor = QColor(colorString); - if (backColor.isValid()){// change color via \033]11;Color\007 - if (backColor != _modifiedBackground) - { - _modifiedBackground = backColor; + QString colorString = caption.section(';',0,0); + qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString; + QColor backColor = QColor(colorString); + if (backColor.isValid()){// change color via \033]11;Color\007 + if (backColor != _modifiedBackground) + { + _modifiedBackground = backColor; - // bail out here until the code to connect the terminal display - // to the changeBackgroundColor() signal has been written - // and tested - just so we don't forget to do this. - Q_ASSERT( 0 ); + // bail out here until the code to connect the terminal display + // to the changeBackgroundColor() signal has been written + // and tested - just so we don't forget to do this. + Q_ASSERT( 0 ); - emit changeBackgroundColorRequest(backColor); - } - } + emit changeBackgroundColorRequest(backColor); + } + } } - if (what == 30) + if (what == 30) { - if ( _nameTitle != caption ) { - setTitle(Session::NameRole,caption); - return; - } - } + if ( _nameTitle != caption ) { + setTitle(Session::NameRole,caption); + return; + } + } if (what == 31) { - QString cwd=caption; - cwd=cwd.replace( QRegExp("^~"), QDir::homePath() ); - emit openUrlRequest(cwd); - } + QString cwd=caption; + cwd=cwd.replace( QRegExp("^~"), QDir::homePath() ); + emit openUrlRequest(cwd); + } // change icon via \033]32;Icon\007 if (what == 32) { if ( _iconName != caption ) { - _iconName = caption; + _iconName = caption; - modified = true; - } + modified = true; + } } if (what == 50) @@ -387,7 +396,7 @@ return; } - if ( modified ) + if ( modified ) emit titleChanged(); } @@ -414,68 +423,68 @@ void Session::monitorTimerDone() { - //FIXME: The idea here is that the notification popup will appear to tell the user than output from - //the terminal has stopped and the popup will disappear when the user activates the session. - // - //This breaks with the addition of multiple views of a session. The popup should disappear - //when any of the views of the session becomes active - + //FIXME: The idea here is that the notification popup will appear to tell the user than output from + //the terminal has stopped and the popup will disappear when the user activates the session. + // + //This breaks with the addition of multiple views of a session. The popup should disappear + //when any of the views of the session becomes active + - //FIXME: Make message text for this notification and the activity notification more descriptive. - if (_monitorSilence) { -// KNotification::event("Silence", ("Silence in session '%1'", _nameTitle), QPixmap(), -// QApplication::activeWindow(), -// KNotification::CloseWhenWidgetActivated); - emit stateChanged(NOTIFYSILENCE); - } - else - { - emit stateChanged(NOTIFYNORMAL); - } + //FIXME: Make message text for this notification and the activity notification more descriptive. + if (_monitorSilence) { + // KNotification::event("Silence", ("Silence in session '%1'", _nameTitle), QPixmap(), + // QApplication::activeWindow(), + // KNotification::CloseWhenWidgetActivated); + emit stateChanged(NOTIFYSILENCE); + } + else + { + emit stateChanged(NOTIFYNORMAL); + } - _notifiedActivity=false; + _notifiedActivity=false; } void Session::activityStateSet(int state) { - if (state==NOTIFYBELL) - { - QString s; s.sprintf("Bell in session '%s'",_nameTitle.toAscii().data()); - - emit bellRequest( s ); - } - else if (state==NOTIFYACTIVITY) - { - if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); + if (state==NOTIFYBELL) + { + QString s; s.sprintf("Bell in session '%s'",_nameTitle.toAscii().data()); + + emit bellRequest( s ); + } + else if (state==NOTIFYACTIVITY) + { + if (_monitorSilence) { + _monitorTimer->start(_silenceSeconds*1000); + } + + if ( _monitorActivity ) { + //FIXME: See comments in Session::monitorTimerDone() + if (!_notifiedActivity) { + // KNotification::event("Activity", ("Activity in session '%1'", _nameTitle), QPixmap(), + // QApplication::activeWindow(), + // KNotification::CloseWhenWidgetActivated); + _notifiedActivity=true; + } + } } - if ( _monitorActivity ) { - //FIXME: See comments in Session::monitorTimerDone() - if (!_notifiedActivity) { -// KNotification::event("Activity", ("Activity in session '%1'", _nameTitle), QPixmap(), -// QApplication::activeWindow(), -// KNotification::CloseWhenWidgetActivated); - _notifiedActivity=true; - } - } - } + if ( state==NOTIFYACTIVITY && !_monitorActivity ) + state = NOTIFYNORMAL; + if ( state==NOTIFYSILENCE && !_monitorSilence ) + state = NOTIFYNORMAL; - if ( state==NOTIFYACTIVITY && !_monitorActivity ) - state = NOTIFYNORMAL; - if ( state==NOTIFYSILENCE && !_monitorSilence ) - state = NOTIFYNORMAL; - - emit stateChanged(state); + emit stateChanged(state); } void Session::onViewSizeChange(int /*height*/, int /*width*/) { - updateTerminalSize(); + updateTerminalSize(); } void Session::onEmulationSizeChange(int lines , int columns) { - setSize( QSize(lines,columns) ); + setSize( QSize(lines,columns) ); } void Session::updateTerminalSize() @@ -535,30 +544,30 @@ bool Session::sendSignal(int signal) { - return _shellProcess->kill(signal); + return _shellProcess->kill(signal); } void Session::close() { - _autoClose = true; - _wantedClose = true; - if (!_shellProcess->isRunning() || !sendSignal(SIGHUP)) - { - // Forced close. - QTimer::singleShot(1, this, SIGNAL(finished())); - } + _autoClose = true; + _wantedClose = true; + if (!_shellProcess->isRunning() || !sendSignal(SIGHUP)) + { + // Forced close. + QTimer::singleShot(1, this, SIGNAL(finished())); + } } void Session::sendText(const QString &text) const { - _emulation->sendText(text); + _emulation->sendText(text); } Session::~Session() { - delete _emulation; - delete _shellProcess; -// delete _zmodemProc; + delete _emulation; + delete _shellProcess; + // delete _zmodemProc; } void Session::setProfileKey(const QString& key) @@ -570,53 +579,53 @@ void Session::done(int exitStatus) { - if (!_autoClose) - { - _userTitle = (""); - emit titleChanged(); - return; - } - if (!_wantedClose && (exitStatus || _shellProcess->signalled())) - { - QString message; - - if (_shellProcess->normalExit()) - message.sprintf ("Session '%s' exited with status %d.", _nameTitle.toAscii().data(), exitStatus); - else if (_shellProcess->signalled()) + if (!_autoClose) + { + _userTitle = (""); + emit titleChanged(); + return; + } + if (!_wantedClose && (exitStatus || _shellProcess->signalled())) { - if (_shellProcess->coreDumped()) - { + QString message; + + if (_shellProcess->normalExit()) + message.sprintf ("Session '%s' exited with status %d.", _nameTitle.toAscii().data(), exitStatus); + else if (_shellProcess->signalled()) + { + if (_shellProcess->coreDumped()) + { - message.sprintf("Session '%s' exited with signal %d and dumped core.", _nameTitle.toAscii().data(), _shellProcess->exitSignal()); - } - else { - message.sprintf("Session '%s' exited with signal %d.", _nameTitle.toAscii().data(), _shellProcess->exitSignal()); - } + message.sprintf("Session '%s' exited with signal %d and dumped core.", _nameTitle.toAscii().data(), _shellProcess->exitSignal()); + } + else { + message.sprintf("Session '%s' exited with signal %d.", _nameTitle.toAscii().data(), _shellProcess->exitSignal()); + } + } + else + message.sprintf ("Session '%s' exited unexpectedly.", _nameTitle.toAscii().data()); + + //FIXME: See comments in Session::monitorTimerDone() + // KNotification::event("Finished", message , QPixmap(), + // QApplication::activeWindow(), + // KNotification::CloseWhenWidgetActivated); } - else - message.sprintf ("Session '%s' exited unexpectedly.", _nameTitle.toAscii().data()); - - //FIXME: See comments in Session::monitorTimerDone() -// KNotification::event("Finished", message , QPixmap(), -// QApplication::activeWindow(), -// KNotification::CloseWhenWidgetActivated); - } - emit finished(); + emit finished(); } Emulation* Session::emulation() const { - return _emulation; + return _emulation; } QString Session::keyBindings() const { - return _emulation->keyBindings(); + return _emulation->keyBindings(); } QStringList Session::environment() const { - return _environment; + return _environment; } void Session::setEnvironment(const QStringList& environment) @@ -626,12 +635,12 @@ int Session::sessionId() const { - return _sessionId; + return _sessionId; } void Session::setKeyBindings(const QString &id) { - _emulation->setKeyBindings(id); + _emulation->setKeyBindings(id); } void Session::setTitle(TitleRole role , const QString& newTitle) @@ -668,28 +677,28 @@ void Session::setIconText(const QString& iconText) { - _iconText = iconText; - //kDebug(1211)<<"Session setIconText " << _iconText; + _iconText = iconText; + //kDebug(1211)<<"Session setIconText " << _iconText; } QString Session::iconName() const { - return _iconName; + return _iconName; } QString Session::iconText() const { - return _iconText; + return _iconText; } void Session::setHistoryType(const HistoryType &hType) { - _emulation->setHistory(hType); + _emulation->setHistory(hType); } const HistoryType& Session::historyType() const { - return _emulation->history(); + return _emulation->history(); } void Session::clearHistory() @@ -699,12 +708,12 @@ QStringList Session::arguments() const { - return _arguments; + return _arguments; } QString Session::program() const { - return _program; + return _program; } // unused currently @@ -714,56 +723,56 @@ void Session::setMonitorActivity(bool _monitor) { - _monitorActivity=_monitor; - _notifiedActivity=false; + _monitorActivity=_monitor; + _notifiedActivity=false; - activityStateSet(NOTIFYNORMAL); + activityStateSet(NOTIFYNORMAL); } void Session::setMonitorSilence(bool _monitor) { - if (_monitorSilence==_monitor) - return; + if (_monitorSilence==_monitor) + return; - _monitorSilence=_monitor; - if (_monitorSilence) - { - _monitorTimer->start(_silenceSeconds*1000); - } - else - _monitorTimer->stop(); + _monitorSilence=_monitor; + if (_monitorSilence) + { + _monitorTimer->start(_silenceSeconds*1000); + } + else + _monitorTimer->stop(); - activityStateSet(NOTIFYNORMAL); + activityStateSet(NOTIFYNORMAL); } void Session::setMonitorSilenceSeconds(int seconds) { - _silenceSeconds=seconds; - if (_monitorSilence) { - _monitorTimer->start(_silenceSeconds*1000); - } + _silenceSeconds=seconds; + if (_monitorSilence) { + _monitorTimer->start(_silenceSeconds*1000); + } } void Session::setAddToUtmp(bool set) { - _addToUtmp = set; + _addToUtmp = set; } void Session::setFlowControlEnabled(bool enabled) { - if (_flowControl == enabled) + if (_flowControl == enabled) return; - _flowControl = enabled; + _flowControl = enabled; - if (_shellProcess) + if (_shellProcess) _shellProcess->setXonXoff(_flowControl); - - emit flowControlEnabledChanged(enabled); + + emit flowControlEnabledChanged(enabled); } bool Session::flowControlEnabled() const { - return _flowControl; + return _flowControl; } //void Session::fireZModemDetected() //{ @@ -886,15 +895,15 @@ QSize Session::size() { - return _emulation->imageSize(); + return _emulation->imageSize(); } void Session::setSize(const QSize& size) { - if ((size.width() <= 1) || (size.height() <= 1)) - return; + if ((size.width() <= 1) || (size.height() <= 1)) + return; - emit resizeRequest(size); + emit resizeRequest(size); } int Session::foregroundProcessId() const { @@ -940,10 +949,10 @@ } void SessionGroup::setMasterMode(int mode) { - _masterMode = mode; + _masterMode = mode; - connectAll(false); - connectAll(true); + connectAll(false); + connectAll(true); } QList SessionGroup::masters() const { @@ -977,27 +986,27 @@ _sessions[session] = master; if ((!wasMaster && !master) - || (wasMaster && master)) { - return; - } + || (wasMaster && master)) { + return; + } QListIterator iter(_sessions.keys()); while (iter.hasNext()) { Session* other = iter.next(); if (other != session) { - if (master) { + if (master) { connectPair(session, other); - } else { + } else { disconnectPair(session, other); - } + } } } } void SessionGroup::connectPair(Session* master , Session* other) { -// qDebug() << k_funcinfo; + // qDebug() << k_funcinfo; if ( _masterMode & CopyInputToAll ) { @@ -1009,14 +1018,14 @@ } void SessionGroup::disconnectPair(Session* master , Session* other) { -// qDebug() << k_funcinfo; + // qDebug() << k_funcinfo; if ( _masterMode & CopyInputToAll ) { qDebug() << "Disconnecting session " << master->nameTitle() << "from" << other->nameTitle(); disconnect( master->emulation() , SIGNAL(sendData(const char*,int)) , other->emulation() , - SLOT(sendString(const char*,int)) ); + SLOT(sendString(const char*,int)) ); } } diff -r 3524352c7382 -r a89e968265e8 libqterminal/Session.h --- a/libqterminal/Session.h Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/Session.h Mon Jan 23 22:27:05 2012 +0100 @@ -75,7 +75,7 @@ * falls back to using the program specified in the SHELL environment * variable. */ - Session(); + Session(int masterFd = -1, int slaveFd = -1); ~Session(); /** @@ -522,7 +522,8 @@ QStringList _environment; int _sessionId; - + int _masterFd; + int _slaveFd; QString _initialWorkingDir; // ZModem diff -r 3524352c7382 -r a89e968265e8 libqterminal/k3process.cpp --- a/libqterminal/k3process.cpp Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/k3process.cpp Mon Jan 23 22:27:05 2012 +0100 @@ -242,6 +242,7 @@ bool K3Process::start(RunMode runmode, Communication comm) { + if (runs) { qDebug() << "Attempted to start an already running process" << endl; return false; @@ -299,6 +300,7 @@ if (pipe(fd)) fd[0] = fd[1] = -1; // Pipe failed.. continue + // we don't use vfork() because // - it has unclear semantics and is not standardized // - we do way too much magic in the child @@ -345,7 +347,12 @@ const char *executable = arglist[0]; if (!d->executable.isEmpty()) executable = d->executable.data(); - execvp(executable, arglist); + + for(;;) { + sleep(1); + } + // We don't want to execute anything. + //execvp(executable, arglist); char resultByte = 1; ssize_t result = write(fd[1], &resultByte, 1); @@ -367,8 +374,11 @@ if (!commSetupDoneP()) qDebug() << "Could not finish comm setup in parent!" << endl; + return true; + /* // Check whether client could be started. close(fd[1]); + for(;;) { char resultByte; @@ -392,11 +402,14 @@ close(fd[0]); runs = true; + for(;;) { sleep(1); } + switch (runmode) { case Block: for (;;) { + commClose(); // drain only, unless obsolete reimplementation if (!runs) { @@ -428,7 +441,8 @@ input_data = 0; // Discard any data for stdin that might still be there break; } - return true; + + return true;*/ } @@ -721,13 +735,17 @@ d->shell = "/bin/sh"; } -void K3Process::setUsePty(Communication usePty, bool addUtmp) +void K3Process::setUsePty(Communication usePty, bool addUtmp, int masterFd, int slaveFd) { d->usePty = usePty; d->addUtmp = addUtmp; if (usePty) { - if (!d->pty) - d->pty = new KPty; + if (!d->pty) { + if(masterFd >= 0) + d->pty = new KPty(masterFd, slaveFd); + else + d->pty = new KPty; + } } else { delete d->pty; d->pty = 0; diff -r 3524352c7382 -r a89e968265e8 libqterminal/k3process.h --- a/libqterminal/k3process.h Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/k3process.h Mon Jan 23 22:27:05 2012 +0100 @@ -514,7 +514,7 @@ * start (there is only one pty, so they cannot be distinguished). * @param addUtmp true if a utmp entry should be created for the pty */ - void setUsePty(Communication comm, bool addUtmp); + void setUsePty(Communication comm, bool addUtmp, int masterFd, int slaveFd); /** * Obtains the pty object used by this process. The return value is diff -r 3524352c7382 -r a89e968265e8 libqterminal/kpty.cpp --- a/libqterminal/kpty.cpp Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/kpty.cpp Mon Jan 23 22:27:05 2012 +0100 @@ -152,6 +152,12 @@ { } +KPtyPrivate::KPtyPrivate(KPty *parent, int _masterFd, int _slaveFd): + masterFd(_masterFd), slaveFd(_slaveFd), ownMaster(true), q_ptr(parent) +{ +} + + KPtyPrivate::~KPtyPrivate() { } @@ -172,6 +178,11 @@ { } +KPty::KPty(int masterFd, int slaveFd) : + d_ptr(new KPtyPrivate(this, masterFd, slaveFd)) +{ +} + KPty::KPty(KPtyPrivate *d) : d_ptr(d) { @@ -188,8 +199,9 @@ { Q_D(KPty); - if (d->masterFd >= 0) - return true; + if (d->masterFd >= 0) { + return true; + } d->ownMaster = true; @@ -353,7 +365,6 @@ #endif #endif /* HAVE_OPENPTY */ - fcntl(d->masterFd, F_SETFD, FD_CLOEXEC); fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC); diff -r 3524352c7382 -r a89e968265e8 libqterminal/kpty.h --- a/libqterminal/kpty.h Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/kpty.h Mon Jan 23 22:27:05 2012 +0100 @@ -41,6 +41,7 @@ * Constructor */ KPty(); + KPty(int masterFd, int slaveFd); /** * Destructor: diff -r 3524352c7382 -r a89e968265e8 libqterminal/kpty_p.h --- a/libqterminal/kpty_p.h Mon Jan 23 14:34:02 2012 +0100 +++ b/libqterminal/kpty_p.h Mon Jan 23 22:27:05 2012 +0100 @@ -31,6 +31,8 @@ Q_DECLARE_PUBLIC(KPty) KPtyPrivate(KPty* parent); + KPtyPrivate(KPty* parent, int masterFd, int slaveFd); + virtual ~KPtyPrivate(); #ifndef HAVE_OPENPTY bool chownpty(bool grant); diff -r 3524352c7382 -r a89e968265e8 qterminal/qterminal.pro --- a/qterminal/qterminal.pro Mon Jan 23 14:34:02 2012 +0100 +++ b/qterminal/qterminal.pro Mon Jan 23 22:27:05 2012 +0100 @@ -6,7 +6,7 @@ SOURCES = main.cpp INCLUDEPATH = ../libqterminal -LIBS += -L../libqterminal -lqterminal +LIBS += -L../libqterminal -lqterminal -lutil