aboutsummaryrefslogtreecommitdiff
path: root/src
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
parentc9c741c88da3cc5e74f0399c3c5c1f0e70163a7a (diff)
downloadfluxbox-0ef76292c5447127dc3fd39d6272f6d88a63d145.zip
fluxbox-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')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/fluxbox.cc103
-rw-r--r--src/fluxbox.hh12
-rw-r--r--src/main.cc124
4 files changed, 140 insertions, 103 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3fcadea..38182c5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,14 +53,14 @@ defaults.hh: Makefile
53 echo '#define DEFAULT_WINDOWMENU "$(DEFAULT_WINDOWMENU)"'; \ 53 echo '#define DEFAULT_WINDOWMENU "$(DEFAULT_WINDOWMENU)"'; \
54 echo '#define PROGRAM_PREFIX "$(PROGRAM_PREFIX:NONE=)"'; \ 54 echo '#define PROGRAM_PREFIX "$(PROGRAM_PREFIX:NONE=)"'; \
55 echo '#define PROGRAM_SUFFIX "$(PROGRAM_SUFFIX:NONE=)"'; \ 55 echo '#define PROGRAM_SUFFIX "$(PROGRAM_SUFFIX:NONE=)"'; \
56 echo 'std::string realProgramName(std::string name);'; \ 56 echo 'std::string realProgramName(const std::string& name);'; \
57 echo 'const char* gitrevision();' ) > defaults.hh 57 echo 'const char* gitrevision();' ) > defaults.hh
58 58
59defaults.cc: force 59defaults.cc: force
60 @( \ 60 @( \
61 echo '#include "defaults.hh"'; \ 61 echo '#include "defaults.hh"'; \
62 echo ''; \ 62 echo ''; \
63 echo 'std::string realProgramName(std::string name) {'; \ 63 echo 'std::string realProgramName(const std::string& name) {'; \
64 echo ' return PROGRAM_PREFIX + name + PROGRAM_SUFFIX;'; \ 64 echo ' return PROGRAM_PREFIX + name + PROGRAM_SUFFIX;'; \
65 echo '}'; \ 65 echo '}'; \
66 echo ''; \ 66 echo ''; \
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 78a482e..ac18281 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -185,13 +185,17 @@ int handleXErrors(Display *d, XErrorEvent *e) {
185//static singleton var 185//static singleton var
186Fluxbox *Fluxbox::s_singleton=0; 186Fluxbox *Fluxbox::s_singleton=0;
187 187
188Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, 188Fluxbox::Fluxbox(int argc, char **argv,
189 const char *rcfilename, bool xsync) 189 const std::string& dpy_name,
190 : FbTk::App(dpy_name), 190 const std::string& rc_path, const std::string& rc_filename, bool xsync)
191 : FbTk::App(dpy_name.c_str()),
191 m_fbatoms(FbAtoms::instance()), 192 m_fbatoms(FbAtoms::instance()),
192 m_resourcemanager(rcfilename, true), 193 m_resourcemanager(rc_filename.c_str(), true),
193 // TODO: shouldn't need a separate one for screen 194 // TODO: shouldn't need a separate one for screen
194 m_screen_rm(m_resourcemanager), 195 m_screen_rm(m_resourcemanager),
196
197 m_RC_PATH(rc_path),
198 m_RC_INIT_FILE("init"),
195 m_rc_ignoreborder(m_resourcemanager, false, "session.ignoreBorder", "Session.IgnoreBorder"), 199 m_rc_ignoreborder(m_resourcemanager, false, "session.ignoreBorder", "Session.IgnoreBorder"),
196 m_rc_pseudotrans(m_resourcemanager, false, "session.forcePseudoTransparency", "Session.forcePseudoTransparency"), 200 m_rc_pseudotrans(m_resourcemanager, false, "session.forcePseudoTransparency", "Session.forcePseudoTransparency"),
197 m_rc_colors_per_channel(m_resourcemanager, 4, 201 m_rc_colors_per_channel(m_resourcemanager, 4,
@@ -199,11 +203,11 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
199 m_rc_double_click_interval(m_resourcemanager, 250, "session.doubleClickInterval", "Session.DoubleClickInterval"), 203 m_rc_double_click_interval(m_resourcemanager, 250, "session.doubleClickInterval", "Session.DoubleClickInterval"),
200 m_rc_tabs_padding(m_resourcemanager, 0, "session.tabPadding", "Session.TabPadding"), 204 m_rc_tabs_padding(m_resourcemanager, 0, "session.tabPadding", "Session.TabPadding"),
201 m_rc_stylefile(m_resourcemanager, DEFAULTSTYLE, "session.styleFile", "Session.StyleFile"), 205 m_rc_stylefile(m_resourcemanager, DEFAULTSTYLE, "session.styleFile", "Session.StyleFile"),
202 m_rc_styleoverlayfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/overlay", "session.styleOverlay", "Session.StyleOverlay"), 206 m_rc_styleoverlayfile(m_resourcemanager, m_RC_PATH + "/overlay", "session.styleOverlay", "Session.StyleOverlay"),
203 m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"), 207 m_rc_menufile(m_resourcemanager, m_RC_PATH + "/menu", "session.menuFile", "Session.MenuFile"),
204 m_rc_keyfile(m_resourcemanager, DEFAULTKEYSFILE, "session.keyFile", "Session.KeyFile"), 208 m_rc_keyfile(m_resourcemanager, m_RC_PATH + "/keys", "session.keyFile", "Session.KeyFile"),
205 m_rc_slitlistfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"), 209 m_rc_slitlistfile(m_resourcemanager, m_RC_PATH + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"),
206 m_rc_appsfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/apps", "session.appsFile", "Session.AppsFile"), 210 m_rc_appsfile(m_resourcemanager, m_RC_PATH + "/apps", "session.appsFile", "Session.AppsFile"),
207 m_rc_tabs_attach_area(m_resourcemanager, ATTACH_AREA_WINDOW, "session.tabsAttachArea", "Session.TabsAttachArea"), 211 m_rc_tabs_attach_area(m_resourcemanager, ATTACH_AREA_WINDOW, "session.tabsAttachArea", "Session.TabsAttachArea"),
208 m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), 212 m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),
209 m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), 213 m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
@@ -213,16 +217,14 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
213 m_keyscreen(0), 217 m_keyscreen(0),
214 m_last_time(0), 218 m_last_time(0),
215 m_masked(0), 219 m_masked(0),
216 m_rc_file(rcfilename ? rcfilename : ""), 220 m_rc_file(rc_filename),
217 m_argv(argv), m_argc(argc), 221 m_argv(argv), m_argc(argc),
218 m_showing_dialog(false), 222 m_showing_dialog(false),
219 m_starting(true), 223 m_starting(true),
220 m_restarting(false), 224 m_restarting(false),
221 m_shutdown(false), 225 m_shutdown(false),
222 m_server_grabs(0), 226 m_server_grabs(0),
223 m_randr_event_type(0), 227 m_randr_event_type(0) {
224 m_RC_PATH(realProgramName("fluxbox")),
225 m_RC_INIT_FILE("init") {
226 228
227 _FB_USES_NLS; 229 _FB_USES_NLS;
228 if (s_singleton != 0) 230 if (s_singleton != 0)
@@ -288,8 +290,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
288 290
289 grab(); 291 grab();
290 292
291 setupConfigFiles();
292
293 if (! XSupportsLocale()) 293 if (! XSupportsLocale())
294 cerr<<_FB_CONSOLETEXT(Fluxbox, WarningLocale, 294 cerr<<_FB_CONSOLETEXT(Fluxbox, WarningLocale,
295 "Warning: X server does not support locale", 295 "Warning: X server does not support locale",
@@ -512,76 +512,6 @@ void Fluxbox::ungrab() {
512 m_server_grabs = 0; 512 m_server_grabs = 0;
513} 513}
514 514
515/**
516 setup the configutation files in
517 home directory
518*/
519void Fluxbox::setupConfigFiles() {
520
521 string dirname = getDefaultDataFilename("");
522
523 // is file/dir already there?
524 const bool create_dir = FbTk::FileUtil::isDirectory(dirname.c_str());
525
526 struct CFInfo {
527 bool create_file;
528 const char* default_name;
529 const std::string filename;
530 } cfiles[] = {
531 { create_dir, DEFAULT_INITFILE, getDefaultDataFilename(m_RC_INIT_FILE) },
532 { create_dir, DEFAULTKEYSFILE, getDefaultDataFilename("keys") },
533 { create_dir, DEFAULTMENU, getDefaultDataFilename("menu") },
534 { create_dir, DEFAULT_APPSFILE, getDefaultDataFilename("apps") },
535 { create_dir, DEFAULT_OVERLAY, getDefaultDataFilename("overlay") },
536 { create_dir, DEFAULT_WINDOWMENU, getDefaultDataFilename("windowmenu") }
537 };
538 const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo);
539
540 if (create_dir) { // check if anything with those name exists, if not create new
541 for (size_t i = 0; i < nr_of_cfiles; ++i) {
542 cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK);
543 }
544 } else{
545 fbdbg<<"Creating dir: " << dirname.c_str() << endl;
546 _FB_USES_NLS;
547 // create directory with perm 700
548 if (mkdir(dirname.c_str(), 0700)) {
549 fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory,
550 "Can't create %s directory",
551 "Can't create a directory, one %s for directory name").c_str(),
552 dirname.c_str());
553 cerr<<endl;
554 return;
555 }
556 }
557
558 // copy default files if needed
559 for (size_t i = 0; i < nr_of_cfiles; ++i) {
560 if (cfiles[i].create_file) {
561 FbTk::FileUtil::copyFile(cfiles[i].default_name, cfiles[i].filename.c_str());
562 }
563 }
564
565#define CONFIG_VERSION 13
566 FbTk::Resource<int> config_version(m_resourcemanager, 0,
567 "session.configVersion", "Session.ConfigVersion");
568 if (*config_version < CONFIG_VERSION) {
569 // configs are out of date, so run fluxbox-update_configs
570
571 string commandargs = realProgramName("fluxbox-update_configs");
572 commandargs += " -rc " + cfiles[0].filename;
573
574#ifdef HAVE_GETPID
575 // add the fluxbox pid so fbuc can have us reload rc if necessary
576 commandargs += " -pid ";
577 commandargs += FbTk::StringUtil::number2String(getpid());
578#endif // HAVE_GETPID
579
580 FbCommands::ExecuteCmd fbuc(commandargs, 0);
581 fbuc.execute();
582 }
583}
584
585void Fluxbox::handleEvent(XEvent * const e) { 515void Fluxbox::handleEvent(XEvent * const e) {
586 _FB_USES_NLS; 516 _FB_USES_NLS;
587 m_last_event = *e; 517 m_last_event = *e;
@@ -1216,7 +1146,7 @@ string Fluxbox::getRcFilename() {
1216 1146
1217/// Provides default filename of data file 1147/// Provides default filename of data file
1218string Fluxbox::getDefaultDataFilename(const char *name) const { 1148string Fluxbox::getDefaultDataFilename(const char *name) const {
1219 return (getenv("HOME") + string("/.") + m_RC_PATH + string("/") + name); 1149 return m_RC_PATH + string("/") + name;
1220} 1150}
1221 1151
1222/// loads resources 1152/// loads resources
@@ -1311,7 +1241,6 @@ void Fluxbox::load_rc(BScreen &screen) {
1311} 1241}
1312 1242
1313void Fluxbox::reconfigure() { 1243void Fluxbox::reconfigure() {
1314 setupConfigFiles();
1315 load_rc(); 1244 load_rc();
1316 m_reconfigure_wait = true; 1245 m_reconfigure_wait = true;
1317 m_reconfig_timer.start(); 1246 m_reconfig_timer.start();
diff --git a/src/fluxbox.hh b/src/fluxbox.hh
index 75b868f..36b39ef 100644
--- a/src/fluxbox.hh
+++ b/src/fluxbox.hh
@@ -79,8 +79,10 @@ class Fluxbox : public FbTk::App,
79 public FbTk::Observer, 79 public FbTk::Observer,
80 private FbTk::SignalTracker { 80 private FbTk::SignalTracker {
81public: 81public:
82 Fluxbox(int argc, char **argv, const char * dpy_name= 0, 82 Fluxbox(int argc, char **argv,
83 const char *rcfilename = 0, bool xsync = false); 83 const std::string& dpy_name,
84 const std::string& rc_path, const std::string& rc_filename,
85 bool xsync = false);
84 virtual ~Fluxbox(); 86 virtual ~Fluxbox();
85 87
86 static Fluxbox *instance() { return s_singleton; } 88 static Fluxbox *instance() { return s_singleton; }
@@ -197,7 +199,6 @@ private:
197 199
198 void handleEvent(XEvent *xe); 200 void handleEvent(XEvent *xe);
199 201
200 void setupConfigFiles();
201 void handleUnmapNotify(XUnmapEvent &ue); 202 void handleUnmapNotify(XUnmapEvent &ue);
202 void handleClientMessage(XClientMessageEvent &ce); 203 void handleClientMessage(XClientMessageEvent &ce);
203 204
@@ -221,6 +222,9 @@ private:
221 222
222 FbTk::ResourceManager m_resourcemanager, &m_screen_rm; 223 FbTk::ResourceManager m_resourcemanager, &m_screen_rm;
223 224
225 std::string m_RC_PATH;
226 const char *m_RC_INIT_FILE;
227
224 //--- Resources 228 //--- Resources
225 229
226 FbTk::Resource<bool> m_rc_ignoreborder; 230 FbTk::Resource<bool> m_rc_ignoreborder;
@@ -289,8 +293,6 @@ private:
289 int m_randr_event_type; ///< the type number of randr event 293 int m_randr_event_type; ///< the type number of randr event
290 int m_shape_eventbase; ///< event base for shape events 294 int m_shape_eventbase; ///< event base for shape events
291 bool m_have_shape; ///< if shape is supported by server 295 bool m_have_shape; ///< if shape is supported by server
292 std::string m_RC_PATH;
293 const char *m_RC_INIT_FILE;
294 Atom m_kwm1_dockwindow, m_kwm2_dockwindow; 296 Atom m_kwm1_dockwindow, m_kwm2_dockwindow;
295 297
296 AttentionNoticeHandler m_attention_handler; 298 AttentionNoticeHandler m_attention_handler;
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