Mercurial > hg > easyhg
comparison hgrunner.cpp @ 75:295e3ee4a257
* Allocate a pty for the subprocess, and ask the user for password. Very rudimentary and non-portable.
author | Chris Cannam |
---|---|
date | Fri, 19 Nov 2010 18:39:40 +0000 |
parents | 10eb97683aa9 |
children | d575a8f76a53 |
comparison
equal
deleted
inserted
replaced
74:10eb97683aa9 | 75:295e3ee4a257 |
---|---|
23 #include <QListWidget> | 23 #include <QListWidget> |
24 #include <QDialog> | 24 #include <QDialog> |
25 #include <QLabel> | 25 #include <QLabel> |
26 #include <QVBoxLayout> | 26 #include <QVBoxLayout> |
27 #include <QSettings> | 27 #include <QSettings> |
28 #include <QInputDialog> | |
28 | 29 |
29 #include <iostream> | 30 #include <iostream> |
30 #include <unistd.h> | 31 #include <unistd.h> |
32 #include <pty.h> | |
33 #include <errno.h> | |
34 #include <stdio.h> | |
31 | 35 |
32 HgRunner::HgRunner(QWidget * parent): QProgressBar(parent) | 36 HgRunner::HgRunner(QWidget * parent): QProgressBar(parent) |
33 { | 37 { |
34 proc = new QProcess(this); | 38 proc = new QProcess(this); |
35 | 39 |
43 isRunning = false; | 47 isRunning = false; |
44 | 48 |
45 stdOut.clear(); | 49 stdOut.clear(); |
46 stdErr.clear(); | 50 stdErr.clear(); |
47 | 51 |
52 procInput = 0; | |
53 char name[1024]; | |
54 if (openpty(&ptyMasterFd, &ptySlaveFd, name, NULL, NULL)) { | |
55 perror("openpty failed"); | |
56 } else { | |
57 DEBUG << "openpty succeeded: master " << ptyMasterFd | |
58 << " slave " << ptySlaveFd << " filename " << name << endl; | |
59 procInput = new QFile; | |
60 procInput->open(ptyMasterFd, QFile::WriteOnly); | |
61 ptySlaveFilename = name; | |
62 proc->setStandardInputFile(ptySlaveFilename); | |
63 ::close(ptySlaveFd); | |
64 } | |
65 | |
48 connect(proc, SIGNAL(started()), this, SLOT(started())); | 66 connect(proc, SIGNAL(started()), this, SLOT(started())); |
49 connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), | 67 connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), |
50 this, SLOT(finished(int, QProcess::ExitStatus))); | 68 this, SLOT(finished(int, QProcess::ExitStatus))); |
69 connect(proc, SIGNAL(readyReadStandardOutput()), | |
70 this, SLOT(stdOutReady())); | |
71 connect(proc, SIGNAL(readyReadStandardError()), | |
72 this, SLOT(stdErrReady())); | |
51 | 73 |
52 reportErrors = false; | 74 reportErrors = false; |
53 } | 75 } |
54 | 76 |
55 HgRunner::~HgRunner() | 77 HgRunner::~HgRunner() |
56 { | 78 { |
79 if (ptySlaveFilename != "") { | |
80 ::close(ptyMasterFd); | |
81 // ::close(ptySlaveFd); | |
82 } | |
57 delete proc; | 83 delete proc; |
58 } | 84 } |
59 | 85 |
60 QString HgRunner::getHgBinaryName() | 86 QString HgRunner::getHgBinaryName() |
61 { | 87 { |
67 return hg; | 93 return hg; |
68 } | 94 } |
69 | 95 |
70 void HgRunner::started() | 96 void HgRunner::started() |
71 { | 97 { |
98 /* | |
99 if (procInput) procInput->write("blah\n"); | |
100 if (procInput) procInput->write("blah\n"); | |
101 if (procInput) { | |
102 procInput->close(); | |
103 // ::close(ptyMasterFd); | |
104 } | |
72 proc -> closeWriteChannel(); | 105 proc -> closeWriteChannel(); |
106 */ | |
73 } | 107 } |
74 | 108 |
75 void HgRunner::saveOutput() | 109 void HgRunner::saveOutput() |
76 { | 110 { |
77 stdOut = QString::fromUtf8(proc -> readAllStandardOutput()); | 111 stdOut += QString::fromUtf8(proc -> readAllStandardOutput()); |
78 stdErr = QString::fromUtf8(proc -> readAllStandardError()); | 112 stdErr += QString::fromUtf8(proc -> readAllStandardError()); |
79 | 113 |
80 DEBUG << "saveOutput: " << stdOut.split("\n").size() << " line(s) of stdout, " << stdErr.split("\n").size() << " line(s) of stderr" << endl; | 114 DEBUG << "saveOutput: " << stdOut.split("\n").size() << " line(s) of stdout, " << stdErr.split("\n").size() << " line(s) of stderr" << endl; |
81 | 115 |
82 // std::cerr << "stdout was " << stdOut.toStdString() << std::endl; | 116 // std::cerr << "stdout was " << stdOut.toStdString() << std::endl; |
83 } | 117 } |
89 } | 123 } |
90 | 124 |
91 QString HgRunner::getLastCommandLine() | 125 QString HgRunner::getLastCommandLine() |
92 { | 126 { |
93 return QString("Command line: " + lastHgCommand + " " + lastParams); | 127 return QString("Command line: " + lastHgCommand + " " + lastParams); |
128 } | |
129 | |
130 void HgRunner::stdOutReady() | |
131 { | |
132 DEBUG << "stdOutReady" << endl; | |
133 QString chunk = QString::fromUtf8(proc->readAllStandardOutput()); | |
134 DEBUG << "stdout was " << chunk << endl; | |
135 stdOut += chunk; | |
136 } | |
137 | |
138 void HgRunner::stdErrReady() | |
139 { | |
140 DEBUG << "stdErrReady" << endl; | |
141 QString chunk = QString::fromUtf8(proc->readAllStandardError()); | |
142 DEBUG << "stderr was " << chunk << endl; | |
143 stdErr += chunk; | |
144 if (procInput) { | |
145 if (chunk.toLower().trimmed() == "password:") { | |
146 bool ok = false; | |
147 QString pwd = QInputDialog::getText | |
148 (qobject_cast<QWidget *>(parent()), | |
149 tr("Enter password"), tr("Password (but for what user name and repository??"), | |
150 QLineEdit::Password, QString(), &ok); | |
151 if (ok) { | |
152 procInput->write(QString("%1\n").arg(pwd).toUtf8()); | |
153 procInput->flush(); | |
154 } else { | |
155 //!!! do what? close the terminal? | |
156 } | |
157 } | |
158 } | |
94 } | 159 } |
95 | 160 |
96 void HgRunner::finished(int procExitCode, QProcess::ExitStatus procExitStatus) | 161 void HgRunner::finished(int procExitCode, QProcess::ExitStatus procExitStatus) |
97 { | 162 { |
98 setProcExitInfo(procExitCode, procExitStatus); | 163 setProcExitInfo(procExitCode, procExitStatus); |