From fe94d6cf89643bc2874e5b1e24800f4cdfaecc6e Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 5 Aug 2024 20:16:05 +0300 Subject: [PATCH] LibC: Implement dummy rename() so vim can save files vim calls rename when saving a file. This patch adds dummy implementation that only works for regular files and does a copy instead of proper rename. --- userspace/libraries/LibC/stdio.cpp | 50 ++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/userspace/libraries/LibC/stdio.cpp b/userspace/libraries/LibC/stdio.cpp index 452c93a2bb..ed562a51db 100644 --- a/userspace/libraries/LibC/stdio.cpp +++ b/userspace/libraries/LibC/stdio.cpp @@ -604,11 +604,55 @@ int remove(const char* path) return unlink(path); } -// TODO int rename(const char* old, const char* _new) { - dwarnln("rename({}, {})", old, _new); - ASSERT_NOT_REACHED(); + struct stat st; + if (lstat(old, &st) == -1) + return -1; + + if (!S_ISREG(st.st_mode)) + { + errno = ENOTSUP; + return -1; + } + + if (unlink(_new) == -1 && errno != ENOENT) + return -1; + + int old_fd = open(old, O_RDWR); + int new_fd = open(_new, O_RDWR | O_CREAT | O_EXCL, st.st_mode); + if (old_fd == -1 || new_fd == -1) + goto error; + + for (;;) + { + char buffer[512]; + ssize_t nread = read(old_fd, buffer, sizeof(buffer)); + if (nread == -1) + { + unlink(_new); + goto error; + } + if (nread == 0) + break; + + if (write(new_fd, buffer, nread) != nread) + { + unlink(_new); + goto error; + } + } + + unlink(old); + + return 0; + +error: + if (old_fd != -1) + close(old_fd); + if (new_fd != -1) + close(new_fd); + return -1; } void rewind(FILE* file)