From: Waldemar Kozaczuk <[email protected]> Committer: Waldemar Kozaczuk <[email protected]> Branch: master
unlinkat: fill the gaps in the implementation V2: The implementation uses vfs_fun_at2() instead of vfs_fun_at() to further simplify code. We also expose unlinkat though syscall. This patch enhances the unlinkat() implementation to handle the AT_FDCWD dirfd and AT_REMOVEDIR flags. We also enhance tst-remove.cc to test unlinkat. #Refs 1188 Signed-off-by: Waldemar Kozaczuk <[email protected]> --- diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc --- a/fs/vfs/main.cc +++ b/fs/vfs/main.cc @@ -1164,11 +1164,13 @@ int unlink(const char *pathname) OSV_LIBC_API int unlinkat(int dirfd, const char *pathname, int flags) { - //TODO: Really implement it - if (dirfd != AT_FDCWD || flags) { - UNIMPLEMENTED("unlinkat() with non-zero flags or dirfd != AT_FDCWD"); - } - return unlink(pathname); + return vfs_fun_at2(dirfd, pathname, [flags](const char *path) { + if (flags & AT_REMOVEDIR) { + return rmdir(path); + } else { + return unlink(path); + } + }); } TRACEPOINT(trace_vfs_stat, "\"%s\" %p", const char*, struct stat*); diff --git a/linux.cc b/linux.cc --- a/linux.cc +++ b/linux.cc @@ -495,6 +495,7 @@ OSV_LIBC_API long syscall(long number, ...) SYSCALL0(getuid); SYSCALL3(lseek, int, off_t, int); SYSCALL2(statfs, const char *, struct statfs *); + SYSCALL3(unlinkat, int, const char *, int); } debug_always("syscall(): unimplemented system call %d\n", number); diff --git a/tests/tst-remove.cc b/tests/tst-remove.cc --- a/tests/tst-remove.cc +++ b/tests/tst-remove.cc @@ -42,6 +42,8 @@ bool do_expect(T actual, T expected, const char *actuals, const char *expecteds, int main(int argc, char **argv) { expect(mkdir("/tmp/tst-remove", 0777), 0); + auto tst_remove_dir = open("/tmp/tst-remove", O_DIRECTORY); + expect(tst_remove_dir != -1, true); /********* test unlink() **************/ // unlink() non-existant file returns ENOENT @@ -79,12 +81,24 @@ int main(int argc, char **argv) expect_errno(rmdir("/tmp/tst-remove/f"), ENOTDIR); expect(unlink("/tmp/tst-remove/f"), 0); - /********* test remove() ***************/ - // TODO... + /********* test unlinkat() ***************/ + expect(mknod("/tmp/tst-remove/u", 0777|S_IFREG, 0), 0); + expect(unlinkat(tst_remove_dir, "u", 0), 0); + expect(mknod("/tmp/tst-remove/u2", 0777|S_IFREG, 0), 0); + expect(chdir("/tmp/tst-remove"), 0); + expect(unlinkat(AT_FDCWD, "u2", 0), 0); + + expect(mkdir("/tmp/tst-remove/ud", 0777), 0); + expect(unlinkat(tst_remove_dir, "ud", AT_REMOVEDIR), 0); + + expect(mkdir("/tmp/tst-remove/ud2", 0777), 0); + expect(chdir("/tmp/tst-remove"), 0); + expect(unlinkat(AT_FDCWD, "ud2", AT_REMOVEDIR), 0); // Finally remove the temporary directory (assumes the above left // nothing in it) + expect(close(tst_remove_dir), 0); expect(rmdir("/tmp/tst-remove"), 0); -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000fd635705dfffc5c9%40google.com.
