aboutsummaryrefslogtreecommitdiff
path: root/src/main.cc
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2010-09-18 15:51:30 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2010-09-18 15:51:30 (GMT)
commit0ef76292c5447127dc3fd39d6272f6d88a63d145 (patch)
tree167e28347f69bcc8db8dfc38f04a01f70f21df2b /src/main.cc
parentc9c741c88da3cc5e74f0399c3c5c1f0e70163a7a (diff)
downloadfluxbox_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.cc124
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
211struct Options { 219struct 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*/
321void 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.
372void 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
302int main(int argc, char **argv) { 404int 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