Skip to content

Commit 4717a2c

Browse files
committed
Separate PTY log history from regular logs
1 parent fe29482 commit 4717a2c

5 files changed

Lines changed: 114 additions & 58 deletions

File tree

src/ApplicationGlobal.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,13 @@ void ApplicationGlobal::init2()
160160
void ApplicationGlobal::writeLog(const std::string_view &str)
161161
{
162162
if (!mainwindow) return;
163-
mainwindow->emitWriteLog(str);
163+
mainwindow->emitWriteLog(str, false);
164164
}
165165

166166
void ApplicationGlobal::writeLog(const QString &str)
167167
{
168168
if (!mainwindow) return;
169-
mainwindow->emitWriteLog(str);
169+
mainwindow->emitWriteLog(str, false);
170170
}
171171

172172
std::shared_ptr<AbstractInetClient> ApplicationGlobal::inet_client()

src/GitHubAPI.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ void GitHubRequestThread::run()
6161
} else {
6262
std::string msg = web()->error().what();
6363
if (!msg.empty()) {
64-
global->mainwindow->emitWriteLog(QString("Failed to access the site: %1\n").arg(QString::fromStdString(url)));
65-
global->mainwindow->emitWriteLog(QString("%1\n").arg(QString::fromStdString(msg)));
64+
global->mainwindow->emitWriteLog(QString("Failed to access the site: %1\n").arg(QString::fromStdString(url)), false);
65+
global->mainwindow->emitWriteLog(QString("%1\n").arg(QString::fromStdString(msg)), false);
6666
}
6767
}
6868
}

src/MainWindow.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ struct MainWindow::Private {
190190
QList<int> splitter_h_sizes;
191191

192192
std::vector<char> log_history_bytes;
193+
std::vector<char> log_history_bytes_pty;
193194

194195
QAction *action_edit_profile = nullptr;
195196
QAction *action_detect_profile = nullptr;
@@ -486,13 +487,13 @@ void MainWindow::startTimers()
486487
/**
487488
* @brief PTYプロセスの出力をログに書き込む
488489
*/
489-
void MainWindow::updatePocessLog(bool processevents)
490+
void MainWindow::updatePtyPocessLog(bool processevents)
490491
{
491492
while (1) {
492493
char tmp[1024];
493494
int len = getPtyProcess()->readOutput(tmp, sizeof(tmp));
494495
if (len < 1) break;
495-
emitWriteLog({tmp, len});
496+
emitWriteLog({tmp, len}, true);
496497
if (processevents) {
497498
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
498499
}
@@ -539,7 +540,7 @@ void MainWindow::onInterval10ms()
539540
}
540541

541542
// PTYプロセスの出力をログに書き込む
542-
updatePocessLog(true);
543+
updatePtyPocessLog(true);
543544
}
544545
}
545546

@@ -822,17 +823,20 @@ void MainWindow::onLogVisibilityChanged()
822823
ui->action_window_log->setChecked(ui->dockWidget_log->isVisible());
823824
}
824825

825-
void MainWindow::appendLogHistory(QByteArray const &str)
826+
void MainWindow::appendLogHistory(QByteArray const &str, bool pty)
826827
{
827-
m->log_history_bytes.insert(m->log_history_bytes.begin(), str.begin(), str.end());
828+
std::vector<char> *vec = pty ? &m->log_history_bytes_pty : &m->log_history_bytes;
829+
vec->insert(vec->end(), str.begin(), str.end());
828830
}
829831

830-
std::vector<std::string> MainWindow::getLogHistoryLines()
832+
std::vector<std::string> MainWindow::getLogHistoryLines(bool pty)
831833
{
834+
std::vector<char> *vec = pty ? &m->log_history_bytes_pty : &m->log_history_bytes;
835+
832836
std::vector<std::string> lines;
833-
if (m->log_history_bytes.empty()) return {};
834-
char const *begin = m->log_history_bytes.data();
835-
char const *end = begin + m->log_history_bytes.size();
837+
if (vec->empty()) return {};
838+
char const *begin = vec->data();
839+
char const *end = begin + vec->size();
836840
char const *top = begin;
837841
char const *ptr = begin;
838842
bool cr = false;
@@ -856,7 +860,7 @@ std::vector<std::string> MainWindow::getLogHistoryLines()
856860
ptr++;
857861
}
858862
}
859-
m->log_history_bytes.erase(m->log_history_bytes.begin(), m->log_history_bytes.begin() + (ptr - begin));
863+
vec->erase(vec->begin(), vec->begin() + (ptr - begin));
860864
return lines;
861865
}
862866

@@ -865,11 +869,11 @@ void MainWindow::clearLogHistory()
865869
m->log_history_bytes.clear();
866870
}
867871

