Compare commits

...
4 Commits
3 changed files with 491 additions and 26 deletions

No files matched your search

+80 -26
View File
@@ -58,7 +58,8 @@ DigeWhite Theme:
- Supports direct/local port forwarding, reverse/remote port forwarding and dynamic port forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/port_forwarding/) - Supports direct/local port forwarding, reverse/remote port forwarding and dynamic port forwarding. [Intro Video](https://kingtoolbox.github.io/2020/07/21/port_forwarding/)
- Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on. [Intro Video](https://kingtoolbox.github.io/tags/transfer/) - Integrated sftp, scp client, supports download, upload, remove, rename, make new file/directory and so on. [Intro Video](https://kingtoolbox.github.io/tags/transfer/)
- Integrated local file manager, supports move to, copy to, copy from, remove, rename, make new file/directory and so on. - Integrated local file manager, supports move to, copy to, copy from, remove, rename, make new file/directory and so on.
- Supports Cmd, PowerShell and Cmd, PowerShell as administrator. - Supports Windows Cmd, PowerShell and Cmd, PowerShell as administrator.
- Supports Linux bash, zsh, powershell core and so on.
### GUI ### GUI
- Session dialog and session tree. - Session dialog and session tree.
- **Command palette.** [Intro Video](https://kingtoolbox.github.io/tags/command-palette/) - **Command palette.** [Intro Video](https://kingtoolbox.github.io/tags/command-palette/)
@@ -77,6 +78,7 @@ DigeWhite Theme:
- Supports setting the windows transparency. [Intro video](https://kingtoolbox.github.io/2020/11/13/windows-opacity/) - Supports setting the windows transparency. [Intro video](https://kingtoolbox.github.io/2020/11/13/windows-opacity/)
- Supports select-to-copy and middle-click-to-paste. - Supports select-to-copy and middle-click-to-paste.
- Supports searching text online with Google, Bing, Github, Stackoverflow, Wikipedia and DuckDuckGo. [Intro video](https://kingtoolbox.github.io/2020/11/13/search-online/) - Supports searching text online with Google, Bing, Github, Stackoverflow, Wikipedia and DuckDuckGo. [Intro video](https://kingtoolbox.github.io/2020/11/13/search-online/)
- Supports hiding mouse cursor while typing.
### Term ### Term
- Supports vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors. - Supports vt100, vt220, vt340, vt420, vt520, xterm, xterm-256-colors.
- Supports unicode, emojis, true-color, mouse protocol, etc. - Supports unicode, emojis, true-color, mouse protocol, etc.
@@ -110,7 +112,7 @@ The version of clients:
**All test data is for reference only.** **All test data is for reference only.**
- 5GB huge file (5,154,830 KB), generated by random data ### 5GB huge file (5,154,830 KB), generated by random data
| | Download Time | Download Rate | Upload Time | Upload Rate | | | Download Time | Download Rate | Upload Time | Upload Rate |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
@@ -120,7 +122,7 @@ The version of clients:
| FileZilla | 32s | 161.1 MB/s | 30s | 171.8 MB/s | | FileZilla | 32s | 161.1 MB/s | 30s | 171.8 MB/s |
| WinSCP | 81s | 63.7 MB/s | 91s | 56.7 MB/s | | WinSCP | 81s | 63.7 MB/s | 91s | 56.7 MB/s |
- 4400 files, 16 folders (107,042 KB), unzipped from [vim-7.4.1049.zip](https://github.com/vim/vim/archive/v7.4.1049.zip) ### 4400 files, 16 folders (107,042 KB), unzipped from [vim-7.4.1049.zip](https://github.com/vim/vim/archive/v7.4.1049.zip)
| | Download Time | Download Rate | Upload Time | Upload Rate | | | Download Time | Download Rate | Upload Time | Upload Rate |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
@@ -161,7 +163,9 @@ The version of terminals:
**All test data is for reference only.** **All test data is for reference only.**
- 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh)) ## Test Command: "cat ./benchmark_randomdata"
The benchmark_randomdata contains 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh))
In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs. In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs.
@@ -193,9 +197,9 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| kitty | unlimited | 17.2 | 2655 | | kitty | unlimited | 17.2 | 2655 |
| Alacritty | 100,000 | 41.3 | - | | Alacritty | 100,000 | 41.3 | - |
- time seq 1 n ## Test command: "time seq 1 n" (n = [1000000, 2000000, 5000000, 10000000], scrollback lines: unlimited)
1. n = 1,000,000, scrollback = 1,000,000 Lines ### n = 1,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -208,7 +212,7 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | **1.162** | Not measured, use 100,000 scrollback lines setting | | Alacritty | **1.162** | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 23.246 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 23.246 | Not measured, use 65,535 scrollback lines setting |
2. n = 2,000,000, scrollback = 2,000,000 Lines ### n = 2,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -221,33 +225,33 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | 2.322 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 2.322 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 50.381 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 50.381 | Not measured, use 65,535 scrollback lines setting |
3. n = 5,000,000 scrollback = 5,000,000 Lines ### n = 5,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
| WindTerm | **5.520** | **68.2** | | WindTerm | **5.520** | **68.2** |
| rxvt | 27.533 | 3166.2 | | rxvt | 27.533 | 3166.2 |
| putty | 45.911 | 2757.1 | | putty | 45.911 | 2757.1 |
| xterm | - | Out of memmory | | xterm | - | Out of memory |
| iterm2 | 10.805 | 1048.3 | | iterm2 | 10.805 | 1048.3 |
| Kitty | - | Out of memory | | Kitty | - | Out of memory |
| Alacritty | 5.799 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 5.799 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 130.371 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 130.371 | Not measured, use 65,535 scrollback lines setting |
4. n = 10,000,000 scrollback = 10,000,000 Lines ### n = 10,000,000
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
| WindTerm | **10.674** | **133.3** | | WindTerm | **10.674** | **133.3** |
| rxvt | - | Out of memory | | rxvt | - | Out of memory |
| putty | - | Out of memory | | putty | - | Out of memory |
| xterm | - | Out of memmory | | xterm | - | Out of memory |
| iterm2 | 20.468 | 2231.3 | | iterm2 | 20.468 | 2231.3 |
| Kitty | - | Out of memory | | Kitty | - | Out of memory |
| Alacritty | 11.598 | Not measured, use 100,000 scrollback lines setting | | Alacritty | 11.598 | Not measured, use 100,000 scrollback lines setting |
| Windows Terminal + ssh.exe | 264.739 | Not measured, use 65,535 scrollback lines setting | | Windows Terminal + ssh.exe | 264.739 | Not measured, use 65,535 scrollback lines setting |
5. n = 10,000,000 scrollback = 30 Lines ### n = 10,000,000 scrollback = 30 Lines
| | Time(sec) | Memory Usage(MB) | | | Time(sec) | Memory Usage(MB) |
| --- | --- | --- | | --- | --- | --- |
@@ -260,6 +264,55 @@ In all cases, three runs were made to warm system caches. The reported numbers a
| Alacritty | 11.798 | Not measured, use zero scrollback lines setting | | Alacritty | 11.798 | Not measured, use zero scrollback lines setting |
| Windows Terminal + ssh.exe | 261.096 | Not measured, use zero scrollback lines setting | | Windows Terminal + ssh.exe | 261.096 | Not measured, use zero scrollback lines setting |
# Linux Terminal Performance
The hardware used for generating the data in these benchmarks was
Debian 10 Vm - 4cpu and 4GB memory.
For WindTerm: No color scheme used in windterm. Color scheme will result in approximately 2% loss and more memory usage.
For other terminals: No memory usage measured because most of them write the history to disk or only support a limited number of lines in memory..
The version of terminals:
| Application | Version | Release Date |
| --- | --- | --- |
| Windterm | v1.9 | 2020-12-22 |
| Gnome | v3.30.2 | 2018-10-22 |
| Mate Terminal | v1.20.2 | 2019-02-11 |
| Konsole | v18.04.0 | 2019-04-12 |
| Xfce4 Terminal | v0.8.7.4 | 2018-5-15 |
| QTerminal | v0.14.1 | 2019-01-26 |
**All test data is for reference only.**
## Test Command: "cat ./benchmark_randomdata"
The benchmark_randomdata contains 97.6MB random text (102,401,504 bytes, 1,329,878 lines, generated and tested by [random_test.sh](https://github.com/kingToolbox/WindTerm/blob/master/benchmark/urandom_test.sh))
In all cases, three runs were made to warm system caches. The reported numbers are the median of five runs.
| | Cost Time |
| --- | --- |
| WindTerm | **1.976s** |
| Gnome Terminal | 9.781s |
| Mate Terminal | 9.841s |
| Konsole | 25.050s |
| xfce4 Terminal | 10.520s |
| QTerminal | 20.763s |
## Test command: "time seq 1 n" (n = [1000000, 2000000, 5000000, 10000000], scrollback lines: unlimited)
| n | 1,000,000 | 2,000,000 | 5,000,000 | 10,000,000 | 10,000,000<br>(scrollback lines: 100) |
| --- | --- | --- | --- | --- | --- |
| WindTerm | 0.846s (18.6MB) | **1.574s** (26.6MB) | **4.046s** (56.4MB) | **8.232s** (102.2MB) | **7.748s** (3.4MB) |
| Gnome Terminal | 0.920s | 2.152s | 5.271s | 11.111s | 13.109s |
| Mate Terminal | **0.822s** | 1.698s | 5.943s | 10.920s | 12.290s |
| Konsole | 1.612s | 3.199s | 8.157s | 16.029s | 15.650s |
| xfce4 Terminal | 0.870s | 2.160s | 5.866s | 12.089s | 13.304s |
| QTerminal | 9.272s | 18.391s | 45.999s | 104.277s | 17.208s |
# Latency # Latency
Considering the network influence on the latency, the following data is from [WindEdit](https://github.com/kingToolbox/digedit). Considering the network influence on the latency, the following data is from [WindEdit](https://github.com/kingToolbox/digedit).
@@ -275,7 +328,6 @@ DIGEdit is the text component of WindTerm.
| Shortcut | Action | | Shortcut | Action |
| --- | --- | | --- | --- |
| Alt+C | Copy |
| Alt+D | Show command palette | | Alt+D | Show command palette |
| Alt+F | Find | | Alt+F | Find |
| Alt+F3 | Find next | | Alt+F3 | Find next |
@@ -290,13 +342,11 @@ DIGEdit is the text component of WindTerm.
| Alt+T, Alt+F | Toggle margin fold | | Alt+T, Alt+F | Toggle margin fold |
| Alt+T, Alt+N | Toggle margin number | | Alt+T, Alt+N | Toggle margin number |
| Alt+T, Alt+S | Toggle margin symbol | | Alt+T, Alt+S | Toggle margin symbol |
| Alt+V | Paste |
| Alt+W, Alt+D | Close active dock | | Alt+W, Alt+D | Close active dock |
| Alt+W, Alt+G | Close active group | | Alt+W, Alt+G | Close active group |
| Alt+W, Alt+H | Split horizontally | | Alt+W, Alt+H | Split horizontally |
| Alt+W, Alt+L | Show outline pane | | Alt+W, Alt+L | Show outline pane |
| Alt+W, Alt+V | Split vertically | | Alt+W, Alt+V | Split vertically |
| Alt+X | Copy and paste |
| Alt+- | Zoom in | | Alt+- | Zoom in |
| Alt++ | Zoom out | | Alt++ | Zoom out |
| Alt+\[ | Activate next view | | Alt+\[ | Activate next view |
@@ -307,6 +357,9 @@ DIGEdit is the text component of WindTerm.
| Ctrl+Shift+T | Reopen closed session | | Ctrl+Shift+T | Reopen closed session |
| Ctrl+Shift+W | Close current session | | Ctrl+Shift+W | Close current session |
| Ctrl+Shift+- | Select current fold text | | Ctrl+Shift+- | Select current fold text |
| Ctrl+Shift+C | Copy |
| Ctrl+Shift+V | Paste |
| Ctrl+Shift+X | Copy and paste |
| Shift+Del | Copy | | Shift+Del | Copy |
| Shift+End | Jump to document end | | Shift+End | Jump to document end |
| Shift+Home | Jump to document home | | Shift+Home | Jump to document home |
@@ -320,20 +373,21 @@ DIGEdit is the text component of WindTerm.
2-4 weeks. 2-4 weeks.
**Next release (Late November,for reference only):** **Next release (Mid January,for reference only):**
- **Linux Version** - Mosh
- **Linux Shells** - Git Bash
- Xmodem, Ymodem, Zmodem(sz, rz) - SSH
- x11 (Linux Version)
- ProxyCommand
- Shell Pane
- External tools - External tools
**Todo list:**
- Protocols:
- Rlogin
- Mosh
- SSH
- ProxyCommand
- UI: - UI:
- Config dialog - Config dialog
**Todo list:**
- Xmodem, Ymodem, Zmodem(sz, rz)
- Protocols:
- Rlogin
- Terminal: - Terminal:
- MacOs bash - MacOs bash
- Session: - Session:
+328
View File
@@ -0,0 +1,328 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "UnixPty.h"
#ifdef Q_OS_UNIX
#include <QFileInfo>
#include <QThread>
#include <errno.h>
#include <utmpx.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
constexpr int BUFFER_SIZE = 0x800; // 2048 bytes
ShellProcess::ShellProcess()
: QProcess()
, m_handleMaster(-1)
, m_handleSlave(-1)
{
setProcessChannelMode(QProcess::MergedChannels);
}
void ShellProcess::setupChildProcess() {
dup2(m_handleSlave, STDIN_FILENO);
dup2(m_handleSlave, STDOUT_FILENO);
dup2(m_handleSlave, STDERR_FILENO);
pid_t sid = setsid();
ioctl(m_handleSlave, TIOCSCTTY, 0);
tcsetpgrp(m_handleSlave, sid);
struct utmpx utmpxInfo;
memset(&utmpxInfo, 0, sizeof(utmpxInfo));
strncpy(utmpxInfo.ut_user, qgetenv("USER"), sizeof(utmpxInfo.ut_user));
QString device(m_handleSlaveName);
if (device.startsWith("/dev/")) {
device = device.mid(5);
}
const char *d = device.toLatin1().constData();
strncpy(utmpxInfo.ut_line, d, sizeof(utmpxInfo.ut_line));
strncpy(utmpxInfo.ut_id, d + strlen(d) - sizeof(utmpxInfo.ut_id), sizeof(utmpxInfo.ut_id));
struct timeval tv;
gettimeofday(&tv, 0);
utmpxInfo.ut_tv.tv_sec = tv.tv_sec;
utmpxInfo.ut_tv.tv_usec = tv.tv_usec;
utmpxInfo.ut_type = USER_PROCESS;
utmpxInfo.ut_pid = getpid();
utmpxname(_PATH_UTMPX);
setutxent();
pututxline(&utmpxInfo);
endutxent();
#if !defined(Q_OS_UNIX)
updwtmpx(_PATH_UTMPX, &loginInfo);
#endif
}
UnixPty::UnixPty(QObject *parent /*= nullptr*/)
: Pty(parent)
, m_pid(0)
, m_readMasterNotify(nullptr)
{
m_buffer = static_cast<char *>(malloc(BUFFER_SIZE));
}
UnixPty::~UnixPty() {
stop();
free(m_buffer);
m_buffer = nullptr;
}
bool UnixPty::createProcess(QString command, const QString &arguments,
const QString &workingDirectory, const QProcessEnvironment &environment,
int rows, int columns) {
if (m_shellProcess.state() == QProcess::Running) {
return false;
}
QFileInfo fileInfo(command);
if (fileInfo.isRelative() || fileInfo.exists() == false) {
setErrorString(tr("UnixPty: shell file path must be absolute"));
return false;
}
bool success = false;
do {
int result = 0;
m_shellProcess.m_handleMaster = ::posix_openpt(O_RDWR | O_NOCTTY);
if (m_shellProcess.m_handleMaster < 0) {
setError("Unable to open master");
break;
}
m_shellProcess.m_handleSlaveName = ptsname(m_shellProcess.m_handleMaster);
if (m_shellProcess.m_handleSlaveName.isEmpty()) {
setError("Unable to get slave name");
break;
}
result = grantpt(m_shellProcess.m_handleMaster);
if (result != 0) {
setError("Unable to change perms for slave");
break;
}
result = unlockpt(m_shellProcess.m_handleMaster);
if (result != 0) {
setError("Unable to unlock slave");
break;
}
m_shellProcess.m_handleSlave = ::open(m_shellProcess.m_handleSlaveName.toLatin1().data(), O_RDWR | O_NOCTTY);
if (m_shellProcess.m_handleSlave < 0) {
setError("Unable to open slave");
break;
}
int flags = fcntl(m_shellProcess.m_handleMaster, F_GETFL, 0);
result = fcntl(m_shellProcess.m_handleMaster, F_SETFL, flags | O_NONBLOCK);
if (result == -1) {
setError("Unable to set non-blocking mode for master");
break;
}
result = fcntl(m_shellProcess.m_handleMaster, F_SETFD, FD_CLOEXEC);
if (result == -1) {
setError("Unable to set flags for master");
break;
}
result = fcntl(m_shellProcess.m_handleSlave, F_SETFD, FD_CLOEXEC);
if (result == -1) {
setError("Unable to set flags for slave");
break;
}
struct ::termios ttmode;
if (terminalAttributes(&ttmode) == false) {
break;
}
ttmode.c_iflag |= IXON;
ttmode.c_iflag |= IUTF8;
ttmode.c_lflag |= ECHO;
#ifdef Q_OS_MACOS
ttmode.c_cc[VDSUSP] = 25;
ttmode.c_cc[VSTATUS] = 20;
#endif
if (setTerminalAttributes(&ttmode) == false) {
break;
}
m_readMasterNotify = new QSocketNotifier(m_shellProcess.m_handleMaster, QSocketNotifier::Read, &m_shellProcess);
m_readMasterNotify->setEnabled(true);
m_readMasterNotify->moveToThread(m_shellProcess.thread());
QObject::connect(m_readMasterNotify, &QSocketNotifier::activated, [this](int socket) {
Q_UNUSED(socket)
int readSize = 0;
QByteArray readData;
do {
readSize = ::read(m_shellProcess.m_handleMaster, m_buffer, BUFFER_SIZE);
if (readSize == -1) {
if (errno == EAGAIN) {
QThread::yieldCurrentThread();
continue;
} else {
break;
}
}
readData.append(QByteArray::fromRawData(m_buffer, readSize));
} while (readSize == BUFFER_SIZE || (readSize == -1 && errno == EAGAIN)); //last data block always < readSize
if (readData.isEmpty() == false) {
m_shellReadBuffer.append(readData);
emit readyRead();
}
});
m_shellProcess.setWorkingDirectory(workingDirectory);
m_shellProcess.setProcessEnvironment(environment);
m_shellProcess.setReadChannel(QProcess::StandardOutput);
m_shellProcess.start(command, arguments.isEmpty() ? QStringList() : QStringList(arguments));
m_shellProcess.waitForStarted();
m_pid = m_shellProcess.processId();
success = resizeWindow(rows, columns);
} while(0);
if (success == false) {
stop();
}
Q_ASSERT(success == true);
return success;
}
bool UnixPty::resizeWindow(int rows, int columns) {
if (rows != m_rows || columns != m_columns) {
bool success = false;
struct winsize winSize;
memset(&winSize, 0, sizeof(winSize));
winSize.ws_row = static_cast<quint16>(rows);
winSize.ws_col = static_cast<quint16>(columns);
if (ioctl(m_shellProcess.m_handleMaster, TIOCSWINSZ, &winSize) == 0
&& ioctl(m_shellProcess.m_handleSlave, TIOCSWINSZ, &winSize) == 0) {
m_rows = rows;
m_columns = columns;
success = true;
}
return success;
}
return true;
}
void UnixPty::setError(const char *error) {
Pty::setErrorString(QString("%1: %2 -> %3").arg(tr("UnixPty"), tr(error), strerror(errno)));
}
bool UnixPty::setTerminalAttributes(struct ::termios *ttmode) {
Q_ASSERT(m_shellProcess.m_handleMaster >= 0);
int result = -1;
if (m_shellProcess.m_handleMaster >=0) {
result = tcsetattr(m_shellProcess.m_handleMaster, TCSANOW, ttmode);
if (result != 0) {
setError("Unable to set terminal attributes");
}
}
return (result == 0);
}
void UnixPty::stop() {
m_shellProcess.m_handleSlaveName = QString();
if (m_shellProcess.m_handleSlave >= 0) {
::close(m_shellProcess.m_handleSlave);
m_shellProcess.m_handleSlave = -1;
}
if (m_shellProcess.m_handleMaster >= 0) {
::close(m_shellProcess.m_handleMaster);
m_shellProcess.m_handleMaster = -1;
}
if (m_shellProcess.state() == QProcess::Running) {
m_readMasterNotify->disconnect();
m_readMasterNotify->deleteLater();
m_shellProcess.terminate();
m_shellProcess.waitForFinished(1000);
if (m_shellProcess.state() == QProcess::Running) {
QProcess::startDetached(QString("kill -9 %1").arg(m_pid));
m_shellProcess.kill();
m_shellProcess.waitForFinished(1000);
}
Q_ASSERT(m_shellProcess.state() == QProcess::NotRunning);
}
}
bool UnixPty::terminalAttributes(struct ::termios *ttmode) {
Q_ASSERT(m_shellProcess.m_handleMaster >= 0);
int result = -1;
if (m_shellProcess.m_handleMaster >= 0) {
result = tcgetattr(m_shellProcess.m_handleMaster, ttmode);
if (result != 0) {
setError("Unable to get terminal attributes");
}
}
return (result == 0);
}
QByteArray UnixPty::readAll() {
QByteArray shellReadBuffer = m_shellReadBuffer;
m_shellReadBuffer.clear();
return shellReadBuffer;
}
qint64 UnixPty::write(const QByteArray &text) {
int writeSize = ::write(m_shellProcess.m_handleMaster, text.constData(), text.size());
Q_ASSERT(writeSize == text.size());
if (writeSize == -1) {
setError("Unable to write output");
}
return writeSize;
}
bool UnixPty::isAvailable() {
return true;
}
void UnixPty::moveToThread(QThread *targetThread) {
m_shellProcess.moveToThread(targetThread);
}
#endif // Q_OS_UNIX
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2020, WindTerm.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UNIXPTY_H
#define UNIXPTY_H
#pragma once
#include <QtGlobal>
#ifdef Q_OS_UNIX
#include "Pty.h"
#include <QProcess>
#include <QSocketNotifier>
#include <termios.h>
class ShellProcess
: public QProcess
{
Q_OBJECT
public:
ShellProcess();
private:
void setupChildProcess() final;
private:
int m_handleMaster;
int m_handleSlave;
QString m_handleSlaveName;
private:
friend class UnixPty;
};
class UnixPty
: public Pty
{
public:
UnixPty(QObject *parent = nullptr);
virtual ~UnixPty();
bool createProcess(QString command, const QString &arguments,
const QString &workingDirectory, const QProcessEnvironment &environment,
int rows, int columns) final;
static bool isAvailable();
bool resizeWindow(int rows, int columns) final;
QByteArray readAll() final;
qint64 write(const QByteArray &text) final;
private:
void moveToThread(QThread *targetThread);
void setError(const char *error);
bool setTerminalAttributes(struct ::termios *ttmode);
void stop();
bool terminalAttributes(struct ::termios *ttmode);
private:
qint64 m_pid;
ShellProcess m_shellProcess;
QSocketNotifier *m_readMasterNotify;
char *m_buffer;
QByteArray m_shellReadBuffer;
};
#endif // Q_OS_UNIX
#endif // UNIXPTY_H