# HG changeset patch # User Chris Cannam # Date 1290788898 0 # Node ID 151209bc5bd6321f6f377e850cf189cd5276ba3a # Parent 0f039d3cc38ecfa96e8af5abab11f1651f575d52 * Fixes to terminal lifecycle (only the first of a series of interactive commands was working before). Also switch from openpty to POSIX/Unix98 openpt diff -r 0f039d3cc38e -r 151209bc5bd6 hgrunner.cpp --- a/hgrunner.cpp Fri Nov 26 14:50:10 2010 +0000 +++ b/hgrunner.cpp Fri Nov 26 16:28:18 2010 +0000 @@ -28,16 +28,13 @@ #include #include -#include #include #include +#include #ifndef Q_OS_WIN32 -#ifdef Q_OS_MAC -#include -#else -#include -#endif +#include +#include #endif HgRunner::HgRunner(QWidget * parent): QProgressBar(parent) @@ -65,9 +62,7 @@ HgRunner::~HgRunner() { - if (m_ptySlaveFilename != "") { - ::close(m_ptyMasterFd); - } + closeTerminal(); delete m_proc; } @@ -143,9 +138,14 @@ m_procInput->write(QString("%1\n").arg(pwd).toUtf8()); m_procInput->flush(); return; + } else { + DEBUG << "HgRunner::getUsername: user cancelled" << endl; + killCurrentCommand(); + return; } } // user cancelled or something went wrong + DEBUG << "HgRunner::getUsername: something went wrong" << endl; killCurrentCommand(); } @@ -171,9 +171,14 @@ m_procInput->write(QString("%1\n").arg(pwd).toUtf8()); m_procInput->flush(); return; + } else { + DEBUG << "HgRunner::getPassword: user cancelled" << endl; + killCurrentCommand(); + return; } } // user cancelled or something went wrong + DEBUG << "HgRunner::getPassword: something went wrong" << endl; killCurrentCommand(); } @@ -239,18 +244,13 @@ DEBUG << "HgRunner::finished: Command completed successfully" << endl; emit commandCompleted(completedAction, m_stdout); } else { - DEBUG << "HgRunner::finished: Command failed" << endl; + DEBUG << "HgRunner::finished: Command failed, stderr follows" << endl; + DEBUG << m_stderr << endl; emit commandFailed(completedAction, m_stderr); } checkQueue(); } -/* -bool HgRunner::isCommandRunning() -{ - return m_isRunning; -} -*/ void HgRunner::killCurrentCommand() { @@ -310,25 +310,12 @@ m_proc->setWorkingDirectory(action.workingDir); } - m_procInput = 0; - m_ptySlaveFilename = ""; - -#ifndef Q_OS_WIN32 if (interactive) { - char name[1024]; - if (openpty(&m_ptyMasterFd, &m_ptySlaveFd, name, NULL, NULL)) { - perror("openpty failed"); - } else { - DEBUG << "openpty succeeded: master " << m_ptyMasterFd - << " slave " << m_ptySlaveFd << " filename " << name << endl; - m_procInput = new QFile; - m_procInput->open(m_ptyMasterFd, QFile::WriteOnly); - m_ptySlaveFilename = name; + openTerminal(); + if (m_ptySlaveFilename != "") { m_proc->setStandardInputFile(m_ptySlaveFilename); - ::close(m_ptySlaveFd); } } -#endif QString cmdline = executable; foreach (QString param, params) cmdline += " " + param; @@ -347,11 +334,48 @@ DEBUG << "closeProcInput" << endl; m_proc->closeWriteChannel(); +} + +void HgRunner::openTerminal() +{ +#ifndef Q_OS_WIN32 + if (m_ptySlaveFilename != "") return; // already open + DEBUG << "HgRunner::openTerminal: trying to open new pty" << endl; + int master = posix_openpt(O_RDWR | O_NOCTTY); + if (master < 0) { + DEBUG << "openpt failed" << endl; + perror("openpt failed"); + return; + } + if (grantpt(master)) { + perror("grantpt failed"); + } + if (unlockpt(master)) { + perror("unlockpt failed"); + } + char *slave = ptsname(master); + if (!slave) { + perror("ptsname failed"); + ::close(master); + return; + } + m_ptyMasterFd = master; + m_procInput = new QFile(); + m_procInput->open(m_ptyMasterFd, QFile::WriteOnly); + m_ptySlaveFilename = slave; + DEBUG << "HgRunner::openTerminal: succeeded, slave is " + << m_ptySlaveFilename << endl; +#endif +} + +void HgRunner::closeTerminal() +{ #ifndef Q_OS_WIN32 if (m_ptySlaveFilename != "") { + delete m_procInput; + m_procInput = 0; ::close(m_ptyMasterFd); m_ptySlaveFilename = ""; } #endif } - diff -r 0f039d3cc38e -r 151209bc5bd6 hgrunner.h --- a/hgrunner.h Fri Nov 26 14:50:10 2010 +0000 +++ b/hgrunner.h Fri Nov 26 16:28:18 2010 +0000 @@ -66,6 +66,9 @@ void getPassword(); void checkPrompts(QString); + void openTerminal(); + void closeTerminal(); + int m_ptyMasterFd; int m_ptySlaveFd; QString m_ptySlaveFilename;