This is pretty much blatantly stolen from glib 2.0, with a few tweaks
to make it build (including getting rid of a bunch of functions we
weren't using that use GError).
