1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2007 Oswald Buddenhagen <ossi@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "kptyprocess.h"
9
10#include <kptydevice.h>
11#include <kuser.h>
12
13#include <stdlib.h>
14#include <unistd.h>
15
16//////////////////
17// private data //
18//////////////////
19
20class KPtyProcessPrivate
21{
22public:
23 KPtyProcessPrivate()
24 {
25 }
26
27 std::unique_ptr<KPtyDevice> pty;
28 KPtyProcess::PtyChannels ptyChannels = KPtyProcess::NoChannels;
29 bool addUtmp = false;
30};
31
32KPtyProcess::KPtyProcess(QObject *parent)
33 : KPtyProcess(-1, parent)
34{
35}
36
37KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent)
38 : KProcess(parent)
39 , d_ptr(new KPtyProcessPrivate)
40{
41 Q_D(KPtyProcess);
42
43 auto parentChildProcModifier = KProcess::childProcessModifier();
44 setChildProcessModifier([d, parentChildProcModifier]() {
45 d->pty->setCTty();
46 if (d->addUtmp) {
47 d->pty->login(user: KUser(KUser::UseRealUserID).loginName().toLocal8Bit().constData(), remotehost: qgetenv(varName: "DISPLAY").constData());
48 }
49 if (d->ptyChannels & StdinChannel) {
50 dup2(fd: d->pty->slaveFd(), fd2: 0);
51 }
52 if (d->ptyChannels & StdoutChannel) {
53 dup2(fd: d->pty->slaveFd(), fd2: 1);
54 }
55 if (d->ptyChannels & StderrChannel) {
56 dup2(fd: d->pty->slaveFd(), fd2: 2);
57 }
58
59 if (parentChildProcModifier) {
60 parentChildProcModifier();
61 }
62 });
63
64 d->pty = std::make_unique<KPtyDevice>(args: this);
65
66 if (ptyMasterFd == -1) {
67 d->pty->open();
68 } else {
69 d->pty->open(fd: ptyMasterFd);
70 }
71
72 connect(sender: this, signal: &QProcess::stateChanged, context: this, slot: [this](QProcess::ProcessState state) {
73 if (state == QProcess::NotRunning && d_ptr->addUtmp) {
74 d_ptr->pty->logout();
75 }
76 });
77}
78
79KPtyProcess::~KPtyProcess()
80{
81 Q_D(KPtyProcess);
82
83 if (state() != QProcess::NotRunning && d->addUtmp) {
84 d->pty->logout();
85 disconnect(sender: this, signal: &QProcess::stateChanged, receiver: this, zero: nullptr);
86 }
87}
88
89void KPtyProcess::setPtyChannels(PtyChannels channels)
90{
91 Q_D(KPtyProcess);
92
93 d->ptyChannels = channels;
94}
95
96KPtyProcess::PtyChannels KPtyProcess::ptyChannels() const
97{
98 Q_D(const KPtyProcess);
99
100 return d->ptyChannels;
101}
102
103void KPtyProcess::setUseUtmp(bool value)
104{
105 Q_D(KPtyProcess);
106
107 d->addUtmp = value;
108}
109
110bool KPtyProcess::isUseUtmp() const
111{
112 Q_D(const KPtyProcess);
113
114 return d->addUtmp;
115}
116
117KPtyDevice *KPtyProcess::pty() const
118{
119 Q_D(const KPtyProcess);
120
121 return d->pty.get();
122}
123
124#include "moc_kptyprocess.cpp"
125

source code of kpty/src/kptyprocess.cpp