From aa623f82b2866aee0d87803fe9a3d097b09f4a49 Mon Sep 17 00:00:00 2001
From: Luis Gerhorst <privat@luisgerhorst.de>
Date: Tue, 13 Jul 2021 20:55:36 +0200
Subject: [PATCH] task_find: summarize disk usage
---
src/task_find.c | 81 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 58 insertions(+), 23 deletions(-)
diff --git a/src/task_find.c b/src/task_find.c
index 883e064..c553a87 100644
--- a/src/task_find.c
+++ b/src/task_find.c
@@ -234,9 +234,15 @@ struct linux_dirent64 {
/* Same as in GNU find. */
#define BUF_SIZE (32*1024)
+enum action {
+ SUMMARIZE_DISK_USAGE = 1,
+ PRINT_LIBC = 1 << 1,
+ PRINT_MATCHES = 1 << 2,
+};
+
static int do_user_find(unsigned char d_type, int parent_dfd, const char *name,
const char *search_name, int search_type, bool debug,
- bool print_libc) {
+ int flags, size_t *disk_usage_total) {
int err = 0;
size_t namelen = strlen(name);
@@ -247,11 +253,24 @@ static int do_user_find(unsigned char d_type, int parent_dfd, const char *name,
bool match = (search_type != -1 && d_type == search_type)
|| (search_name != NULL && strcmp(search_name, name) == 0);
if (match) {
- if (print_libc) {
- printf("%s\n", name);
- } else {
- write(STDOUT_FILENO, name, namelen);
- write(STDOUT_FILENO, "\n", 1);
+ if (flags & PRINT_MATCHES) {
+ if (flags & PRINT_LIBC) {
+ printf("%s\n", name);
+ } else {
+ write(STDOUT_FILENO, name, namelen);
+ write(STDOUT_FILENO, "\n", 1);
+ }
+ }
+
+ if (d_type == DT_REG &&
+ flags & SUMMARIZE_DISK_USAGE) {
+ struct stat statbuf;
+ err = fstatat(parent_dfd, name, &statbuf, 0);
+ if (err) {
+ perror("fstatat");
+ exit(EXIT_FAILURE);
+ }
+ *disk_usage_total += statbuf.st_size;
}
}
@@ -265,11 +284,13 @@ static int do_user_find(unsigned char d_type, int parent_dfd, const char *name,
return 0;
}
- if (print_libc) {
- printf("%s/\n", name);
- } else {
- write(STDOUT_FILENO, name, namelen);
- write(STDOUT_FILENO, "/\n", 2);
+ if (flags & PRINT_MATCHES) {
+ if (flags & PRINT_LIBC) {
+ printf("%s/\n", name);
+ } else {
+ write(STDOUT_FILENO, name, namelen);
+ write(STDOUT_FILENO, "/\n", 2);
+ }
}
while (true) {
@@ -286,7 +307,7 @@ static int do_user_find(unsigned char d_type, int parent_dfd, const char *name,
for (int bpos = 0; bpos < nread;) {
struct linux_dirent64 *d = (struct linux_dirent64 *) (buf + bpos);
err = do_user_find(d->d_type, dfd, d->d_name, search_name, search_type,
- debug, print_libc);
+ debug, flags, disk_usage_total);
if (err) {
goto close;
}
@@ -295,25 +316,33 @@ static int do_user_find(unsigned char d_type, int parent_dfd, const char *name,
}
close:
- if (print_libc) {
- printf("..\n");
- } else {
- write(STDOUT_FILENO, "..\n", 3);
+ if (flags & PRINT_MATCHES) {
+ if (flags & PRINT_LIBC) {
+ printf("..\n");
+ } else {
+ write(STDOUT_FILENO, "..\n", 3);
+ }
}
close(dfd);
return err;
}
static int user_find(const char *path, const char *search_name,
- bool debug, int search_type, bool print_libc) {
- return do_user_find(DT_DIR, AT_FDCWD, path, search_name, search_type, debug, print_libc);
+ bool debug, int search_type, int flags) {
+ size_t disk_usage_total = 0;
+ int err = do_user_find(DT_DIR, AT_FDCWD, path, search_name, search_type,
+ debug, flags, &disk_usage_total);
+ if (!err) {
+ printf("%zu %s\n", disk_usage_total, path);
+ }
+ return err;
}
int main(int argc, char **argv)
{
bool debug = false;
bool variant_bpf = true;
- bool print_libc = true;
+ int flags = 0;
const char *path;
const char *name = NULL;
@@ -322,7 +351,7 @@ int main(int argc, char **argv)
int optc;
opterr = 0;
- while ((optc = getopt(argc, argv, "D" "v:" "n:" "t:" "p:")) != -1) {
+ while ((optc = getopt(argc, argv, "D" "v:" "n:" "t:" "b" "s" "m")) != -1) {
switch (optc) {
case 'D':
debug = true;
@@ -336,8 +365,14 @@ int main(int argc, char **argv)
case 't':
type_str = optarg;
break;
- case 'p':
- print_libc = strcmp("libc", optarg) == 0;
+ case 'b':
+ flags |= PRINT_LIBC;
+ break;
+ case 's':
+ flags |= SUMMARIZE_DISK_USAGE;
+ break;
+ case 'm':
+ flags |= PRINT_MATCHES;
break;
default:
fprintf(stderr, "error: invalid option %c\n", optc);
@@ -398,7 +433,7 @@ int main(int argc, char **argv)
if (variant_bpf) {
ret = bpf_find(path, name, debug, type);
} else {
- ret = user_find(path, name, debug, type, print_libc);
+ ret = user_find(path, name, debug, type, flags);
}
return ret;
--
GitLab