summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Lebon <jonathan@jlebon.com>2023-04-13 17:22:42 -0400
committerJonathan Lebon <jonathan@jlebon.com>2023-04-14 09:57:16 -0400
commit462d413d2e8ef4e8196ac99c142dd165086f7b69 (patch)
tree530ad90a1105d98ea94d8067268f54a6544aae5a
parenta0681cd20190d96311738e50334426f218d96214 (diff)
downloadostree-462d413d2e8ef4e8196ac99c142dd165086f7b69.tar.gz
libotutil: add utility functions for calculating directory size
Prep for future patch.
-rw-r--r--src/libotutil/ot-fs-utils.c44
-rw-r--r--src/libotutil/ot-fs-utils.h7
2 files changed, 51 insertions, 0 deletions
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index 64ebc966..935b1bbc 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -245,3 +245,47 @@ ot_parse_file_by_line (const char *path,
return TRUE;
}
+
+/* Calculate the size of the files contained in a directory. Symlinks are not
+ * followed. */
+gboolean
+ot_get_dir_size (int dfd,
+ const char *path,
+ guint64 *out_size,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error))
+ return FALSE;
+
+ *out_size = 0;
+ while (TRUE)
+ {
+ struct dirent *dent;
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+
+ if (dent == NULL)
+ break;
+
+ if (dent->d_type == DT_REG)
+ {
+ struct stat stbuf;
+ if (!glnx_fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error))
+ return FALSE;
+
+ *out_size += stbuf.st_size;
+ }
+ else if (dent->d_type == DT_DIR)
+ {
+ guint64 subdir_size;
+ if (!ot_get_dir_size (dfd_iter.fd, dent->d_name, &subdir_size, cancellable, error))
+ return FALSE;
+
+ *out_size += subdir_size;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h
index fad4c53d..f719381d 100644
--- a/src/libotutil/ot-fs-utils.h
+++ b/src/libotutil/ot-fs-utils.h
@@ -95,4 +95,11 @@ ot_parse_file_by_line (const char *path,
GCancellable *cancellable,
GError **error);
+gboolean
+ot_get_dir_size (int dfd,
+ const char *path,
+ guint64 *out_size,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS