libotutil: add utility functions for calculating directory size
authorJonathan Lebon <jonathan@jlebon.com>
Thu, 13 Apr 2023 21:22:42 +0000 (17:22 -0400)
committerJonathan Lebon <jonathan@jlebon.com>
Fri, 14 Apr 2023 13:57:16 +0000 (09:57 -0400)
Prep for future patch.

src/libotutil/ot-fs-utils.c
src/libotutil/ot-fs-utils.h

index 64ebc966052f3c6db933250fcf891b4ed49debb3..935b1bbc9eae218c036901ab6e99cd26627aeb9f 100644 (file)
@@ -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;
+}
index fad4c53d635302e754bbb16ee266e8bd17236256..f719381d0ffb5efb45daf80c735e8833c1ae937a 100644 (file)
@@ -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