File indexing completed on 2024-04-28 11:44:05

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2007 Oswald Buddenhagen <ossi@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kptyprocess.h"
0009 
0010 #include <kptydevice.h>
0011 #include <kuser.h>
0012 
0013 #include <stdlib.h>
0014 #include <unistd.h>
0015 
0016 //////////////////
0017 // private data //
0018 //////////////////
0019 
0020 class KPtyProcessPrivate
0021 {
0022 public:
0023     KPtyProcessPrivate()
0024     {
0025     }
0026 
0027     std::unique_ptr<KPtyDevice> pty;
0028     KPtyProcess::PtyChannels ptyChannels = KPtyProcess::NoChannels;
0029     bool addUtmp = false;
0030 };
0031 
0032 KPtyProcess::KPtyProcess(QObject *parent)
0033     : KPtyProcess(-1, parent)
0034 {
0035 }
0036 
0037 KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent)
0038     : KProcess(parent)
0039     , d_ptr(new KPtyProcessPrivate)
0040 {
0041     Q_D(KPtyProcess);
0042 
0043     d->pty = std::make_unique<KPtyDevice>(this);
0044 
0045     if (ptyMasterFd == -1) {
0046         d->pty->open();
0047     } else {
0048         d->pty->open(ptyMasterFd);
0049     }
0050 
0051     connect(this, &QProcess::stateChanged, this, [this](QProcess::ProcessState state) {
0052         if (state == QProcess::NotRunning && d_ptr->addUtmp) {
0053             d_ptr->pty->logout();
0054         }
0055     });
0056 }
0057 
0058 KPtyProcess::~KPtyProcess()
0059 {
0060     Q_D(KPtyProcess);
0061 
0062     if (state() != QProcess::NotRunning && d->addUtmp) {
0063         d->pty->logout();
0064         disconnect(this, &QProcess::stateChanged, this, nullptr);
0065     }
0066 }
0067 
0068 void KPtyProcess::setPtyChannels(PtyChannels channels)
0069 {
0070     Q_D(KPtyProcess);
0071 
0072     d->ptyChannels = channels;
0073 }
0074 
0075 KPtyProcess::PtyChannels KPtyProcess::ptyChannels() const
0076 {
0077     Q_D(const KPtyProcess);
0078 
0079     return d->ptyChannels;
0080 }
0081 
0082 void KPtyProcess::setUseUtmp(bool value)
0083 {
0084     Q_D(KPtyProcess);
0085 
0086     d->addUtmp = value;
0087 }
0088 
0089 bool KPtyProcess::isUseUtmp() const
0090 {
0091     Q_D(const KPtyProcess);
0092 
0093     return d->addUtmp;
0094 }
0095 
0096 KPtyDevice *KPtyProcess::pty() const
0097 {
0098     Q_D(const KPtyProcess);
0099 
0100     return d->pty.get();
0101 }
0102 
0103 void KPtyProcess::setupChildProcess()
0104 {
0105     Q_D(KPtyProcess);
0106 
0107     d->pty->setCTty();
0108     if (d->addUtmp) {
0109         d->pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().constData(), qgetenv("DISPLAY").constData());
0110     }
0111     if (d->ptyChannels & StdinChannel) {
0112         dup2(d->pty->slaveFd(), 0);
0113     }
0114     if (d->ptyChannels & StdoutChannel) {
0115         dup2(d->pty->slaveFd(), 1);
0116     }
0117     if (d->ptyChannels & StderrChannel) {
0118         dup2(d->pty->slaveFd(), 2);
0119     }
0120 
0121     KProcess::setupChildProcess();
0122 }
0123 
0124 #include "moc_kptyprocess.cpp"