浏览代码

base: faux_filesize() and test for it

Serj Kalichev 3 年之前
父节点
当前提交
fb1d860b5e
共有 5 个文件被更改,包括 128 次插入0 次删除
  1. 4 0
      faux/base/Makefile.am
  2. 51 0
      faux/base/fs.c
  3. 69 0
      faux/base/testc_base.c
  4. 1 0
      faux/faux.h
  5. 3 0
      faux/testc_module/testc_module.c

+ 4 - 0
faux/base/Makefile.am

@@ -2,3 +2,7 @@ libfaux_la_SOURCES += \
 	faux/base/mem.c \
 	faux/base/io.c \
 	faux/base/fs.c
+
+if TESTC
+libfaux_la_SOURCES += faux/base/testc_base.c
+endif

+ 51 - 0
faux/base/fs.c

@@ -16,6 +16,57 @@
 #include "faux/str.h"
 
 
+/** @brief Reports size of file or directory.
+ *
+ * Function works recursively so directory size is a sum of all file size
+ * inside it and size of subdirs.
+ *
+ * @param [in] path Filesystem path.
+ * @return Size of filesystem object or < 0 on error.
+ */
+ssize_t faux_filesize(const char *path)
+{
+	struct stat statbuf = {};
+	DIR *dir = NULL;
+	struct dirent *entry = NULL;
+	ssize_t sum = 0;
+
+	assert(path);
+	if (!path)
+		return -1;
+
+	if (stat(path, &statbuf) < 0)
+		return -1;
+
+	// Regular file
+	if (!S_ISDIR(statbuf.st_mode))
+		return statbuf.st_size;
+
+	// Directory
+	dir = opendir(path);
+	if (!dir)
+		return -1;
+	// Get each file from 'path' directory
+	for (entry = readdir(dir); entry; entry = readdir(dir)) {
+		char *fn = NULL;
+		ssize_t r = 0;
+		// Ignore "." and ".."
+		if ((faux_str_casecmp(entry->d_name, ".") == 0) ||
+			(faux_str_casecmp(entry->d_name, "..") == 0))
+			continue;
+		// Construct filename
+		fn = faux_str_sprintf("%s/%s", path, entry->d_name);
+		r = faux_filesize(fn);
+		faux_str_free(fn);
+		if (r < 0)
+			continue;
+		sum += r;
+	}
+
+	return sum;
+}
+
+
 /** @brief If given path is directory.
  *
  * @param [in] path Filesystem path.

+ 69 - 0
faux/base/testc_base.c

@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "faux/faux.h"
+#include "faux/str.h"
+#include "faux/testc_helpers.h"
+
+
+int testc_faux_filesize(void)
+{
+	const char *dirname = "subdir";
+	const char *basedir = getenv(FAUX_TESTC_TMPDIR_ENV);
+	const char *fd1 = "asdfghjkl"; // 9 bytes
+	const char *fd2 = "asdfghjklzxcvbnm"; // 16 bytes
+	const char *fd3 = "asdfghjklzxcvbnmqwertyuiop"; // 26 bytes
+	ssize_t r = 0;
+	ssize_t etalon_filesize = 0;
+	int ret = -1; // Pessimistic
+	char *fn1 = NULL;
+	char *dn1 = NULL;
+	char *fn2 = NULL;
+	char *fn3 = NULL;
+
+	// Prepare filenames
+	fn1 = faux_str_sprintf("%s/f1", basedir);
+	dn1 = faux_str_sprintf("%s/%s", basedir, dirname);
+	fn2 = faux_str_sprintf("%s/f2", dn1);
+	fn3 = faux_str_sprintf("%s/f3", dn1);
+
+	// Create files and dirs
+	mkdir(dn1, 0777);
+	if ((r = faux_testc_file_deploy(fn1, fd1)) < 0)
+		goto err;
+	etalon_filesize += r;
+	if ((r = faux_testc_file_deploy(fn2, fd2)) < 0)
+		goto err;
+	etalon_filesize += r;
+	if ((r = faux_testc_file_deploy(fn3, fd3)) < 0)
+		goto err;
+	etalon_filesize += r;
+
+	// Debug
+	printf("Dir: %s\n", basedir);
+	printf("File: %s\n", fn1);
+
+	// Get filesize
+	if ((ssize_t)strlen(fd1) != faux_filesize(fn1)) {
+		printf("Wrong filesize (%ld %ld)\n",
+			strlen(fd1), faux_filesize(fn1));
+		goto err;
+	}
+	if (etalon_filesize != faux_filesize(basedir)) {
+		printf("Wrong dirsize (%ld %ld)\n",
+			etalon_filesize, faux_filesize(basedir));
+		goto err;
+	}
+
+	ret = 0;
+err:
+	faux_str_free(fn1);
+	faux_str_free(dn1);
+	faux_str_free(fn2);
+	faux_str_free(fn3);
+
+	return ret;
+}

+ 1 - 0
faux/faux.h

@@ -85,6 +85,7 @@ ssize_t faux_write_block(int fd, const void *buf, size_t n);
 size_t faux_read_block(int fd, void *buf, size_t n);
 
 // Filesystem
+ssize_t faux_filesize(const char *path);
 bool_t faux_isdir(const char *path);
 int faux_rm(const char *path);
 char *faux_expand_tilde(const char *path);

+ 3 - 0
faux/testc_module/testc_module.c

@@ -10,6 +10,9 @@ const char *testc_module[][2] = {
 //	{"testc_faux_ini_signal", "Interrupted by signal"}, // demo
 //	{"testc_faux_ini_good", "INI subsystem good"}, // demo
 
+	// base
+	{"testc_faux_filesize", "Get size of filesystem object"},
+
 	// str
 	{"testc_faux_str_nextword", "Find next word (quotation)"},