-/* Tries to remove the current directory.
- This is allowed to succeed or fail.
- Then creates a file in the root to make sure that we haven't
- corrupted any directory state. */
+/* Tries to remove the current directory, which may succeed or
+ fail. The requirements in each case are different; refer to
+ the assignment for details. */
#include <syscall.h>
#include "tests/lib.h"
#include "tests/main.h"
+static int
+wrap_open (const char *name)
+{
+ static int fds[8], fd_cnt;
+ int fd, i;
+
+ CHECK ((fd = open (name)) > 1, "open \"%s\"", name);
+ for (i = 0; i < fd_cnt; i++)
+ if (fds[i] == fd)
+ fail ("fd returned is not unique");
+ fds[fd_cnt++] = fd;
+ return fd;
+}
+
void
test_main (void)
{
+ int root_fd, a_fd0;
+ char name[READDIR_MAX_LEN + 1];
+
+ root_fd = wrap_open ("/");
CHECK (mkdir ("a"), "mkdir \"a\"");
+
+ a_fd0 = wrap_open ("/a");
+ CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty");
+ CHECK (inumber (root_fd) != inumber (a_fd0),
+ "\"/\" and \"/a\" must have different inumbers");
+
CHECK (chdir ("a"), "chdir \"a\"");
- msg ("remove \"/a\" (must not crash)");
- remove ("/a");
- msg ("create \"b\" (must not crash)");
- create ("b", 123);
+
+ msg ("try to remove \"/a\"");
+ if (remove ("/a"))
+ {
+ msg ("remove successful");
+
+ CHECK (open ("/a") == -1, "open \"/a\" (must fail)");
+ CHECK (open (".") == -1, "open \".\" (must fail)");
+ CHECK (open ("..") == -1, "open \"..\" (must fail)");
+ CHECK (!create ("x", 512), "create \"x\" (must fail)");
+ }
+ else
+ {
+ int a_fd1, a_fd2, a_fd3;
+
+ msg ("remove failed");
+
+ CHECK (!remove ("../a"), "try to remove \"../a\" (must fail)");
+ CHECK (!remove (".././a"), "try to remove \".././a\" (must fail)");
+ CHECK (!remove ("/./a"), "try to remove \"/./a\" (must fail)");
+
+ a_fd1 = wrap_open ("/a");
+ a_fd2 = wrap_open (".");
+ CHECK (inumber (a_fd1) == inumber (a_fd2),
+ "\"/a\" and \".\" must have same inumber");
+ CHECK (inumber (root_fd) != inumber (a_fd1),
+ "\"/\" and \"/a\" must have different inumbers");
+
+ CHECK (chdir ("/a"), "chdir \"/a\"");
+ a_fd3 = wrap_open (".");
+ CHECK (inumber (a_fd3) == inumber (a_fd1),
+ "\".\" must have same inumber as before");
+
+ CHECK (chdir ("/"), "chdir \"/\"");
+ CHECK (!remove ("a"), "try to remove \"a\" (must fail: still open)");
+ }
+ CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty");
}