MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / __syscall_unlinkat

Function __syscall_unlinkat

system/lib/wasmfs/syscalls.cpp:813–870  ·  view source on GitHub ↗

TODO: Test this with non-AT_FDCWD values.

Source from the content-addressed store, hash-verified

811
812// TODO: Test this with non-AT_FDCWD values.
813int __syscall_unlinkat(int dirfd, const char* path, int flags) {
814 if (flags & ~AT_REMOVEDIR) {
815 // TODO: Test this case.
816 return -EINVAL;
817 }
818 // It is invalid for rmdir paths to end in ".", but we need to distinguish
819 // this case from the case of `parseParent` returning (root, '.') when parsing
820 // "/", so we need to find the invalid "/." manually.
821 if (flags == AT_REMOVEDIR) {
822 std::string_view p(path);
823 // Ignore trailing '/'.
824 while (!p.empty() && p.back() == '/') {
825 p.remove_suffix(1);
826 }
827 if (p.size() >= 2 && p.substr(p.size() - 2) == std::string_view("/.")) {
828 return -EINVAL;
829 }
830 }
831 auto parsed = path::parseParent(path, dirfd);
832 if (auto err = parsed.getError()) {
833 return err;
834 }
835 auto& [parent, childNameView] = parsed.getParentChild();
836 std::string childName(childNameView);
837 auto lockedParent = parent->locked();
838 auto file = lockedParent.getChild(childName);
839 if (!file) {
840 return -ENOENT;
841 }
842 // Disallow removing the root directory, even if it is empty.
843 if (file == wasmFS.getRootDirectory()) {
844 return -EBUSY;
845 }
846
847 auto lockedFile = file->locked();
848 if (auto dir = file->dynCast<Directory>()) {
849 if (flags != AT_REMOVEDIR) {
850 return -EISDIR;
851 }
852 // A directory can only be removed if it has no entries.
853 if (dir->locked().getNumEntries() > 0) {
854 return -ENOTEMPTY;
855 }
856 } else {
857 // A normal file or symlink.
858 if (flags == AT_REMOVEDIR) {
859 return -ENOTDIR;
860 }
861 }
862
863 // Cannot unlink/rmdir if the parent dir doesn't have write permissions.
864 if (!(lockedParent.getMode() & WASMFS_PERM_WRITE)) {
865 return -EACCES;
866 }
867
868 // Input is valid, perform the unlink.
869 return lockedParent.removeChild(childName);
870}

Callers 3

_wasmfs_rmdirFunction · 0.85
_wasmfs_unlinkFunction · 0.85
__syscall_rmdirFunction · 0.85

Calls 14

parseParentFunction · 0.85
remove_suffixMethod · 0.80
substrMethod · 0.80
getRootDirectoryMethod · 0.80
getModeMethod · 0.80
sizeMethod · 0.65
string_viewFunction · 0.50
emptyMethod · 0.45
backMethod · 0.45
getErrorMethod · 0.45
lockedMethod · 0.45
getChildMethod · 0.45

Tested by

no test coverage detected