source: ogBrowser-Git/qtermwidget/lib/Pty.cpp

jenkins
Last change on this file was fedf2a2, checked in by Vadim Troshchinskiy Shmelev <vtroshchinskiy@…>, 18 months ago

Update Qtermwidget to Qt6 version
Remove build files

  • Property mode set to 100644
File size: 8.1 KB
Line 
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 Konsole, an X terminal.
11    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301  USA.
27*/
28
29// Own
30#include "Pty.h"
31
32// System
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <unistd.h>
36#include <cerrno>
37#include <termios.h>
38#include <csignal>
39
40// Qt
41#include <QStringList>
42#include <QtDebug>
43
44#include "kpty.h"
45#include "kptydevice.h"
46
47using namespace Konsole;
48
49void Pty::setWindowSize(int lines, int cols)
50{
51  _windowColumns = cols;
52  _windowLines = lines;
53
54  if (pty()->masterFd() >= 0)
55    pty()->setWinSize(lines, cols);
56}
57QSize Pty::windowSize() const
58{
59    return {_windowColumns,_windowLines};
60}
61
62void Pty::setFlowControlEnabled(bool enable)
63{
64  _xonXoff = enable;
65
66  if (pty()->masterFd() >= 0)
67  {
68    struct ::termios ttmode;
69    pty()->tcGetAttr(&ttmode);
70    if (!enable)
71      ttmode.c_iflag &= ~(IXOFF | IXON);
72    else
73      ttmode.c_iflag |= (IXOFF | IXON);
74    if (!pty()->tcSetAttr(&ttmode))
75      qWarning() << "Unable to set terminal attributes.";
76  }
77}
78bool Pty::flowControlEnabled() const
79{
80    if (pty()->masterFd() >= 0)
81    {
82        struct ::termios ttmode;
83        pty()->tcGetAttr(&ttmode);
84        return ttmode.c_iflag & IXOFF &&
85               ttmode.c_iflag & IXON;
86    }
87    qWarning() << "Unable to get flow control status, terminal not connected.";
88    return false;
89}
90
91void Pty::setUtf8Mode(bool enable)
92{
93#ifdef IUTF8 // XXX not a reasonable place to check it.
94  _utf8 = enable;
95
96  if (pty()->masterFd() >= 0)
97  {
98    struct ::termios ttmode;
99    pty()->tcGetAttr(&ttmode);
100    if (!enable)
101      ttmode.c_iflag &= ~IUTF8;
102    else
103      ttmode.c_iflag |= IUTF8;
104    if (!pty()->tcSetAttr(&ttmode))
105      qWarning() << "Unable to set terminal attributes.";
106  }
107#endif
108}
109
110void Pty::setErase(char erase)
111{
112  _eraseChar = erase;
113
114  if (pty()->masterFd() >= 0)
115  {
116    struct ::termios ttmode;
117    pty()->tcGetAttr(&ttmode);
118    ttmode.c_cc[VERASE] = erase;
119    if (!pty()->tcSetAttr(&ttmode))
120      qWarning() << "Unable to set terminal attributes.";
121  }
122}
123
124char Pty::erase() const
125{
126    if (pty()->masterFd() >= 0)
127    {
128        struct ::termios ttyAttributes;
129        pty()->tcGetAttr(&ttyAttributes);
130        return ttyAttributes.c_cc[VERASE];
131    }
132
133    return _eraseChar;
134}
135
136void Pty::addEnvironmentVariables(const QStringList& environment)
137{
138
139    bool termEnvVarAdded = false;
140    for (const QString &pair : environment)
141    {
142        // split on the first '=' character
143        int pos = pair.indexOf(QLatin1Char('='));
144
145        if ( pos >= 0 )
146        {
147            QString variable = pair.left(pos);
148            QString value = pair.mid(pos+1);
149
150            setEnv(variable,value);
151
152            if (variable == QLatin1String("TERM")) {
153                termEnvVarAdded = true;
154        }
155    }
156
157    // fallback to ensure that $TERM is always set
158    if (!termEnvVarAdded) {
159        setEnv(QStringLiteral("TERM"), QStringLiteral("xterm-256color"));
160    }
161}
162}
163
164int Pty::start(const QString& program,
165               const QStringList& programArguments,
166               const QStringList& environment,
167               ulong winid,
168               bool addToUtmp
169               //const QString& dbusService,
170               //const QString& dbusSession
171               )
172{
173  clearProgram();
174
175  // For historical reasons, the first argument in programArguments is the
176  // name of the program to execute, so create a list consisting of all
177  // but the first argument to pass to setProgram()
178  Q_ASSERT(programArguments.count() >= 1);
179  setProgram(program, programArguments.mid(1));
180
181  addEnvironmentVariables(environment);
182
183  setEnv(QLatin1String("WINDOWID"), QString::number(winid));
184  setEnv(QLatin1String("COLORTERM"), QLatin1String("truecolor"));
185
186  // unless the LANGUAGE environment variable has been set explicitly
187  // set it to a null string
188  // this fixes the problem where KCatalog sets the LANGUAGE environment
189  // variable during the application's startup to something which
190  // differs from LANG,LC_* etc. and causes programs run from
191  // the terminal to display messages in the wrong language
192  //
193  // this can happen if LANG contains a language which KDE
194  // does not have a translation for
195  //
196  // BR:149300
197  setEnv(QLatin1String("LANGUAGE"),QString(),false /* do not overwrite existing value if any */);
198
199  setUseUtmp(addToUtmp);
200
201  struct ::termios ttmode;
202  pty()->tcGetAttr(&ttmode);
203  if (!_xonXoff)
204    ttmode.c_iflag &= ~(IXOFF | IXON);
205  else
206    ttmode.c_iflag |= (IXOFF | IXON);
207#ifdef IUTF8 // XXX not a reasonable place to check it.
208  if (!_utf8)
209    ttmode.c_iflag &= ~IUTF8;
210  else
211    ttmode.c_iflag |= IUTF8;
212#endif
213
214  if (_eraseChar != 0)
215      ttmode.c_cc[VERASE] = _eraseChar;
216
217  if (!pty()->tcSetAttr(&ttmode))
218    qWarning() << "Unable to set terminal attributes.";
219
220  pty()->setWinSize(_windowLines, _windowColumns);
221
222  KProcess::start();
223
224  if (!waitForStarted())
225      return -1;
226
227  return 0;
228}
229
230void Pty::setEmptyPTYProperties()
231{
232    struct ::termios ttmode;
233    pty()->tcGetAttr(&ttmode);
234    if (!_xonXoff)
235      ttmode.c_iflag &= ~(IXOFF | IXON);
236    else
237      ttmode.c_iflag |= (IXOFF | IXON);
238  #ifdef IUTF8 // XXX not a reasonable place to check it.
239    if (!_utf8)
240      ttmode.c_iflag &= ~IUTF8;
241    else
242      ttmode.c_iflag |= IUTF8;
243  #endif
244
245    if (_eraseChar != 0)
246        ttmode.c_cc[VERASE] = _eraseChar;
247
248    if (!pty()->tcSetAttr(&ttmode))
249      qWarning() << "Unable to set terminal attributes.";
250}
251
252void Pty::setWriteable(bool writeable)
253{
254  struct stat sbuf;
255  stat(pty()->ttyName(), &sbuf);
256  if (writeable)
257    chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
258  else
259    chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
260}
261
262Pty::Pty(int masterFd, QObject* parent)
263    : KPtyProcess(masterFd,parent)
264{
265    init();
266}
267Pty::Pty(QObject* parent)
268    : KPtyProcess(parent)
269{
270    init();
271}
272void Pty::init()
273{
274  _windowColumns = 0;
275  _windowLines = 0;
276  _eraseChar = 0;
277  _xonXoff = true;
278  _utf8 =true;
279
280  connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
281  setPtyChannels(KPtyProcess::AllChannels);
282}
283
284Pty::~Pty()
285{
286}
287
288void Pty::sendData(const char* data, int length)
289{
290  if (!length)
291      return;
292
293  if (!pty()->write(data,length))
294  {
295    qWarning() << "Pty::doSendJobs - Could not send input data to terminal process.";
296    return;
297  }
298}
299
300void Pty::dataReceived()
301{
302     QByteArray data = pty()->readAll();
303    emit receivedData(data.constData(),data.length());
304}
305
306void Pty::lockPty(bool lock)
307{
308    Q_UNUSED(lock);
309
310// TODO: Support for locking the Pty
311  //if (lock)
312    //suspend();
313  //else
314    //resume();
315}
316
317int Pty::foregroundProcessGroup() const
318{
319    int pid = tcgetpgrp(pty()->masterFd());
320
321    if ( pid != -1 )
322    {
323        return pid;
324    }
325
326    return 0;
327}
328
329// TODO: we need to handle this
330#if QT_VERSION < 0x060000
331void Pty::setupChildProcess()
332{
333    KPtyProcess::setupChildProcess();
334    // reset all signal handlers
335    // this ensures that terminal applications respond to
336    // signals generated via key sequences such as Ctrl+C
337    // (which sends SIGINT)
338    struct sigaction action;
339    sigset_t sigset;
340    sigemptyset(&action.sa_mask);
341    sigemptyset(&sigset);
342    action.sa_handler = SIG_DFL;
343    action.sa_flags = 0;
344    for (int signal=1;signal < NSIG; signal++) {
345        sigaction(signal,&action,nullptr);
346        sigaddset(&sigset, signal);
347    }
348    sigprocmask(SIG_UNBLOCK, &sigset, nullptr);
349}
350#endif
Note: See TracBrowser for help on using the repository browser.