Skip to content

Commit 9a54975

Browse files
committed
Fix renaming a file on top of an existing file in memfs and nodefs
1 parent 81b7179 commit 9a54975

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

src/library_memfs.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ addToLibrary({
193193
},
194194
rename(old_node, new_dir, new_name) {
195195
// if we're overwriting a directory at new_name, make sure it's empty.
196+
var new_node;
196197
if (FS.isDir(old_node.mode)) {
197-
var new_node;
198198
try {
199199
new_node = FS.lookupNode(new_dir, new_name);
200200
} catch (e) {
@@ -205,6 +205,10 @@ addToLibrary({
205205
}
206206
}
207207
}
208+
try {
209+
new_node = FS.lookupNode(new_dir, new_name);
210+
FS.hashRemoveNode(new_node);
211+
} catch (e) {}
208212
// do the internal rewiring
209213
delete old_node.parent.contents[old_node.name];
210214
old_node.parent.timestamp = Date.now()

src/library_nodefs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ addToLibrary({
196196
rename(oldNode, newDir, newName) {
197197
var oldPath = NODEFS.realPath(oldNode);
198198
var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
199+
try {
200+
FS.unlink(newPath);
201+
} catch(e) {}
199202
NODEFS.tryFSOperation(() => fs.renameSync(oldPath, newPath));
200203
oldNode.name = newName;
201204
},

test/fs/test_rename_on_existing.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <assert.h>
4+
#include <fcntl.h>
5+
#include <string.h>
6+
#include <sys/stat.h>
7+
#include <assert.h>
8+
#include <errno.h>
9+
#include <string.h>
10+
11+
12+
#if defined(__EMSCRIPTEN__)
13+
#include <emscripten.h>
14+
#endif
15+
16+
void makedir(const char *dir) {
17+
int rtn = mkdir(dir, 0777);
18+
assert(rtn == 0);
19+
}
20+
21+
void changedir(const char *dir) {
22+
int rtn = chdir(dir);
23+
assert(rtn == 0);
24+
}
25+
26+
static void create_file(const char *path, const char *buffer) {
27+
printf("creating: %s\n", path);
28+
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666);
29+
printf("error: %s\n", strerror(errno));
30+
assert(fd >= 0);
31+
32+
int err = write(fd, buffer, sizeof(char) * strlen(buffer));
33+
assert(err == (sizeof(char) * strlen(buffer)));
34+
35+
close(fd);
36+
}
37+
38+
39+
void setup() {
40+
makedir("working");
41+
#if defined(__EMSCRIPTEN__) && defined(NODEFS)
42+
EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working'));
43+
#endif
44+
changedir("working");
45+
}
46+
47+
int main() {
48+
setup();
49+
create_file("a", "abc");
50+
create_file("b", "xyz");
51+
assert(rename("a", "b") == 0);
52+
assert(unlink("b") == 0);
53+
create_file("b", "xyz");
54+
printf("success\n");
55+
}

test/test_core.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5935,6 +5935,16 @@ def test_fs_64bit(self):
59355935
self.set_setting('FORCE_FILESYSTEM')
59365936
self.do_runf('fs/test_64bit.c', 'success')
59375937

5938+
@parameterized({
5939+
'': ([],),
5940+
'nodefs': (['-DNODEFS', '-lnodefs.js'],),
5941+
'noderawfs': (['-sNODERAWFS'],)
5942+
})
5943+
def test_fs_rename_on_existing(self, args):
5944+
if self.get_setting('WASMFS'):
5945+
self.set_setting('FORCE_FILESYSTEM')
5946+
self.do_runf('fs/test_rename_on_existing.c', 'success', emcc_args=args)
5947+
59385948
def test_sigalrm(self):
59395949
self.do_runf('test_sigalrm.c', 'Received alarm!')
59405950
self.set_setting('EXIT_RUNTIME')

0 commit comments

Comments
 (0)