diff options
| author | 2020-05-19 22:00:18 -0700 | |
|---|---|---|
| committer | 2020-05-20 12:08:41 -0700 | |
| commit | cf2ee87fd43aaacd8e952fc9bc116fd27f2d8eb7 (patch) | |
| tree | 059a5d85c1ca664cede60237723ffcc5717c090c | |
| parent | 25adf3c4718092df863d3173c5066f705a04ce49 (diff) | |
Maintain compatibility by deleting target directory before renaming into it.
The target shouldn't be a directory, but if it is, it would be
deleted (as long as it's empty). This became some kind of API and we
need to remain compatible with it.
Bug: 151959443
Test: Reboot and ensure ShortcutService can persist its state
Change-Id: I11a80cd4252128b025912b7aab86b113935e549a
Merged-In: I11a80cd4252128b025912b7aab86b113935e549a
| -rw-r--r-- | core/java/android/util/AtomicFile.java | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java index 1dd4cbb403db..4d2c9b5f5df7 100644 --- a/core/java/android/util/AtomicFile.java +++ b/core/java/android/util/AtomicFile.java @@ -116,10 +116,7 @@ public class AtomicFile { mStartTime = startTime; if (mLegacyBackupName.exists()) { - if (!mLegacyBackupName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName - + " to base file " + mBaseName); - } + rename(mLegacyBackupName, mBaseName); } try { @@ -157,9 +154,7 @@ public class AtomicFile { } catch (IOException e) { Log.e(LOG_TAG, "Failed to close file output stream", e); } - if (!mNewName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename new file " + mNewName + " to base file " + mBaseName); - } + rename(mNewName, mBaseName); if (mCommitTag != null) { com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( mCommitTag, SystemClock.uptimeMillis() - mStartTime); @@ -221,10 +216,7 @@ public class AtomicFile { */ public FileInputStream openRead() throws FileNotFoundException { if (mLegacyBackupName.exists()) { - if (!mLegacyBackupName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName - + " to base file " + mBaseName); - } + rename(mLegacyBackupName, mBaseName); } // Don't delete mNewName here - it was okay to call openRead() between startWrite() and @@ -301,4 +293,21 @@ public class AtomicFile { IoUtils.closeQuietly(out); } } + + private static void rename(File source, File target) { + // We used to delete the target file before rename, but that isn't atomic, and the rename() + // syscall should atomically replace the target file. However in the case where the target + // file is a directory, a simple rename() won't work. We need to delete the file in this + // case because there are callers who erroneously called mBaseName.mkdirs() (instead of + // mBaseName.getParentFile().mkdirs()) before creating the AtomicFile, and it worked + // regardless, so this deletion became some kind of API. + if (target.isDirectory()) { + if (!target.delete()) { + Log.e(LOG_TAG, "Failed to delete file which is a directory " + target); + } + } + if (!source.renameTo(target)) { + Log.e(LOG_TAG, "Failed to rename " + source + " to " + target); + } + } } |