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.
Signed-off-by: Waldemar Kozaczuk <
jwkoz...@gmail.com>
---
fs/vfs/main.cc | 18 ++++++++++++++----
tests/tst-remove.cc | 18 ++++++++++++++++--
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
index a72042b2..4f0ce463 100644
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -1154,11 +1154,21 @@ 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");
+ if (pathname[0] == '/' || dirfd == AT_FDCWD) {
+ if (flags & AT_REMOVEDIR) {
+ return rmdir(pathname);
+ } else {
+ return unlink(pathname);
+ }
}
- return unlink(pathname);
+
+ return vfs_fun_at(dirfd, pathname, [flags](const char *absolute_path) {
+ if (flags & AT_REMOVEDIR) {
+ return rmdir(absolute_path);
+ } else {
+ return unlink(absolute_path);
+ }
+ });
}
TRACEPOINT(trace_vfs_stat, "\"%s\" %p", const char*, struct stat*);
diff --git a/tests/tst-remove.cc b/tests/tst-remove.cc
index 6851cba0..fdf4037d 100644
--- 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);
--
2.34.1