diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2010-09-18 15:51:30 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2010-09-18 15:51:30 (GMT) |
commit | 0ef76292c5447127dc3fd39d6272f6d88a63d145 (patch) | |
tree | 167e28347f69bcc8db8dfc38f04a01f70f21df2b /src/main.cc | |
parent | c9c741c88da3cc5e74f0399c3c5c1f0e70163a7a (diff) | |
download | fluxbox_pavel-0ef76292c5447127dc3fd39d6272f6d88a63d145.zip fluxbox_pavel-0ef76292c5447127dc3fd39d6272f6d88a63d145.tar.bz2 |
changed the way we create the '~/.fluxbox' directory to avoid race conditions
before bringing up the first instance of Fluxbox we prepare the directory
and the files it needs. if the config version of exiting files is lower
than what we expect, we upgrade the config files. after that we bring
up Fluxbox.
the old way was problematic because setupConfigFiles() calls
'fluxbox-update_configs' which does its job in the background while
fluxbox continues to boot. 'fluxbox-update_configs' sends a USR2 signal
to the booting fluxbox (it might even be finished, no one knows) which
triggers 'load_rc()' which triggered 'setupConfigFiles()' again which
might trigger 'fluxbox-update_configs' again (on my machine
'fluxbox-update_configs' was called 3 times and left a pretty crippled
'keys' file when it was done).
bootstrapping before bringing up fluxbox resolves the issue. as a bonus:
no need to send USR2 to fluxbox to reload the config file because fluxbox
has not even tried to read it yet.
Diffstat (limited to 'src/main.cc')
-rw-r--r-- | src/main.cc | 124 |
1 files changed, 115 insertions, 9 deletions
diff --git a/src/main.cc b/src/main.cc index 6c03c63..6775b53 100644 --- a/src/main.cc +++ b/src/main.cc | |||
@@ -20,17 +20,21 @@ | |||
20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | // DEALINGS IN THE SOFTWARE. | 21 | // DEALINGS IN THE SOFTWARE. |
22 | 22 | ||
23 | #ifdef HAVE_CONFIG_H | ||
24 | #include "config.h" | ||
25 | #endif // HAVE_CONFIG_H | ||
26 | |||
23 | #include "fluxbox.hh" | 27 | #include "fluxbox.hh" |
24 | #include "version.h" | 28 | #include "version.h" |
25 | #include "defaults.hh" | 29 | #include "defaults.hh" |
26 | 30 | ||
31 | #include "Debug.hh" | ||
32 | #include "FbCommands.hh" | ||
33 | |||
27 | #include "FbTk/Theme.hh" | 34 | #include "FbTk/Theme.hh" |
28 | #include "FbTk/I18n.hh" | 35 | #include "FbTk/I18n.hh" |
29 | #include "FbTk/CommandParser.hh" | 36 | #include "FbTk/CommandParser.hh" |
30 | 37 | #include "FbTk/FileUtil.hh" | |
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif // HAVE_CONFIG_H | ||
34 | 38 | ||
35 | //use GNU extensions | 39 | //use GNU extensions |
36 | #ifndef _GNU_SOURCE | 40 | #ifndef _GNU_SOURCE |
@@ -49,7 +53,11 @@ | |||
49 | #include <string.h> | 53 | #include <string.h> |
50 | #endif | 54 | #endif |
51 | 55 | ||
52 | #include <iostream> | 56 | #ifdef HAVE_SYS_STAT_H |
57 | #include <sys/types.h> | ||
58 | #include <sys/stat.h> | ||
59 | #endif // HAVE_SYS_STAT_H | ||
60 | |||
53 | #include <fstream> | 61 | #include <fstream> |
54 | #include <stdexcept> | 62 | #include <stdexcept> |
55 | #include <typeinfo> | 63 | #include <typeinfo> |
@@ -209,8 +217,16 @@ static void showInfo(ostream &ostr) { | |||
209 | } | 217 | } |
210 | 218 | ||
211 | struct Options { | 219 | struct Options { |
212 | Options() : xsync(false) { } | 220 | Options() : |
221 | session_display(getenv("DISPLAY")), | ||
222 | rc_path(std::string(getenv("HOME")) + "/." + realProgramName("fluxbox")), | ||
223 | rc_file(rc_path + "/init"), | ||
224 | xsync(false) { | ||
225 | |||
226 | } | ||
227 | |||
213 | std::string session_display; | 228 | std::string session_display; |
229 | std::string rc_path; | ||
214 | std::string rc_file; | 230 | std::string rc_file; |
215 | std::string log_filename; | 231 | std::string log_filename; |
216 | bool xsync; | 232 | bool xsync; |
@@ -298,6 +314,92 @@ static void parseOptions(int argc, char** argv, Options& opts) { | |||
298 | } | 314 | } |
299 | 315 | ||
300 | 316 | ||
317 | /** | ||
318 | setup the configutation files in | ||
319 | home directory | ||
320 | */ | ||
321 | void setupConfigFiles(const std::string& dirname, const std::string& rc) { | ||
322 | |||
323 | _FB_USES_NLS; | ||
324 | |||
325 | const bool has_dir = FbTk::FileUtil::isDirectory(dirname.c_str()); | ||
326 | |||
327 | |||
328 | struct CFInfo { | ||
329 | bool create_file; | ||
330 | const char* default_name; | ||
331 | const std::string filename; | ||
332 | } cfiles[] = { | ||
333 | { !has_dir, DEFAULT_INITFILE, rc }, | ||
334 | { !has_dir, DEFAULTKEYSFILE, dirname + "/keys" }, | ||
335 | { !has_dir, DEFAULTMENU, dirname + "/menu" }, | ||
336 | { !has_dir, DEFAULT_APPSFILE, dirname + "/apps" }, | ||
337 | { !has_dir, DEFAULT_OVERLAY, dirname + "/overlay" }, | ||
338 | { !has_dir, DEFAULT_WINDOWMENU, dirname + "/windowmenu" } | ||
339 | }; | ||
340 | const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo); | ||
341 | |||
342 | |||
343 | if (has_dir) { // check if anything with these names exists, if not create new | ||
344 | for (size_t i = 0; i < nr_of_cfiles; ++i) { | ||
345 | cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK); | ||
346 | } | ||
347 | } else { | ||
348 | |||
349 | fbdbg << "Creating dir: " << dirname << endl; | ||
350 | if (mkdir(dirname.c_str(), 0700)) { | ||
351 | fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory, | ||
352 | "Can't create %s directory", | ||
353 | "Can't create a directory, one %s for directory name").c_str(), | ||
354 | dirname.c_str()); | ||
355 | cerr << endl; | ||
356 | return; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | // copy default files if needed | ||
361 | for (size_t i = 0; i < nr_of_cfiles; ++i) { | ||
362 | if (cfiles[i].create_file) { | ||
363 | FbTk::FileUtil::copyFile(cfiles[i].default_name, cfiles[i].filename.c_str()); | ||
364 | } | ||
365 | } | ||
366 | |||
367 | } | ||
368 | |||
369 | |||
370 | // configs might be out of date, so run fluxbox-update_configs | ||
371 | // if necassary. | ||
372 | void updateConfigFilesIfNeeded(const std::string& rc_file) { | ||
373 | |||
374 | const int CONFIG_VERSION = 13; // TODO: move this to 'defaults.hh' or 'config.h' | ||
375 | |||
376 | FbTk::ResourceManager r_mgr(rc_file.c_str(), false); | ||
377 | FbTk::Resource<int> c_version(r_mgr, 0, "session.configVersion", "Session.ConfigVersion"); | ||
378 | |||
379 | if (!r_mgr.load(rc_file.c_str())) { | ||
380 | _FB_USES_NLS; | ||
381 | cerr << _FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "") | ||
382 | << ": " | ||
383 | << rc_file << endl; | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | if (*c_version < CONFIG_VERSION) { | ||
388 | |||
389 | fbdbg << "updating config files from version " | ||
390 | << *c_version | ||
391 | << " to " | ||
392 | << CONFIG_VERSION | ||
393 | << endl; | ||
394 | |||
395 | string commandargs = realProgramName("fluxbox-update_configs"); | ||
396 | commandargs += " -rc " + rc_file; | ||
397 | |||
398 | FbCommands::ExecuteCmd fbuc(commandargs, 0); | ||
399 | fbuc.execute(); | ||
400 | } | ||
401 | } | ||
402 | |||
301 | 403 | ||
302 | int main(int argc, char **argv) { | 404 | int main(int argc, char **argv) { |
303 | 405 | ||
@@ -309,7 +411,6 @@ int main(int argc, char **argv) { | |||
309 | #ifdef __EMX__ | 411 | #ifdef __EMX__ |
310 | _chdir2(getenv("X11ROOT")); | 412 | _chdir2(getenv("X11ROOT")); |
311 | #endif // __EMX__ | 413 | #endif // __EMX__ |
312 | auto_ptr<Fluxbox> fluxbox; | ||
313 | 414 | ||
314 | streambuf *outbuf = 0; | 415 | streambuf *outbuf = 0; |
315 | streambuf *errbuf = 0; | 416 | streambuf *errbuf = 0; |
@@ -338,11 +439,16 @@ int main(int argc, char **argv) { | |||
338 | 439 | ||
339 | int exitcode = EXIT_FAILURE; | 440 | int exitcode = EXIT_FAILURE; |
340 | 441 | ||
442 | setupConfigFiles(opts.rc_path, opts.rc_file); | ||
443 | updateConfigFilesIfNeeded(opts.rc_file); | ||
444 | |||
445 | auto_ptr<Fluxbox> fluxbox; | ||
341 | try { | 446 | try { |
342 | 447 | ||
343 | fluxbox.reset(new Fluxbox(argc, argv, | 448 | fluxbox.reset(new Fluxbox(argc, argv, |
344 | opts.session_display.c_str(), | 449 | opts.session_display, |
345 | opts.rc_file.c_str(), | 450 | opts.rc_path, |
451 | opts.rc_file, | ||
346 | opts.xsync)); | 452 | opts.xsync)); |
347 | fluxbox->eventLoop(); | 453 | fluxbox->eventLoop(); |
348 | 454 | ||