Skip to content

Commit c008b11

Browse files
Piotr.Paczkowskikripken
authored andcommitted
Fix std::remove on folders #4440
1 parent 650d7b6 commit c008b11

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

src/library_fs.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,9 @@ mergeInto(LibraryManager.library, {
795795
var node = FS.lookupNode(parent, name);
796796
var err = FS.mayDelete(parent, name, false);
797797
if (err) {
798-
// POSIX says unlink should set EPERM, not EISDIR
799-
if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
798+
// According to POSIX, we should map EISDIR to EPERM, but
799+
// we instead do what Linux does (and we must, as we use
800+
// the musl linux libc).
800801
throw new FS.ErrnoError(err);
801802
}
802803
if (!parent.node_ops.unlink) {

tests/cstdio/test_remove.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include <assert.h>
2+
#include <errno.h>
3+
#include <cstdio>
4+
#include <iostream>
5+
#include <string.h>
6+
#include <unistd.h>
7+
#include <stdlib.h>
8+
#include <fcntl.h>
9+
#include <sys/stat.h>
10+
11+
void create_file(const char *path, const char *buffer, int mode) {
12+
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
13+
assert(fd >= 0);
14+
15+
int err = write(fd, buffer, sizeof(char) * strlen(buffer));
16+
assert(err == (sizeof(char) * strlen(buffer)));
17+
18+
close(fd);
19+
}
20+
21+
void setup() {
22+
create_file("file", "abcdef", 0777);
23+
mkdir("dir", 0777);
24+
create_file("dir/file", "abcdef", 0777);
25+
mkdir("dir/subdir", 0777);
26+
}
27+
28+
void cleanup() {
29+
// make sure we get it all regardless of anything failing
30+
unlink("file");
31+
unlink("dir/file");
32+
rmdir("dir/subdir");
33+
rmdir("dir");
34+
}
35+
36+
void test() {
37+
int err;
38+
39+
err = std::remove("dir/file");
40+
assert(!err);
41+
42+
err = std::remove("file");
43+
assert(!err);
44+
45+
// should fail, folder is not empty
46+
err = std::remove("dir");
47+
assert(err);
48+
49+
err = std::remove("dir/subdir");
50+
assert(!err);
51+
52+
err = std::remove("dir");
53+
assert(!err);
54+
55+
std::cout << "success";
56+
}
57+
58+
int main() {
59+
atexit(cleanup);
60+
setup();
61+
test();
62+
return EXIT_SUCCESS;
63+
}

tests/test_core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,10 @@ def test_rename(self):
17861786
src = open(path_from_root('tests', 'stdio', 'test_rename.c'), 'r').read()
17871787
self.do_run(src, 'success', force_c=True)
17881788

1789+
def test_remove(self):
1790+
src = open(path_from_root('tests', 'cstdio', 'test_remove.cpp'), 'r').read()
1791+
self.do_run(src, 'success')
1792+
17891793
def test_alloca_stack(self):
17901794
test_path = path_from_root('tests', 'core', 'test_alloca_stack')
17911795
src, output = (test_path + s for s in ('.in', '.out'))

tests/unistd/unlink.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ void test() {
7979

8080
err = unlink("dir-readonly");
8181
assert(err == -1);
82-
#ifdef __linux__
82+
83+
// emscripten uses 'musl' what is an implementation of the standard library for Linux-based systems
84+
#if defined(__linux__) || defined(__EMSCRIPTEN__)
8385
assert(errno == EISDIR);
8486
#else
8587
assert(errno == EPERM);

0 commit comments

Comments
 (0)