File indexing completed on 2024-04-28 09:46:50
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com> 0003 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef PTY_H 0009 #define PTY_H 0010 0011 // Qt 0012 #include <QProcess> 0013 #include <QSize> 0014 0015 // Konsole 0016 #include "konsoleprivate_export.h" 0017 0018 #ifndef Q_OS_WIN 0019 // KDE 0020 #include <KPtyProcess> 0021 #else 0022 #include <QObject> 0023 0024 #include "ptyqt/iptyprocess.h" 0025 #endif 0026 0027 namespace Konsole 0028 { 0029 /** 0030 * The Pty class is used to start the terminal process, 0031 * send data to it, receive data from it and manipulate 0032 * various properties of the pseudo-teletype interface 0033 * used to communicate with the process. 0034 * 0035 * To use this class, construct an instance and connect 0036 * to the sendData slot and receivedData signal to 0037 * send data to or receive data from the process. 0038 * 0039 * To start the terminal process, call the start() method 0040 * with the program name and appropriate arguments. 0041 */ 0042 #ifdef Q_OS_WIN 0043 #define ParentClass QObject 0044 #else 0045 #define ParentClass KPtyProcess 0046 #endif 0047 0048 class KONSOLEPRIVATE_EXPORT Pty : public ParentClass 0049 { 0050 Q_OBJECT 0051 0052 public: 0053 /** 0054 * Constructs a new Pty. 0055 * 0056 * Connect to the sendData() slot and receivedData() signal to prepare 0057 * for sending and receiving data from the terminal process. 0058 * 0059 * To start the terminal process, call the run() method with the 0060 * name of the program to start and appropriate arguments. 0061 */ 0062 explicit Pty(QObject *parent = nullptr); 0063 0064 /** 0065 * Construct a process using an open pty master. 0066 * See KPtyProcess::KPtyProcess() 0067 */ 0068 explicit Pty(int ptyMasterFd, QObject *parent = nullptr); 0069 0070 ~Pty() override; 0071 0072 #ifndef Q_OS_WIN 0073 /** 0074 * Starts the terminal process. 0075 * 0076 * Returns 0 if the process was started successfully or non-zero 0077 * otherwise. 0078 * 0079 * @param program Path to the program to start 0080 * @param arguments Arguments to pass to the program being started 0081 * @param environment A list of key=value pairs which will be added 0082 * to the environment for the new process. At the very least this 0083 * should include an assignment for the TERM environment variable. 0084 */ 0085 int start(const QString &program, const QStringList &arguments, const QStringList &environment); 0086 #else 0087 /** 0088 * Starts the terminal process. 0089 * 0090 * Returns 0 if the process was started successfully or non-zero 0091 * otherwise. 0092 * 0093 * @param program Path to the program to start 0094 * @param arguments Arguments to pass to the program being started 0095 * @param workingDir initial working directory 0096 * @param environment A list of key=value pairs which will be added 0097 * to the environment for the new process. At the very least this 0098 * should include an assignment for the TERM environment variable. 0099 */ 0100 int start(const QString &program, const QStringList &arguments, const QString &workingDir, const QStringList &environment, int cols, int lines); 0101 #endif 0102 0103 /** Control whether the pty device is writeable by group members. */ 0104 void setWriteable(bool writeable); 0105 0106 /** 0107 * Enables or disables Xon/Xoff flow control. The flow control setting 0108 * may be changed later by a terminal application, so flowControlEnabled() 0109 * may not equal the value of @p on in the previous call to setFlowControlEnabled() 0110 */ 0111 void setFlowControlEnabled(bool on); 0112 0113 /** Queries the terminal state and returns true if Xon/Xoff flow control is enabled. */ 0114 bool flowControlEnabled() const; 0115 0116 /** 0117 * Sets the size of the window (in columns and lines of characters, 0118 * and width and height in pixels) used by this teletype. 0119 */ 0120 void setWindowSize(int columns, int lines, int width, int height); 0121 0122 /** Returns the size of the window used by this teletype in characters. See setWindowSize() */ 0123 QSize windowSize() const; 0124 0125 /** Returns the size of the window used by this teletype in pixels. See setWindowSize() */ 0126 QSize pixelSize() const; 0127 0128 /** 0129 * Sets the special character for erasing previous not-yet-erased character. 0130 * See termios(3) for detailed description. 0131 */ 0132 void setEraseChar(char eraseChar); 0133 0134 /** */ 0135 char eraseChar() const; 0136 0137 /** 0138 * Sets the initial working directory. 0139 */ 0140 void setInitialWorkingDirectory(const QString &dir); 0141 0142 /** 0143 * Returns the process id of the teletype's current foreground 0144 * process. This is the process which is currently reading 0145 * input sent to the terminal via. sendData() 0146 * 0147 * If there is a problem reading the foreground process group, 0148 * 0 will be returned. 0149 */ 0150 int foregroundProcessGroup() const; 0151 0152 /** 0153 * Close the underlying pty master/slave pair. 0154 */ 0155 void closePty(); 0156 0157 #ifdef Q_OS_WIN 0158 int processId() const 0159 { 0160 if (m_proc && m_proc->isAvailable()) { 0161 return m_proc->pid(); 0162 } 0163 return 0; 0164 } 0165 0166 bool isRunning() const 0167 { 0168 return processId() > 0; 0169 } 0170 0171 QString errorString() const 0172 { 0173 if (m_proc) { 0174 return m_proc->lastError(); 0175 } 0176 return QStringLiteral("Conhost failed to start"); 0177 } 0178 0179 bool kill() 0180 { 0181 if (m_proc) { 0182 return m_proc->kill(); 0183 } 0184 return false; 0185 } 0186 0187 int exitCode() const 0188 { 0189 if (m_proc) { 0190 return m_proc->exitCode(); 0191 } 0192 return -1; 0193 } 0194 0195 Q_SIGNAL void finished(int exitCode, QProcess::ExitStatus); 0196 #endif 0197 0198 public Q_SLOTS: 0199 /** 0200 * Put the pty into UTF-8 mode on systems which support it. 0201 */ 0202 void setUtf8Mode(bool on); 0203 0204 /** 0205 * Sends data to the process currently controlling the 0206 * teletype ( whose id is returned by foregroundProcessGroup() ) 0207 * 0208 * @param data the data to send. 0209 */ 0210 void sendData(const QByteArray &data); 0211 0212 Q_SIGNALS: 0213 /** 0214 * Emitted when a new block of data is received from 0215 * the teletype. 0216 * 0217 * @param buffer Pointer to the data received. 0218 * @param length Length of @p buffer 0219 */ 0220 void receivedData(const char *buffer, int length); 0221 0222 private Q_SLOTS: 0223 // called when data is received from the terminal process 0224 void dataReceived(); 0225 0226 private: 0227 void init(); 0228 0229 // takes a list of key=value pairs and adds them 0230 // to the environment for the process 0231 void addEnvironmentVariables(const QStringList &environment); 0232 0233 int _windowColumns; 0234 int _windowLines; 0235 int _windowWidth; 0236 int _windowHeight; 0237 char _eraseChar; 0238 bool _xonXoff; 0239 bool _utf8; 0240 #ifdef Q_OS_WIN 0241 std::unique_ptr<IPtyProcess> m_proc; 0242 #endif 0243 }; 0244 } 0245 0246 #undef ParentClass 0247 0248 #endif // PTY_H