Fix corruption of fbrun-history

This commit fixes issues #72 (brought up + different solution by Mattias
Guns; I received a similar patch by 'Nable 80' via ML and discussed the
issue in #fluxbox with 'Nable 80'), patch #73 (Mattias Guns) and finally
patch #162 (Ulrich Eckhardt; this commit is heavily based upon Ulrich's
work).

The original code was overly complex. It tried to avoid writing
bytes to the disk at the expense of comprehensibility and as a result it
was buggy. I looked at both patches from Mattias and 'Nable 80' which address
the bug with skipping entries in the history-file (my fault: incorrect use
of outfile.ignore(1, '\n')): They provided a proper fix for the problem
but I decided to use Ulrich's code since it improves the whole code by making
it a lot simpler.

So, kudos to all of you.
This commit is contained in:
Mathias Gumz 2015-01-02 17:04:36 +01:00
parent 0e8a27e931
commit a3c0b049bf

View file

@ -110,12 +110,18 @@ FbRun::~FbRun() {
} }
void FbRun::run(const std::string &command) { void FbRun::run(const std::string &command) {
FbTk::App::instance()->end(); // end application FbTk::App::instance()->end(); // end application
m_end = true; // mark end of processing m_end = true; // mark end of processing
hide(); // hide gui
if (m_print) { if (m_print) {
std::cout << command; std::cout << command;
hide(); return;
}
if (command.empty()) {
return; return;
} }
@ -152,52 +158,24 @@ void FbRun::run(const std::string &command) {
#error "Can't build FbRun - don't know how to launch without fork on your platform" #error "Can't build FbRun - don't know how to launch without fork on your platform"
#endif #endif
hide(); // hide gui ofstream outfile(m_history_file.c_str());
if (!outfile) {
// save command history to file
if (text().size() != 0) { // no need to save empty command
// don't allow duplicates into the history file, first
// look for a duplicate
if (m_current_history_item < m_history.size()
&& text() == m_history[m_current_history_item]) {
// m_current_history_item is the duplicate
} else {
m_current_history_item = 0;
for (; m_current_history_item < m_history.size();
++m_current_history_item) {
if (m_history[m_current_history_item] == text())
break;
}
}
fstream inoutfile(m_history_file.c_str(), ios::in|ios::out);
if (inoutfile) {
// now m_current_history_item points at the duplicate, or
// at m_history.size() if no duplicate
if (m_current_history_item != m_history.size()) {
unsigned int i = 0;
// read past history items before current
for (; inoutfile.good() && i < m_current_history_item; i++)
inoutfile.ignore(1, '\n');
// write the history items that come after current
for (i++; i < m_history.size(); i++)
inoutfile<<m_history[i]<<endl;
} else {
// set put-pointer at end of file
inoutfile.seekp(0, ios::end);
}
// append current command to the file
inoutfile<<command<<endl;
} else
cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl; cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
return;
} }
for (unsigned i = 0; i != m_history.size(); ++i) {
// don't allow duplicates into the history file
if (m_history[i] == command)
continue;
outfile<<m_history[i]<<endl;
}
outfile<<command<<endl;
outfile.close();
} }
bool FbRun::loadHistory(const char *filename) { bool FbRun::loadHistory(const char *filename) {
if (filename == 0) if (filename == 0)
return false; return false;