diff options
author | Mathias Gumz <akira@fluxbox.org> | 2015-01-02 16:04:36 (GMT) |
---|---|---|
committer | Mathias Gumz <akira@fluxbox.org> | 2015-01-02 16:08:44 (GMT) |
commit | a3c0b049bf4fabee1b7b4ab3a5513dc11c5e9dd4 (patch) | |
tree | f42196489304515ce593161554904a455757e699 /util/fbrun/FbRun.cc | |
parent | 0e8a27e931e66a4823b761983dca38a59fa6f37f (diff) | |
download | fluxbox-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.
Diffstat (limited to 'util/fbrun/FbRun.cc')
-rw-r--r-- | util/fbrun/FbRun.cc | 62 |
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 | ||
112 | void FbRun::run(const std::string &command) { | 112 | void 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 | |||
201 | bool FbRun::loadHistory(const char *filename) { | 179 | bool FbRun::loadHistory(const char *filename) { |
202 | if (filename == 0) | 180 | if (filename == 0) |
203 | return false; | 181 | return false; |