mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
playlist, core_info: rename the temporary into place directly
filestream_rename() now replaces an existing destination on every target, keeping the file being replaced on disk until its replacement is in place, so the move-aside helpers each of these carried on top of it duplicate what the VFS already guarantees. Drop them and rename the completed temporary over its destination in one call.
This commit is contained in:
1 parent
4b10fa10a8
commit
20c99924db
2 files changed
+3
-79
No files matched your search
+1
-37
@@ -925,42 +925,6 @@ end:
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move a completed temporary over its destination.
|
||||
*
|
||||
* POSIX rename() replaces atomically, which is the whole point;
|
||||
* Windows' rename() refuses when the destination exists, so fall back
|
||||
* to moving the original aside first and putting it back if the second
|
||||
* move fails - never leaving nothing behind.
|
||||
*
|
||||
* (playlist.c carries the same helper for the same reason. A third
|
||||
* caller would justify hoisting one copy into libretro-common.) */
|
||||
static bool core_info_replace_file(const char *from, const char *to)
|
||||
{
|
||||
char saved[PATH_MAX_LENGTH];
|
||||
size_t _len;
|
||||
|
||||
if (filestream_rename(from, to) == 0)
|
||||
return true;
|
||||
|
||||
_len = strlcpy(saved, to, sizeof(saved));
|
||||
if (_len + STRLEN_CONST(".old") >= sizeof(saved))
|
||||
return false;
|
||||
strlcpy_lit(saved + _len, ".old", sizeof(saved) - _len);
|
||||
|
||||
filestream_delete(saved); /* a leftover from a previous run */
|
||||
if (filestream_rename(to, saved) != 0)
|
||||
return false; /* original untouched; give up */
|
||||
|
||||
if (filestream_rename(from, to) == 0)
|
||||
{
|
||||
filestream_delete(saved);
|
||||
return true;
|
||||
}
|
||||
|
||||
filestream_rename(saved, to); /* put the original back */
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool core_info_cache_write(core_info_cache_list_t *list, const char *info_dir)
|
||||
{
|
||||
intfstream_t *file = NULL;
|
||||
@@ -1296,7 +1260,7 @@ static bool core_info_cache_write(core_info_cache_list_t *list, const char *info
|
||||
free(file);
|
||||
file = NULL;
|
||||
|
||||
if (!core_info_replace_file(write_path, file_path))
|
||||
if (filestream_rename(write_path, file_path) != 0)
|
||||
{
|
||||
filestream_delete(write_path);
|
||||
RARCH_ERR("[Core info] Failed to write core info cache file: \"%s\".\n",
|
||||
|
||||
+2
-42
@@ -1946,7 +1946,6 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool playlist_replace_file(const char *from, const char *to);
|
||||
|
||||
void playlist_write_runtime_file(playlist_t *playlist)
|
||||
{
|
||||
@@ -2103,7 +2102,7 @@ end:
|
||||
/* Only now does the new content replace the old one. If anything
|
||||
* above failed, the temporary is discarded and what is on disk is
|
||||
* exactly what it was. */
|
||||
if (wrote_ok && playlist_replace_file(write_path, playlist->config.path))
|
||||
if (wrote_ok && filestream_rename(write_path, playlist->config.path) == 0)
|
||||
RARCH_DBG("[Playlist] Runtime written to file: \"%s\".\n",
|
||||
playlist->config.path);
|
||||
else
|
||||
@@ -2150,45 +2149,6 @@ static void playlist_cached_after_write(playlist_t *written)
|
||||
}
|
||||
}
|
||||
|
||||
/* Move @from onto @to, replacing whatever is there.
|
||||
*
|
||||
* POSIX rename() replaces atomically and that is the whole point of
|
||||
* this, so try it first and take the single-syscall path where it
|
||||
* works. Windows' rename() refuses when the destination exists, so
|
||||
* there the original is moved aside first: at every instant either the
|
||||
* destination or the saved copy is a complete file, and if the second
|
||||
* move fails the original is put back. A failure anywhere leaves the
|
||||
* existing playlist untouched, which is the outcome that matters. */
|
||||
static bool playlist_replace_file(const char *from, const char *to)
|
||||
{
|
||||
char saved[PATH_MAX_LENGTH];
|
||||
size_t _len;
|
||||
|
||||
if (filestream_rename(from, to) == 0)
|
||||
return true;
|
||||
|
||||
/* Either the destination exists and this platform will not replace
|
||||
* it, or the move itself failed. Try moving the original aside. */
|
||||
_len = strlcpy(saved, to, sizeof(saved));
|
||||
if (_len + STRLEN_CONST(".old") >= sizeof(saved))
|
||||
return false;
|
||||
strlcpy_lit(saved + _len, ".old", sizeof(saved) - _len);
|
||||
|
||||
filestream_delete(saved); /* a leftover from a previous run */
|
||||
if (filestream_rename(to, saved) != 0)
|
||||
return false; /* original untouched; give up */
|
||||
|
||||
if (filestream_rename(from, to) == 0)
|
||||
{
|
||||
filestream_delete(saved);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Put the original back rather than leave nothing behind. */
|
||||
filestream_rename(saved, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
void playlist_write_file(playlist_t *playlist)
|
||||
{
|
||||
size_t i, _len;
|
||||
@@ -2610,7 +2570,7 @@ end:
|
||||
/* Only now does the new content replace the old one. If anything
|
||||
* above failed, the temporary is discarded and the playlist on disk
|
||||
* is exactly what it was. */
|
||||
if (wrote_ok && playlist_replace_file(write_path, playlist->config.path))
|
||||
if (wrote_ok && filestream_rename(write_path, playlist->config.path) == 0)
|
||||
{
|
||||
RARCH_LOG("[Playlist] Written to file: \"%s\".\n",
|
||||
playlist->config.path);
|
||||
|
||||
Reference in new issue
Block a user