static dbus_bool_t _dbus_keyring_lock (DBusKeyring *keyring) { int n_timeouts; n_timeouts = 0; while (n_timeouts < MAX_LOCK_TIMEOUTS) { DBusError error; dbus_error_init (&error); if (_dbus_create_file_exclusively (&keyring->filename_lock, &error)) break; _dbus_verbose ("Did not get lock file, sleeping %d milliseconds (%s)\n", LOCK_TIMEOUT_MILLISECONDS, error.message); dbus_error_free (&error); _dbus_sleep_milliseconds (LOCK_TIMEOUT_MILLISECONDS); ++n_timeouts; } if (n_timeouts == MAX_LOCK_TIMEOUTS) { DBusError error; _dbus_verbose ("Lock file timed out %d times, assuming stale\n", n_timeouts); dbus_error_init (&error); if (!_dbus_delete_file (&keyring->filename_lock, &error)) { _dbus_verbose ("Couldn't delete old lock file: %s\n", error.message); dbus_error_free (&error); return FALSE; } if (!_dbus_create_file_exclusively (&keyring->filename_lock, &error)) { _dbus_verbose ("Couldn't create lock file after deleting stale one: %s\n", error.message); dbus_error_free (&error); return FALSE; } } return TRUE; }
static dbus_bool_t _dbus_create_uuid_file_exclusively (const DBusString *filename, DBusGUID *uuid, DBusError *error) { DBusString encoded; if (!_dbus_string_init (&encoded)) { _DBUS_SET_OOM (error); return FALSE; } _dbus_generate_uuid (uuid); if (!_dbus_uuid_encode (uuid, &encoded)) { _DBUS_SET_OOM (error); goto error; } /* FIXME this is racy; we need a save_file_exclusively * function. But in practice this should be fine for now. * * - first be sure we can create the file and it * doesn't exist by creating it empty with O_EXCL * - then create it by creating a temporary file and * overwriting atomically with rename() */ if (!_dbus_create_file_exclusively (filename, error)) goto error; if (!_dbus_string_append_byte (&encoded, '\n')) { _DBUS_SET_OOM (error); goto error; } if (!_dbus_string_save_to_file (&encoded, filename, error)) goto error; if (!_dbus_make_file_world_readable (filename, error)) goto error; _dbus_string_free (&encoded); _DBUS_ASSERT_ERROR_IS_CLEAR (error); return TRUE; error: _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_string_free (&encoded); return FALSE; }