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

Function __syscall_renameat

system/lib/wasmfs/syscalls.cpp:977–1079  ·  view source on GitHub ↗

TODO: Test this with non-AT_FDCWD values.

Source from the content-addressed store, hash-verified

975
976// TODO: Test this with non-AT_FDCWD values.
977int __syscall_renameat(int olddirfd,
978 const char* oldpath,
979 int newdirfd,
980 const char* newpath) {
981 // Rename is the only syscall that needs to (or is allowed to) acquire locks
982 // on two directories at once. It requires locks on both the old and new
983 // parent directories to ensure that the moved file can be atomically removed
984 // from the old directory and added to the new directory without something
985 // changing that would prevent the move.
986 //
987 // To prevent deadlock in the case of simultaneous renames, serialize renames
988 // with an additional global lock.
989 static std::mutex renameMutex;
990 std::lock_guard<std::mutex> renameLock(renameMutex);
991
992 // Get the old directory.
993 auto parsedOld = path::parseParent(oldpath, olddirfd);
994 if (auto err = parsedOld.getError()) {
995 return err;
996 }
997 auto& [oldParent, oldFileNameView] = parsedOld.getParentChild();
998 std::string oldFileName(oldFileNameView);
999
1000 // Get the new directory.
1001 auto parsedNew = path::parseParent(newpath, newdirfd);
1002 if (auto err = parsedNew.getError()) {
1003 return err;
1004 }
1005 auto& [newParent, newFileNameView] = parsedNew.getParentChild();
1006 std::string newFileName(newFileNameView);
1007
1008 if (newFileNameView.size() > WASMFS_NAME_MAX) {
1009 return -ENAMETOOLONG;
1010 }
1011
1012 // Lock both directories.
1013 auto lockedOldParent = oldParent->locked();
1014 auto lockedNewParent = newParent->locked();
1015
1016 // Get the source and destination files.
1017 auto oldFile = lockedOldParent.getChild(oldFileName);
1018 auto newFile = lockedNewParent.getChild(newFileName);
1019
1020 if (!oldFile) {
1021 return -ENOENT;
1022 }
1023
1024 // If the source and destination are the same, do nothing.
1025 if (oldFile == newFile) {
1026 return 0;
1027 }
1028
1029 // Never allow renaming or overwriting the root.
1030 auto root = wasmFS.getRootDirectory();
1031 if (oldFile == root || newFile == root) {
1032 return -EBUSY;
1033 }
1034

Callers 2

libsyscall.jsFile · 0.85
_wasmfs_renameFunction · 0.85

Calls 12

parseParentFunction · 0.85
getRootDirectoryMethod · 0.80
getModeMethod · 0.80
getBackendMethod · 0.80
getParentMethod · 0.80
sizeMethod · 0.65
assertFunction · 0.50
getErrorMethod · 0.45
lockedMethod · 0.45
getChildMethod · 0.45
getNumEntriesMethod · 0.45
insertMoveMethod · 0.45

Tested by

no test coverage detected