868-
void MainWindow::internalWriteLog(LogData const &logdata)
872+
void MainWindow::internalWriteLog(LogData const &logdata, bool pty)
869873
{
870874
QByteArray ba = logdata.data;
871875

872-
appendLogHistory(ba);
876+
appendLogHistory(ba, pty);
873877

874878
if (ba.size() > 0) {
875879
int i = ba.size() - 1;
@@ -5596,9 +5600,9 @@ bool MainWindow::isValidWorkingCopy(QString const &local_dir)
55965600
return isValidWorkingCopy(g);
55975601
}
55985602

5599-
void MainWindow::emitWriteLog(const LogData &logdata)
5603+
void MainWindow::emitWriteLog(const LogData &logdata, bool pty)
56005604
{
5601-
emit sigWriteLog(logdata);
5605+
emit sigWriteLog(logdata, pty);
56025606
}
56035607

56045608
QString MainWindow::findFileID(GitHash const &commit_id, const QString &file)
@@ -6702,7 +6706,7 @@ void MainWindow::onLogIdle()
67026706
"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!");
67036707
}
67046708

6705-
std::vector<std::string> lines = getLogHistoryLines();
6709+
std::vector<std::string> lines = getLogHistoryLines(true);
67066710
clearLogHistory();
67076711

67086712
if (lines.empty()) return;

src/MainWindow.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,9 @@ class MainWindow : public QMainWindow {
385385
void msgNoRepositorySelected();
386386
bool isRepositoryOpened() const;
387387
void initRepository(QString const &path, QString const &reponame, const GitRemote &remote);
388-
void updatePocessLog(bool processevents);
389-
void appendLogHistory(const QByteArray &str);
390-
std::vector<std::string> getLogHistoryLines();
388+
void updatePtyPocessLog(bool processevents);
389+
void appendLogHistory(const QByteArray &str, bool pty);
390+
std::vector<std::string> getLogHistoryLines(bool pty);
391391
void clearLogHistory();
392392
void updateAvatar(const GitUser &user, bool request);
393393
void cleanSubModule(GitRunner g, QListWidgetItem *item);
@@ -567,7 +567,7 @@ private slots:
567567
void signalSetProgress(float progress);
568568
void signalShowStatusInfo(StatusInfo const &info);
569569
void signalHideProgress();
570-
void sigWriteLog(LogData const &logdata);
570+
void sigWriteLog(LogData const &logdata, bool pty);
571571
void sigShowFileList(FileListType files_list_type);
572572
void signalAddFileObjectData(const MainWindowExchangeData &data);
573573
void remoteInfoChanged();
@@ -661,7 +661,7 @@ private slots:
661661
bool jumpToCommit(QString const &id);
662662

663663
TextEditorThemePtr themeForTextEditor();
664-
void emitWriteLog(LogData const &logdata);
664+
void emitWriteLog(LogData const &logdata, bool pty);
665665
QString findFileID(const GitHash &commit_id, QString const &file);
666666
const GitCommitItem &commitItem(int row) const;
667667
const GitCommitItem &commitItem(GitHash const &id) const;
@@ -703,7 +703,7 @@ private slots:
703703
static void openExplorer(QString const &dir, QString const &ssh_key);
704704
static void openNewGuitar(QString const &path, QString const &commit_id);
705705
public slots:
706-
void internalWriteLog(const LogData &logdata);
706+
void internalWriteLog(const LogData &logdata, bool pty);
707707
};
708708

