1/*
2 * This file is a part of QTerminal - http://gitorious.org/qterminal
3 *
4 * This file was un-linked from KDE and modified
5 * by Maxim Bourmistrov <maxim@unixconn.com>
6 *
7 */
8
9/*
10 This file is part of the KDE libraries
11
12 Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
13
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Library General Public
16 License as published by the Free Software Foundation; either
17 version 2 of the License, or (at your option) any later version.
18
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Library General Public License for more details.
23
24 You should have received a copy of the GNU Library General Public License
25 along with this library; see the file COPYING.LIB. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28*/
29
30
31#include "kptyprocess.h"
32#include "kprocess.h"
33#include "kptydevice.h"
34
35#include <stdlib.h>
36#include <unistd.h>
37#include <signal.h>
38#include <QDebug>
39
40KPtyProcess::KPtyProcess(QObject *parent) :
41 KProcess(new KPtyProcessPrivate, parent)
42{
43 Q_D(KPtyProcess);
44
45 d->pty = new KPtyDevice(this);
46 d->pty->open();
47 connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
48 SLOT(_k_onStateChanged(QProcess::ProcessState)));
49}
50
51KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent) :
52 KProcess(new KPtyProcessPrivate, parent)
53{
54 Q_D(KPtyProcess);
55
56 d->pty = new KPtyDevice(this);
57 d->pty->open(ptyMasterFd);
58 connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
59 SLOT(_k_onStateChanged(QProcess::ProcessState)));
60}
61
62KPtyProcess::~KPtyProcess()
63{
64 Q_D(KPtyProcess);
65
66 if (state() != QProcess::NotRunning)
67 {
68 if (d->addUtmp)
69 {
70 d->pty->logout();
71 disconnect(SIGNAL(stateChanged(QProcess::ProcessState)),
72 this, SLOT(_k_onStateChanged(QProcess::ProcessState)));
73 }
74 }
75 delete d->pty;
76 waitForFinished(300); // give it some time to finish
77 if (state() != QProcess::NotRunning)
78 {
79 qWarning() << Q_FUNC_INFO << "the terminal process is still running, trying to stop it by SIGHUP";
80 ::kill(pid(), SIGHUP);
81 waitForFinished(300);
82 if (state() != QProcess::NotRunning)
83 qCritical() << Q_FUNC_INFO << "process didn't stop upon SIGHUP and will be SIGKILL-ed";
84 }
85}
86
87void KPtyProcess::setPtyChannels(PtyChannels channels)
88{
89 Q_D(KPtyProcess);
90
91 d->ptyChannels = channels;
92}
93
94KPtyProcess::PtyChannels KPtyProcess::ptyChannels() const
95{
96 Q_D(const KPtyProcess);
97
98 return d->ptyChannels;
99}
100
101void KPtyProcess::setUseUtmp(bool value)
102{
103 Q_D(KPtyProcess);
104
105 d->addUtmp = value;
106}
107
108bool KPtyProcess::isUseUtmp() const
109{
110 Q_D(const KPtyProcess);
111
112 return d->addUtmp;
113}
114
115KPtyDevice *KPtyProcess::pty() const
116{
117 Q_D(const KPtyProcess);
118
119 return d->pty;
120}
121
122void KPtyProcess::setupChildProcess()
123{
124 Q_D(KPtyProcess);
125
126 d->pty->setCTty();
127
128#if 0
129 if (d->addUtmp)
130 d->pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY"));
131#endif
132 if (d->ptyChannels & StdinChannel)
133 dup2(d->pty->slaveFd(), 0);
134
135 if (d->ptyChannels & StdoutChannel)
136 dup2(d->pty->slaveFd(), 1);
137
138 if (d->ptyChannels & StderrChannel)
139 dup2(d->pty->slaveFd(), 2);
140
141 KProcess::setupChildProcess();
142}
143
144//#include "kptyprocess.moc"
145