diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-04-13 21:39:54 +0100 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2009-04-13 21:39:54 +0100 |
commit | d2d49b41bb8e8bf3d00b79e9e22ea68bb803c67c (patch) | |
tree | 5493d6b7694e7408f6c4fa86ad3e721d2730ba43 | |
parent | 27f977bbfde5a35481e9e564864fdf4cff27807d (diff) | |
download | xine-lib-d2d49b41bb8e8bf3d00b79e9e22ea68bb803c67c.tar.gz xine-lib-d2d49b41bb8e8bf3d00b79e9e22ea68bb803c67c.tar.bz2 |
When writing catalog.cache, use a new file & atomically replace the old one.
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | src/xine-engine/load_plugins.c | 27 |
2 files changed, 26 insertions, 3 deletions
@@ -5,6 +5,8 @@ xine-lib (1.1.17) 2009-??-?? * Fix a resource leak in libdvdnav. * Properly NUL-terminate when reading ID3v2.2 tag content. * Fix handling of the length of UTF-16 content sourced from, e.g., ID3 tags. + * Make ~/.xine/catalog.cache writing safer: write a new file & atomically + replace the old one. xine-lib (1.1.16.3) 2009-04-03 * Security fixes: diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 30bf58e6c..5128644da 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -1062,20 +1062,21 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) { static void save_catalog (xine_t *this) { FILE *fp; - char *cachefile, *dirfile; + char *cachefile, *cachefile_new, *dirfile; const char *relname = CACHE_CATALOG_FILE; const char *dirname = CACHE_CATALOG_DIR; const char *const homedir = xine_get_homedir(); asprintf(&cachefile, "%s/%s", homedir, relname); + asprintf(&cachefile_new, "%s.new", cachefile); /* make sure homedir (~/.xine) exists */ asprintf(&dirfile, "%s/%s", homedir, dirname); mkdir (dirfile, 0755); free (dirfile); - if( (fp = fopen(cachefile,"w")) != NULL ) { + if( (fp = fopen(cachefile_new,"w")) != NULL ) { int i; fprintf(fp, "# this file is automatically created by xine, do not edit.\n\n"); @@ -1084,9 +1085,29 @@ static void save_catalog (xine_t *this) { for (i = 0; i < PLUGIN_TYPE_MAX; i++) { save_plugin_list (fp, this->plugin_catalog->plugin_lists[i]); } - fclose(fp); + if (fclose(fp)) + { + const char *err = strerror (errno); + xine_log (this, XINE_LOG_MSG, + _("failed to save catalogue cache: %s\n"), err); + goto do_unlink; + } + else if (rename (cachefile_new, cachefile)) + { + const char *err = strerror (errno); + xine_log (this, XINE_LOG_MSG, + _("failed to replace catalogue cache: %s\n"), err); + do_unlink: + if (unlink (cachefile_new) && errno != ENOENT) + { + err = strerror (errno); + xine_log (this, XINE_LOG_MSG, + _("failed to remove new catalogue cache: %s\n"), err); + } + } } free(cachefile); + free(cachefile_new); } /* |