Commit ee9e916308e892888e310fd81ca0f8862e1a2069

Edward Thomson 2020-05-23T15:56:29

clar: remove files internally instead of /bin/rm Similar to how clar has used `/bin/cp` to copy files, it's used `/bin/rm` to remove them. This has similar deficiencies; meaning that leaks is noisy and it's slow. Move it to an internal function.

diff --git a/tests/clar/fs.h b/tests/clar/fs.h
index b683171..6c63a0d 100644
--- a/tests/clar/fs.h
+++ b/tests/clar/fs.h
@@ -455,19 +455,46 @@ fs_copy(const char *source, const char *_dest)
 }
 
 static void
-fs_rm(const char *source)
+fs_rmdir_helper(const char *path)
 {
-	char *argv[4];
+	DIR *dir;
+	struct dirent *d;
+
+	cl_assert_(dir = opendir(path), "Could not open dir");
+	while ((d = (errno = 0, readdir(dir))) != NULL) {
+		char *child;
 
-	argv[0] = "/bin/rm";
-	argv[1] = "-Rf";
-	argv[2] = (char *)source;
-	argv[3] = NULL;
+		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+			continue;
 
-	cl_must_pass_(
-		shell_out(argv),
-		"Failed to cleanup the sandbox"
-	);
+		child = joinpath(path, d->d_name, -1);
+		fs_rm(child);
+		free(child);
+	}
+
+	cl_assert_(errno == 0, "Failed to iterate source dir");
+	closedir(dir);
+
+	cl_must_pass_(rmdir(path), "Could not remove directory");
+}
+
+static void
+fs_rm(const char *path)
+{
+	struct stat st;
+
+	if (lstat(path, &st)) {
+		if (errno == ENOENT)
+			return;
+
+		cl_fail("Cannot copy; cannot stat destination");
+	}
+
+	if (S_ISDIR(st.st_mode)) {
+		fs_rmdir_helper(path);
+	} else {
+		cl_must_pass(unlink(path));
+	}
 }
 
 void