Skip to content

Commit b7df3e5

Browse files
committed
extmod/vfs_fat: Implement POSIX behaviour of rename, allow to overwrite.
If the destination of os.rename() exists then it will be overwritten if it is a file. This is the POSIX behaviour, which is also the CPython behaviour, and so we follow suit. See issue adafruit#2598 for discussion.
1 parent 08bd7d1 commit b7df3e5

3 files changed

Lines changed: 16 additions & 0 deletions

File tree

extmod/vfs_fat.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
121121
const char *old_path = mp_obj_str_get_str(path_in);
122122
const char *new_path = mp_obj_str_get_str(path_out);
123123
FRESULT res = f_rename(old_path, new_path);
124+
if (res == FR_EXIST) {
125+
// if new_path exists then try removing it (but only if it's a file)
126+
fat_vfs_remove_internal(path_out, 0); // 0 == file attribute
127+
// try to rename again
128+
res = f_rename(old_path, new_path);
129+
}
124130
if (res == FR_OK) {
125131
return mp_const_none;
126132
} else {

tests/extmod/vfs_fat_fileio.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ def ioctl(self, op, arg):
140140
vfs.rename("foo_dir/file.txt", "moved-to-root.txt")
141141
print(vfs.listdir())
142142

143+
# check that renaming to existing file will overwrite it
144+
with vfs.open("temp", "w") as f:
145+
f.write("new text")
146+
vfs.rename("temp", "moved-to-root.txt")
147+
print(vfs.listdir())
148+
with vfs.open("moved-to-root.txt") as f:
149+
print(f.read())
150+
143151
# valid removes
144152
vfs.remove("foo_dir/sub_file.txt")
145153
vfs.remove("foo_file.txt")

tests/extmod/vfs_fat_fileio.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ b'data in file'
1818
True
1919
['sub_file.txt', 'file.txt']
2020
['foo_file.txt', 'foo_dir', 'moved-to-root.txt']
21+
['foo_file.txt', 'foo_dir', 'moved-to-root.txt']
22+
new text
2123
['moved-to-root.txt']
2224
ENOSPC: True

0 commit comments

Comments
 (0)