aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Gumz <akira@fluxbox.org>2015-01-02 16:04:36 (GMT)
committerMathias Gumz <akira@fluxbox.org>2015-01-02 16:08:44 (GMT)
commita3c0b049bf4fabee1b7b4ab3a5513dc11c5e9dd4 (patch)
treef42196489304515ce593161554904a455757e699
parent0e8a27e931e66a4823b761983dca38a59fa6f37f (diff)
downloadfluxbox-a3c0b049bf4fabee1b7b4ab3a5513dc11c5e9dd4.zip
fluxbox-a3c0b049bf4fabee1b7b4ab3a5513dc11c5e9dd4.tar.bz2
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.
-rw-r--r--util/fbrun/FbRun.cc62
1 files changed, 20 insertions, 42 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc
index a858487..8cc6b16 100644
--- a/util/fbrun/FbRun.cc
+++ b/util/fbrun/FbRun.cc
@@ -110,12 +110,18 @@ FbRun::~FbRun() {
110} 110}
111 111
112void FbRun::run(const std::string &command) { 112void FbRun::run(const std::string &command) {
113
113 FbTk::App::instance()->end(); // end application 114 FbTk::App::instance()->end(); // end application
114 m_end = true; // mark end of processing 115 m_end = true; // mark end of processing
115 116
117 hide(); // hide gui
118
116 if (m_print) { 119 if (m_print) {
117 std::cout << command; 120 std::cout << command;
118 hide(); 121 return;
122 }
123
124 if (command.empty()) {
119 return; 125 return;
120 } 126 }
121 127
@@ -152,52 +158,24 @@ void FbRun::run(const std::string &command) {
152#error "Can't build FbRun - don't know how to launch without fork on your platform" 158#error "Can't build FbRun - don't know how to launch without fork on your platform"
153#endif 159#endif
154 160
155 hide(); // hide gui 161 ofstream outfile(m_history_file.c_str());
156 162 if (!outfile) {
157 // save command history to file 163 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
158 if (text().size() != 0) { // no need to save empty command 164 return;
159 165 }
160 // don't allow duplicates into the history file, first
161 // look for a duplicate
162 if (m_current_history_item < m_history.size()
163 && text() == m_history[m_current_history_item]) {
164 // m_current_history_item is the duplicate
165 } else {
166 m_current_history_item = 0;
167 for (; m_current_history_item < m_history.size();
168 ++m_current_history_item) {
169 if (m_history[m_current_history_item] == text())
170 break;
171 }
172 }
173 166
174 fstream inoutfile(m_history_file.c_str(), ios::in|ios::out); 167 for (unsigned i = 0; i != m_history.size(); ++i) {
175 if (inoutfile) { 168 // don't allow duplicates into the history file
176 // now m_current_history_item points at the duplicate, or 169 if (m_history[i] == command)
177 // at m_history.size() if no duplicate 170 continue;
178 if (m_current_history_item != m_history.size()) {
179 unsigned int i = 0;
180 // read past history items before current
181 for (; inoutfile.good() && i < m_current_history_item; i++)
182 inoutfile.ignore(1, '\n');
183
184 // write the history items that come after current
185 for (i++; i < m_history.size(); i++)
186 inoutfile<<m_history[i]<<endl;
187
188 } else {
189 // set put-pointer at end of file
190 inoutfile.seekp(0, ios::end);
191 }
192 // append current command to the file
193 inoutfile<<command<<endl;
194 171
195 } else 172 outfile<<m_history[i]<<endl;
196 cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl;
197 } 173 }
198 174 outfile<<command<<endl;
175 outfile.close();
199} 176}
200 177
178
201bool FbRun::loadHistory(const char *filename) { 179bool FbRun::loadHistory(const char *filename) {
202 if (filename == 0) 180 if (filename == 0)
203 return false; 181 return false;