• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Konsole

  • kde-4.14
  • applications
  • konsole
  • src
Pty.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Konsole, an X terminal.
3  Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301 USA.
19 */
20 
21 // Own
22 #include "Pty.h"
23 
24 // System
25 #include <termios.h>
26 #include <signal.h>
27 
28 // Qt
29 #include <QtCore/QStringList>
30 
31 // KDE
32 #include <KDebug>
33 #include <KPtyDevice>
34 #include <kde_file.h>
35 
36 using Konsole::Pty;
37 
38 Pty::Pty(int masterFd, QObject* aParent)
39  : KPtyProcess(masterFd, aParent)
40 {
41  init();
42 }
43 
44 Pty::Pty(QObject* aParent)
45  : KPtyProcess(aParent)
46 {
47  init();
48 }
49 
50 void Pty::init()
51 {
52  _windowColumns = 0;
53  _windowLines = 0;
54  _eraseChar = 0;
55  _xonXoff = true;
56  _utf8 = true;
57 
58  setEraseChar(_eraseChar);
59  setFlowControlEnabled(_xonXoff);
60  setUtf8Mode(_utf8);
61 
62  setWindowSize(_windowColumns, _windowLines);
63 
64  setUseUtmp(true);
65  setPtyChannels(KPtyProcess::AllChannels);
66 
67  connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
68 }
69 
70 Pty::~Pty()
71 {
72 }
73 
74 void Pty::sendData(const char* data, int length)
75 {
76  if (length == 0)
77  return;
78 
79  if (!pty()->write(data, length)) {
80  kWarning() << "Could not send input data to terminal process.";
81  return;
82  }
83 }
84 
85 void Pty::dataReceived()
86 {
87  QByteArray data = pty()->readAll();
88  emit receivedData(data.constData(), data.count());
89 }
90 
91 void Pty::setWindowSize(int columns, int lines)
92 {
93  _windowColumns = columns;
94  _windowLines = lines;
95 
96  if (pty()->masterFd() >= 0)
97  pty()->setWinSize(lines, columns);
98 }
99 
100 QSize Pty::windowSize() const
101 {
102  return QSize(_windowColumns, _windowLines);
103 }
104 
105 void Pty::setFlowControlEnabled(bool enable)
106 {
107  _xonXoff = enable;
108 
109  if (pty()->masterFd() >= 0) {
110  struct ::termios ttmode;
111  pty()->tcGetAttr(&ttmode);
112  if (enable)
113  ttmode.c_iflag |= (IXOFF | IXON);
114  else
115  ttmode.c_iflag &= ~(IXOFF | IXON);
116 
117  if (!pty()->tcSetAttr(&ttmode))
118  kWarning() << "Unable to set terminal attributes.";
119  }
120 }
121 
122 bool Pty::flowControlEnabled() const
123 {
124  if (pty()->masterFd() >= 0) {
125  struct ::termios ttmode;
126  pty()->tcGetAttr(&ttmode);
127  return ttmode.c_iflag & IXOFF &&
128  ttmode.c_iflag & IXON;
129  } else {
130  kWarning() << "Unable to get flow control status, terminal not connected.";
131  return _xonXoff;
132  }
133 }
134 
135 void Pty::setUtf8Mode(bool enable)
136 {
137 #if defined(IUTF8) // XXX not a reasonable place to check it.
138  _utf8 = enable;
139 
140  if (pty()->masterFd() >= 0) {
141  struct ::termios ttmode;
142  pty()->tcGetAttr(&ttmode);
143  if (enable)
144  ttmode.c_iflag |= IUTF8;
145  else
146  ttmode.c_iflag &= ~IUTF8;
147 
148  if (!pty()->tcSetAttr(&ttmode))
149  kWarning() << "Unable to set terminal attributes.";
150  }
151 #else
152  Q_UNUSED(enable);
153 #endif
154 }
155 
156 void Pty::setEraseChar(char eChar)
157 {
158  _eraseChar = eChar;
159 
160  if (pty()->masterFd() >= 0) {
161  struct ::termios ttmode;
162  pty()->tcGetAttr(&ttmode);
163  ttmode.c_cc[VERASE] = eChar;
164 
165  if (!pty()->tcSetAttr(&ttmode))
166  kWarning() << "Unable to set terminal attributes.";
167  }
168 }
169 
170 char Pty::eraseChar() const
171 {
172  if (pty()->masterFd() >= 0) {
173  struct ::termios ttyAttributes;
174  pty()->tcGetAttr(&ttyAttributes);
175  return ttyAttributes.c_cc[VERASE];
176  } else {
177  kWarning() << "Unable to get erase char attribute, terminal not connected.";
178  return _eraseChar;
179  }
180 }
181 
182 void Pty::setInitialWorkingDirectory(const QString& dir)
183 {
184  QString pwd = dir;
185 
186  // remove trailing slash in the path when appropriate
187  // example: /usr/share/icons/ ==> /usr/share/icons
188  if (pwd.length() > 1 && pwd.endsWith(QLatin1Char('/'))) {
189  pwd.chop(1);
190  }
191 
192  setWorkingDirectory(pwd);
193 
194  // setting PWD to "." will cause problem for bash & zsh
195  if (pwd != ".")
196  setEnv("PWD", pwd);
197 }
198 
199 void Pty::addEnvironmentVariables(const QStringList& environmentVariables)
200 {
201  bool isTermEnvAdded = false;
202 
203  foreach(const QString& pair, environmentVariables) {
204  // split on the first '=' character
205  const int separator = pair.indexOf('=');
206 
207  if (separator >= 0) {
208  QString variable = pair.left(separator);
209  QString value = pair.mid(separator + 1);
210 
211  setEnv(variable, value);
212 
213  if (variable == "TERM") {
214  isTermEnvAdded = true;
215  }
216  }
217  }
218 
219  // extra safeguard to make sure $TERM is always set
220  if (!isTermEnvAdded) {
221  setEnv("TERM", "xterm");
222  }
223 }
224 
225 int Pty::start(const QString& programName,
226  const QStringList& programArguments,
227  const QStringList& environmentList)
228 {
229  clearProgram();
230 
231  // For historical reasons, the first argument in programArguments is the
232  // name of the program to execute, so create a list consisting of all
233  // but the first argument to pass to setProgram()
234  Q_ASSERT(programArguments.count() >= 1);
235  setProgram(programName, programArguments.mid(1));
236 
237  addEnvironmentVariables(environmentList);
238 
239  // unless the LANGUAGE environment variable has been set explicitly
240  // set it to a null string
241  // this fixes the problem where KCatalog sets the LANGUAGE environment
242  // variable during the application's startup to something which
243  // differs from LANG,LC_* etc. and causes programs run from
244  // the terminal to display messages in the wrong language
245  //
246  // this can happen if LANG contains a language which KDE
247  // does not have a translation for
248  //
249  // BR:149300
250  setEnv("LANGUAGE", QString(), false /* do not overwrite existing value if any */);
251 
252  KProcess::start();
253 
254  if (waitForStarted()) {
255  return 0;
256  } else {
257  return -1;
258  }
259 }
260 
261 void Pty::setWriteable(bool writeable)
262 {
263  KDE_struct_stat sbuf;
264  if (KDE::stat(pty()->ttyName(), &sbuf) == 0) {
265  if (writeable) {
266  if (KDE::chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP) < 0) {
267  kWarning() << "Could not set writeable on "<<pty()->ttyName();
268  }
269  } else {
270  if (KDE::chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
271  kWarning() << "Could not unset writeable on "<<pty()->ttyName();
272  }
273  }
274  }
275 }
276 
277 void Pty::closePty()
278 {
279  pty()->close();
280 }
281 
282 int Pty::foregroundProcessGroup() const
283 {
284  int foregroundPid = tcgetpgrp(pty()->masterFd());
285 
286  if (foregroundPid != -1) {
287  return foregroundPid;
288  }
289 
290  return 0;
291 }
292 
293 void Pty::setupChildProcess()
294 {
295  KPtyProcess::setupChildProcess();
296 
297  // reset all signal handlers
298  // this ensures that terminal applications respond to
299  // signals generated via key sequences such as Ctrl+C
300  // (which sends SIGINT)
301  struct sigaction action;
302  sigemptyset(&action.sa_mask);
303  action.sa_handler = SIG_DFL;
304  action.sa_flags = 0;
305  for (int signal = 1; signal < NSIG; signal++)
306  sigaction(signal, &action, 0);
307 }
308 
309 #include "Pty.moc"
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
Konsole::Pty::sendData
void sendData(const char *buffer, int length)
Sends data to the process currently controlling the teletype ( whose id is returned by foregroundProc...
Definition: Pty.cpp:74
Konsole::Pty::foregroundProcessGroup
int foregroundProcessGroup() const
Returns the process id of the teletype's current foreground process.
Definition: Pty.cpp:282
Konsole::Pty::setupChildProcess
void setupChildProcess()
Definition: Pty.cpp:293
Konsole::Pty::start
int start(const QString &program, const QStringList &arguments, const QStringList &environment)
Starts the terminal process.
Definition: Pty.cpp:225
QByteArray
Konsole::Pty::setEraseChar
void setEraseChar(char eraseChar)
Sets the special character for erasing previous not-yet-erased character.
Definition: Pty.cpp:156
Konsole::Pty::closePty
void closePty()
Close the underlying pty master/slave pair.
Definition: Pty.cpp:277
Konsole::Pty::windowSize
QSize windowSize() const
Returns the size of the window used by this teletype.
Definition: Pty.cpp:100
Konsole::Pty::setWindowSize
void setWindowSize(int columns, int lines)
Sets the size of the window (in columns and lines of characters) used by this teletype.
Definition: Pty.cpp:91
QString::chop
void chop(int n)
Konsole::Pty::receivedData
void receivedData(const char *buffer, int length)
Emitted when a new block of data is received from the teletype.
Konsole::Pty::~Pty
~Pty()
Definition: Pty.cpp:70
Konsole::Pty
The Pty class is used to start the terminal process, send data to it, receive data from it and manipu...
Definition: Pty.h:52
QList::count
int count(const T &value) const
QObject
Konsole::Pty::eraseChar
char eraseChar() const
Definition: Pty.cpp:170
QByteArray::constData
const char * constData() const
Konsole::Pty::Pty
Pty(QObject *parent=0)
Constructs a new Pty.
Definition: Pty.cpp:44
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QByteArray::count
int count(char ch) const
QString
QStringList
QSize
Pty.h
QLatin1Char
Konsole::Pty::setInitialWorkingDirectory
void setInitialWorkingDirectory(const QString &dir)
Sets the initial working directory.
Definition: Pty.cpp:182
Konsole::Pty::flowControlEnabled
bool flowControlEnabled() const
Queries the terminal state and returns true if Xon/Xoff flow control is enabled.
Definition: Pty.cpp:122
QString::mid
QString mid(int position, int n) const
Konsole::Pty::setFlowControlEnabled
void setFlowControlEnabled(bool on)
Enables or disables Xon/Xoff flow control.
Definition: Pty.cpp:105
KPtyProcess
QList::mid
QList< T > mid(int pos, int length) const
QString::length
int length() const
QString::left
QString left(int n) const
Konsole::Pty::setWriteable
void setWriteable(bool writeable)
Control whether the pty device is writeable by group members.
Definition: Pty.cpp:261
Konsole::Pty::setUtf8Mode
void setUtf8Mode(bool on)
Put the pty into UTF-8 mode on systems which support it.
Definition: Pty.cpp:135
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal