/* * This file is a part of QTerminal - http://gitorious.org/qterminal * * This file was un-linked from KDE and modified * by Maxim Bourmistrov * */ /* This file is part of the KDE libraries Copyright (C) 2007 Oswald Buddenhagen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kptyprocess.h" #include "kprocess.h" #include "kptydevice.h" #include #include #include #include KPtyProcess::KPtyProcess(QObject *parent) : KPtyProcess(-1, parent) { Q_D(KPtyProcess); d->pty = std::make_unique(this); d->pty->open(); connect(this, SIGNAL(stateChanged(QProcess::ProcessState)), SLOT(_k_onStateChanged(QProcess::ProcessState))); setChildProcessModifier([this] { Q_D(KPtyProcess); d->pty->setCTty(); #if 0 if (d->addUtmp) d->pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY")); #endif if (d->ptyChannels & StdinChannel) dup2(d->pty->slaveFd(), 0); if (d->ptyChannels & StdoutChannel) dup2(d->pty->slaveFd(), 1); if (d->ptyChannels & StderrChannel) dup2(d->pty->slaveFd(), 2); }); } KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent) : KProcess(parent), d_ptr(new KPtyProcessPrivate) { Q_D(KPtyProcess); d->pty = std::make_unique(this); if (ptyMasterFd == -1) { d->pty->open(); } else { d->pty->open(ptyMasterFd); } connect(this, &QProcess::stateChanged, this, [this](QProcess::ProcessState state) { if (state == QProcess::NotRunning && d_ptr->addUtmp) { d_ptr->pty->logout(); } }); } KPtyProcess::~KPtyProcess() { Q_D(KPtyProcess); if (state() != QProcess::NotRunning) { if (d->addUtmp) { d->pty->logout(); disconnect(this, &QProcess::stateChanged, this, nullptr); } } waitForFinished(300); // give it some time to finish if (state() != QProcess::NotRunning) { qWarning() << Q_FUNC_INFO << "the terminal process is still running, trying to stop it by SIGHUP"; ::kill(static_cast(processId()), SIGHUP); waitForFinished(300); if (state() != QProcess::NotRunning) qCritical() << Q_FUNC_INFO << "process didn't stop upon SIGHUP and will be SIGKILL-ed"; } } void KPtyProcess::setPtyChannels(PtyChannels channels) { Q_D(KPtyProcess); d->ptyChannels = channels; } KPtyProcess::PtyChannels KPtyProcess::ptyChannels() const { Q_D(const KPtyProcess); return d->ptyChannels; } void KPtyProcess::setUseUtmp(bool value) { Q_D(KPtyProcess); d->addUtmp = value; } bool KPtyProcess::isUseUtmp() const { Q_D(const KPtyProcess); return d->addUtmp; } KPtyDevice *KPtyProcess::pty() const { Q_D(const KPtyProcess); return d->pty.get(); } #if QT_VERSION < 0x060000 void KPtyProcess::setupChildProcess() { Q_D(KPtyProcess); d->pty->setCTty(); #if 0 if (d->addUtmp) d->pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY")); #endif if (d->ptyChannels & StdinChannel) dup2(d->pty->slaveFd(), 0); if (d->ptyChannels & StdoutChannel) dup2(d->pty->slaveFd(), 1); if (d->ptyChannels & StderrChannel) dup2(d->pty->slaveFd(), 2); KProcess::setupChildProcess(); } #endif //#include "kptyprocess.moc"