709709
class MainWindowExchangeData {

src/ProcessExample.cpp

Lines changed: 85 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <QElapsedTimer>
1212

1313
#ifdef _WIN32
14+
#include <QApplication>
1415
#include <windows.h>
1516
#include <winpty.h>
1617
#else
@@ -479,6 +480,7 @@ class ProcessWin : public AbstractProcess {
479480
std::vector<char> output_vector_; // for result
480481
void writeOutput(char const *buf, size_t len)
481482
{
483+
std::lock_guard<std::mutex> lock(mutex_);
482484
output_queue_.insert(output_queue_.end(), buf, buf + len);
483485
output_vector_.insert(output_vector_.end(), buf, buf + len);
484486
}
@@ -589,6 +591,7 @@ class ProcessWinPty : public AbstractPtyProcess {
589591
std::mutex mutex_;
590592
std::condition_variable cond_;
591593
int input_fd_ = -1;
594+
HANDLE hConout_ = INVALID_HANDLE_VALUE;
592595
HANDLE hInput_ = INVALID_HANDLE_VALUE;
593596
int exit_code_ = 128;
594597

@@ -626,7 +629,7 @@ class ProcessWinPty : public AbstractPtyProcess {
626629
return ret;
627630
}
628631

629-
HANDLE hConout = CreateFileW(
632+
hConout_ = CreateFileW(
630633
winpty_conout_name(wp),
631634
GENERIC_READ, 0, nullptr,
632635
OPEN_EXISTING, 0, nullptr
@@ -652,14 +655,14 @@ class ProcessWinPty : public AbstractPtyProcess {
652655

653656

654657

655-
if (hConout != INVALID_HANDLE_VALUE) {
658+
if (hConout_ != INVALID_HANDLE_VALUE) {
656659
char buf[256];
657660
DWORD n;
658-
while (ReadFile(hConout, buf, sizeof(buf), &n, nullptr) && n > 0) {
659-
// ret.append(buf, n);
661+
while (ReadFile(hConout_, buf, sizeof(buf), &n, nullptr) && n > 0) {
662+
std::lock_guard<std::mutex> lock(mutex_);
660663
writeOutput(buf, n);
661664
}
662-
CloseHandle(hConout);
665+
CloseHandle(hConout_);
663666
}
664667

665668
WaitForSingleObject(hProcess, INFINITE);
@@ -679,12 +682,46 @@ class ProcessWinPty : public AbstractPtyProcess {
679682
void writeInput(const char *ptr, int len)
680683
{
681684
if (hInput_ != INVALID_HANDLE_VALUE) {
682-
DWORD n;
683-
WriteFile(hInput_, ptr, (DWORD)len, &n, nullptr);
685+
char const *begin = ptr;
686+
char const *end = begin + len;
687+
char const *left = begin;
688+
char const *right = begin;
689+
while (1) {
690+
int c = -1;
691+
if (right < end) {
692+
c = *right & 0xff;
693+
}
694+
if (c == '\r' || c == '\n' || c < 0) {
695+
if (left < right) {
696+
DWORD written;
697+
WriteFile(hInput_, left, right - left, &written, nullptr);
698+
}
699+
if (c < 0) break;
700+
right++;
701+
if (c == '\r') {
702+
if (*right == '\n') {
703+
right++;
704+
}
705+
c = '\r';
706+
} else if (c == '\n') {
707+
c = '\r';
708+
} else {
709+
c = -1;
710+
}
711+
if (c >= 0) {
712+
DWORD written;
713+
WriteFile(hInput_, &c, 1, &written, nullptr);
714+
}
715+
left = right;
716+
} else {
717+
right++;
718+
}
719+
}
684720
}
685721
}
686722
int readOutput(char *ptr, int len)
687723
{
724+
std::lock_guard<std::mutex> lock(mutex_);
688725
int n = output_queue_.size();
689726
if (n > len) n = len;
690727
for (int i = 0; i < n; i++) {
@@ -710,6 +747,10 @@ class ProcessWinPty : public AbstractPtyProcess {
710747
}
711748
void stop()
712749
{
750+
if (hConout_ != INVALID_HANDLE_VALUE) {
751+
CloseHandle(hConout_);
752+
hConout_ = INVALID_HANDLE_VALUE;
753+
}
713754
wait();
714755
}
715756
int getExitCode() const
@@ -967,37 +1008,48 @@ void msleep(unsigned int ms)
9671008
#endif
9681009
}
9691010

1011+
#include "ApplicationGlobal.h"
1012+
#include "MainWindow.h"
1013+
#include <QDir>
1014+
9701015
void process_test()
9711016
{
9721017
#if 0
973-
ProcessWinConPTY proc;
974-
proc.start("git --version", "");
975-
proc.wait();
976-
std::vector<char> out;
977-
proc.readResult(&out);
978-
std::string s(out.begin(), out.end());
979-
fprintf(stderr, "[%s]\n", s.c_str());
980-
#elif 0
981-
ProcessWinConPTY proc;
982-
proc.start("sort", "");
983-
{
984-
// Windowsのsortコマンドは\r\n(CRLF)を行区切りとして期待する
985-
const char *input = "abc\r\ndef\r\n";
986-
proc.writeInput(input, strlen(input));
1018+
ProcessWinPty proc;
1019+
proc.start("git fetch", "");
1020+
1021+
std::string text;
1022+
while (proc.isRunning()) {
1023+
char tmp[1024];
1024+
int n = proc.readOutput(tmp, sizeof(tmp));
1025+
if (n > 0) {
1026+
std::string s(tmp, n);
1027+
fprintf(stderr, "%s", s.c_str());
1028+
text += s;
1029+
} else {
1030+
if (text.find("Are you sure you want to continue connecting (yes/no/[fingerprint])?") != std::string::npos) {
1031+
std::string s = "yes\n";
1032+
proc.writeInput(s.c_str(), (int)s.size());
1033+
proc.closeInput();
1034+
break;
1035+
}
1036+
QApplication::processEvents();
1037+
}
9871038
}
988-
proc.wait();
989-
std::vector<char> out;
990-
proc.readResult(&out);
991-
std::string s(out.begin(), out.end());
992-
fprintf(stderr, "[%s]\n", s.c_str());
993-
#elif 0
994-
ProcessPosixPty proc;
995-
proc.start("sort", "");
996-
{
997-
const char *input = "abc\ndef\n";
998-
proc.writeInput(input, strlen(input));
1039+
while (proc.isRunning()) {
1040+
char tmp[1024];
1041+
int n = proc.readOutput(tmp, sizeof(tmp));
1042+
if (n > 0) {
1043+
std::string s(tmp, n);
1044+
fprintf(stderr, "%s", s.c_str());
1045+
text += s;
1046+
} else {
1047+
QApplication::processEvents();
1048+
}
9991049
}
1000-
proc.wait();
1050+
1051+
1052+
proc.stop();
10011053
std::vector<char> out;
10021054
proc.readResult(&out);
10031055
std::string s(out.begin(), out.end());

0 commit comments

Comments
 (0)