I have a small history of bitching about things GNU and Linux do just
because It's The Unix Way, even when doing so is suboptimal.
I already listed some things that GNU/Linux should outright
steal from Mac OS X, and here was me whining about ports below 1024.
I wanted to add something to that list today. Why are we using hidden files in
$HOME for application configuration data?
My workstation has 233 files/directories that start with a '.' in my home
directory. They all have names like:
Most of these aren't meant to be mucked around in, and some that might be
human-readable, I would fear to wade into anyhow.
It isn't always clear where things came from, either. I guess if you have
a ".cpan" directory, you probably know what CPAN is, but honestly, where
did this ".dmrc" file come from? Could we have picked a better name?
I suspect there is a historic reason for this. User convenience, perhaps.
Some of them did make good sense: after all, I'm editing ~/.plan right now.
But here are my complaints with the current system:
- Their specific purpose isn't clear in many cases.
- It's not clear what application wrote and needs this information.
- It's not clear if several files are all part of the same application.
- They're cluttering up my home directory, even if a historic quirk of
Unix happens to hide this fact.
- Hiding them helps with the clutter, but we really shouldn't be hiding
them at all.
A better way:
- Have one config directory in $HOME, with one subdirectory for each app,
where it can write all it wants.
So I might find I have a tree like this:
/home/icculus/Configs/Mozilla Thunderbird/Address Book
We can call it "Configs" or whatever, but it should probably be user-visible
(that is, without a prepended '.'), be standardized, and allow apps all the
space they want in their own folder under this root.
The good news about this idea is that, when completely ignored, nothing
breaks. We don't have nearly the pain that Windows suffered in trying to
get apps from 1995 to stop writing to their installation directory. Basic
Unix goodness: systems with multiple users that needed unique configs and
had no write permission to the app's directory removed the need to ever
shake out that painful problem. This is much less painful; if we wanted to
change where we write app data, and everything gets updated except that
Loki game from 1999, all your apps keep working well enough. Instead of
a technical problem, you are left with some apps that are just "badly behaved"
The other good news: we have the luxury of keeping things simple. I haven't
checked MSDN, but there seem to be several places where user config data
goes. Any could be correct, I suppose. There are system APIs for this, but
I swear I end up searching several folders with Explorer when I need to find
them. Mac OS X sort of overengineered something like I'm describing (and
there are still holy wars that match the vi vs. emacs thing about whether
your program should put crap in "~/Library/Application Support" or perhaps
"~/Library/Preferences" instead. A new solution can just pick one place.
And one last piece of good news: everything you care deeply about is open
source. All the legacy apps can be updated, leaving only a handful of
binary-only apps writing in your home directory, where they'll continue
To do this properly, though, we're going to have to fix a LOT of legacy code.
My proposal looks like this: add a library that tells apps where to store
config data. This could, in theory, be added to glibc, but for the sake of
compatibility with existing systems, it works better to make it external.
The library, in its entirety, looks like a less naïve version of this:
char *get_pref_path(const char *appname, char *buf, const size_t len)
if (snprintf(buf, len, "%s/Config/%s/", getenv("HOME"), appname) >= len)
This lets us offset localization issues to a system component, and
future-proofs us, in case we want to make this something else later
(hey, maybe Apple _was_ on to something with all those subdirs...).
And an app that wants to use it looks like this, but with error checking:
get_pref_path("MyApplicationName", buf, sizeof (buf));
strcat(buf, "Preferences"); /* yeah, yeah... */
FILE *io = fopen("Preferences", "rb");
/* now use (io) like you would if you opened ~/.appname, like before. */
Bonus points if you dlopen() the library and resort to ~/.appname if it
fails to load.
Existing apps would need to be updated, and there are a lot of patches to
be made, but the patch to any given app is easy enough.
Extra credit for wrapping legacy binary-only apps in something that catches
the open() call to the wrong file and redirects it, so Rune thinks
it is writing in the ~/.loki/rune directory, but in fact it's writing into
What do you think? Is this a silly idea?