diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 63 | ||||
-rwxr-xr-x | cpp/src/IcePatch2/ClientUtil.cpp | 64 |
2 files changed, 107 insertions, 20 deletions
diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index 3c51f4d3aad..1b544f896be 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -10,6 +10,8 @@ #include <Ice/Application.h> #include <IcePatch2/Util.h> #include <IcePatch2/ClientUtil.h> +#include <fcntl.h> +#include <termios.h> using namespace std; using namespace Ice; @@ -36,6 +38,28 @@ class TextPatcherFeedback : public PatcherFeedback { public: + TextPatcherFeedback() + { + tcgetattr(0, &_savedTerm); + termios term; + memcpy(&term, &_savedTerm, sizeof(termios)); + term.c_lflag &= ~(ECHO | ICANON); + term.c_cc[VTIME] = 0; + term.c_cc[VMIN] = 1; + tcsetattr(0, TCSANOW, &term); + + _savedFlags = fcntl(0, F_GETFL); + int flags = _savedFlags; + flags |= O_NONBLOCK; + fcntl(0, F_SETFL, flags); + } + + virtual ~TextPatcherFeedback() + { + tcsetattr(0, TCSANOW, &_savedTerm); + fcntl(0, F_SETFL, _savedFlags); + } + virtual bool noFileSummary(const string& reason) { @@ -58,9 +82,10 @@ public: virtual bool fileListStart() { + cout << "[Press any key to interrupt]" << endl; _lastProgress = "0%"; cout << "Getting list of files to patch: " << _lastProgress << flush; - return true; + return !keyPressed(); } virtual bool @@ -74,14 +99,14 @@ public: s << percent << '%'; _lastProgress = s.str(); cout << _lastProgress << flush; - return true; + return !keyPressed(); } virtual bool fileListEnd() { cout << endl; - return true; + return !keyPressed(); } virtual bool @@ -91,7 +116,7 @@ public: s << "0/" << size << " (" << totalProgress << '/' << totalSize << ')'; _lastProgress = s.str(); cout << getBasename(path) << ' ' << _lastProgress << flush; - return true; + return !keyPressed(); } virtual bool @@ -105,19 +130,33 @@ public: s << progress << '/' << size << " (" << totalProgress << '/' << totalSize << ')'; _lastProgress = s.str(); cout << _lastProgress << flush; - return true; + return !keyPressed(); } virtual bool patchEnd() { cout << endl; - return true; + return !keyPressed(); } private: + bool + keyPressed() + { + bool pressed = false; + char c; + while(read(0, &c, 1) > 0) + { + pressed = true; + } + return pressed; + } + string _lastProgress; + termios _savedTerm; + int _savedFlags; }; int @@ -166,6 +205,8 @@ IcePatch2::Client::run(int argc, char* argv[]) } } + bool patchComplete; + try { PatcherFeedbackPtr feedback = new TextPatcherFeedback; @@ -178,7 +219,15 @@ IcePatch2::Client::run(int argc, char* argv[]) return EXIT_FAILURE; } - return EXIT_SUCCESS; + if(patchComplete) + { + return EXIT_SUCCESS; + } + else + { + cout << "\n[Interrupted]" << endl; + return EXIT_FAILURE; + } } void diff --git a/cpp/src/IcePatch2/ClientUtil.cpp b/cpp/src/IcePatch2/ClientUtil.cpp index fc1fa3ec71a..c9ae0035e12 100755 --- a/cpp/src/IcePatch2/ClientUtil.cpp +++ b/cpp/src/IcePatch2/ClientUtil.cpp @@ -76,7 +76,7 @@ IcePatch2::Patcher::~Patcher() assert(!_decompress); } -void +bool IcePatch2::Patcher::patch() { FileInfoSeq infoSeq; @@ -94,7 +94,7 @@ IcePatch2::Patcher::patch() thorough = _feedback->noFileSummary(ex); if(!thorough) { - return; + return false; } } } @@ -115,7 +115,10 @@ IcePatch2::Patcher::patch() if(tree0.checksum != _serverCompress->getChecksum()) { - _feedback->fileListStart(); + if(!_feedback->fileListStart()) + { + return false; + } ByteSeqSeq checksum0Seq = _serverCompress->getChecksum0Seq(); if(checksum0Seq.size() != 256) @@ -147,18 +150,27 @@ IcePatch2::Patcher::patch() FileInfoLess()); } - _feedback->fileListProgress((node0 + 1) * 100 / 256); + if(!_feedback->fileListProgress((node0 + 1) * 100 / 256)) + { + return false; + } } - _feedback->fileListEnd(); + if(!_feedback->fileListEnd()) + { + return false; + } } sort(removeFileSeq.begin(), removeFileSeq.end(), FileInfoLess()); sort(updateFileSeq.begin(), updateFileSeq.end(), FileInfoLess()); - + if(!removeFileSeq.empty()) { - removeFiles(removeFileSeq); + if(!removeFiles(removeFileSeq)) + { + return false; + } if(!_dryRun) { @@ -199,7 +211,18 @@ IcePatch2::Patcher::patch() try { - updateFiles(updateFileSeq); + if(!updateFiles(updateFileSeq)) + { + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _decompress = false; + notify(); + } + + getThreadControl().join(); + + return false; + } } catch(...) { @@ -245,9 +268,11 @@ IcePatch2::Patcher::patch() saveFileInfoSeq(_dataDir, infoSeq); } } + + return true; } -void +bool IcePatch2::Patcher::removeFiles(const FileInfoSeq& files) { if(!_dryRun) @@ -268,9 +293,11 @@ IcePatch2::Patcher::removeFiles(const FileInfoSeq& files) p->path.compare(0, dir.size(), dir) == 0); } } + + return true; } -void +bool IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) { FileInfoSeq::const_iterator p; @@ -302,7 +329,10 @@ IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) } else // Regular file. { - _feedback->patchStart(p->path, p->size, updated, total); + if(!_feedback->patchStart(p->path, p->size, updated, total)) + { + return false; + } string pathBZ2 = _dataDir + '/' + p->path + ".bz2"; ofstream fileBZ2; @@ -364,7 +394,10 @@ IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) pos += bytes.size(); updated += bytes.size(); - _feedback->patchProgress(pos, p->size, updated, total); + if(!_feedback->patchProgress(pos, p->size, updated, total)) + { + return false; + } } if(!_dryRun) @@ -382,9 +415,14 @@ IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) } } - _feedback->patchEnd(); + if(!_feedback->patchEnd()) + { + return false; + } } } + + return true; } void |