]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fincore: add option to show a grand total
authorMatteo Croce <teknoraver@meta.com>
Thu, 22 May 2025 20:44:32 +0000 (22:44 +0200)
committerMatteo Croce <teknoraver@meta.com>
Sat, 24 May 2025 12:53:54 +0000 (14:53 +0200)
Similarly to `du`, add a --total option to produce a grand total
of the files analyzed.

Signed-off-by: Matteo Croce <teknoraver@meta.com>
misc-utils/fincore.1.adoc
misc-utils/fincore.c
tests/expected/fincore/count.err
tests/expected/fincore/count.total [new file with mode: 0644]
tests/ts/fincore/count

index 7d0c8fca3718cca93f9943f2b0d593f421ddc628..8e480777f087df29f6323bdcf4c5968f84b91df8 100644 (file)
@@ -34,6 +34,9 @@ Do not print a header line in status output.
 *-b*, *--bytes*::
 include::man-common/in-bytes.adoc[]
 
+*-c*, *--total*::
+produce a grand total.
+
 *-o*, *--output* _list_::
 Define output columns. See the *--help* output to get a list of the currently supported columns. The default list of columns may be extended if _list_ is specified in the format _{plus}list_.
 //TRANSLATORS: Keep {plus} untranslated.
index 160dd8e0bf09c64d76500e89e7a9808ef0cd5e01..86c1373cbec8e261bb720cff1bbcbd1859754123 100644 (file)
@@ -130,7 +130,8 @@ struct fincore_control {
                     noheadings : 1,
                     raw : 1,
                     json : 1,
-                    recursive : 1;
+                    recursive : 1,
+                    total : 1;
 
 };
 
@@ -147,6 +148,9 @@ struct fincore_state {
        } cstat_fields;
 };
 
+static struct fincore_state total = {
+       .name = "TOTAL",
+};
 
 static int column_name_to_id(const char *name, size_t namesz)
 {
@@ -297,6 +301,8 @@ static int do_mincore(struct fincore_control *ctl,
                {
                        vec[n] = 0;
                        st->cstat.nr_cache++;
+                       if (ctl->total)
+                               total.cstat.nr_cache++;
                }
        }
 
@@ -349,6 +355,15 @@ static int fincore_fd (struct fincore_control *ctl,
                st->cstat_fields.writeback = 1;
                st->cstat_fields.evicted = 1;
                st->cstat_fields.recently_evicted = 1;
+
+               if (ctl->total) {
+                       total.cstat.nr_cache += st->cstat.nr_cache;
+                       total.cstat.nr_dirty += st->cstat.nr_dirty;
+                       total.cstat.nr_writeback += st->cstat.nr_writeback;
+                       total.cstat.nr_evicted += st->cstat.nr_evicted;
+                       total.cstat.nr_recently_evicted += st->cstat.nr_recently_evicted;
+               }
+
                return 0;
        }
 
@@ -402,6 +417,8 @@ static int fincore_name(struct fincore_control *ctl,
 
        if (!rc) {
                st->name = showname;
+               if (ctl->total)
+                       total.file_size += st->file_size;
                rc = add_output_data(ctl, st);
        }
 
@@ -419,6 +436,7 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(USAGE_OPTIONS, out);
        fputs(_(" -J, --json            use JSON output format\n"), out);
        fputs(_(" -b, --bytes           print sizes in bytes rather than in human readable format\n"), out);
+       fputs(_(" -c, --total           produce a grand total\n"), out);
        fputs(_(" -n, --noheadings      don't print headings\n"), out);
        fputs(_(" -o, --output <list>   output columns\n"), out);
        fputs(_("     --output-all      output all columns\n"), out);
@@ -454,6 +472,7 @@ int main(int argc, char ** argv)
        };
        static const struct option longopts[] = {
                { "bytes",      no_argument, NULL, 'b' },
+               { "total",      no_argument, NULL, 'c' },
                { "noheadings", no_argument, NULL, 'n' },
                { "output",     required_argument, NULL, 'o' },
                { "output-all", no_argument,       NULL, OPT_OUTPUT_ALL },
@@ -470,11 +489,14 @@ int main(int argc, char ** argv)
        textdomain(PACKAGE);
        close_stdout_atexit();
 
-       while ((c = getopt_long (argc, argv, "bno:JrRVh", longopts, NULL)) != -1) {
+       while ((c = getopt_long (argc, argv, "bcno:JrRVh", longopts, NULL)) != -1) {
                switch (c) {
                case 'b':
                        ctl.bytes = 1;
                        break;
+               case 'c':
+                       ctl.total = 1;
+                       break;
                case 'n':
                        ctl.noheadings = 1;
                        break;
@@ -584,6 +606,9 @@ int main(int argc, char ** argv)
                        rc |= fincore_name(&ctl, argv[optind], argv[optind], NULL);
        }
 
+       if (ctl.total)
+               rc |= add_output_data(&ctl, &total);
+
        scols_print_table(ctl.tb);
        scols_unref_table(ctl.tb);
 
index e3fad01132ff7a3d8a7c77b678ce25a2101a867a..fb9f8062770f687d2d6c3f8a76109ea782f210b8 100644 (file)
@@ -2,3 +2,5 @@
 fincore: failed to open: no_such_file: No such file or directory
 [ MULTIPLE FILES ]
 fincore: failed to open: no_such_file: No such file or directory
+[ GRAND TOTAL SIZE ]
+[ GRAND TOTAL PAGES ]
diff --git a/tests/expected/fincore/count.total b/tests/expected/fincore/count.total
new file mode 100644 (file)
index 0000000..57551ec
--- /dev/null
@@ -0,0 +1,33 @@
+0 i_EMPTY
+return value: 0
+1 i_1b
+return value: 0
+1024 i_1k
+return value: 0
+10240 i_10k
+return value: 0
+[ GRAND TOTAL SIZE ]
+0 i_EMPTY
+1 i_1b
+1024 i_1k
+10240 i_10k
+11265 TOTAL
+return value: 0
+0 i_EMPTY
+return value: 0
+1 i_1b
+return value: 0
+1 i_ONE_PAGE
+return value: 0
+2 i_TWO_PAGES
+return value: 0
+10 i_TEN_PAGES
+return value: 0
+[ GRAND TOTAL PAGES ]
+0 i_EMPTY
+1 i_1b
+1 i_ONE_PAGE
+2 i_TWO_PAGES
+10 i_TEN_PAGES
+14 TOTAL
+return value: 0
index e132b99026903f7beda9b33eef5deb6a8bb6d70a..240ccdd114cc37d2ffc5b1503066e774c5439956 100755 (executable)
@@ -117,6 +117,7 @@ else
        OUT_COLUMNS="PAGES,FILE"
 fi
 
+cat "$TS_EXPECTED.total" >>"$AGG_OUT"
 cat "$TS_EXPECTED_ERR" >"$AGG_ERR"
 
 if ! $TS_CMD_FINCORE --recursive |& grep -q 'recursive option is not supported' ; then
@@ -247,6 +248,67 @@ ts_log_both "[ MULTIPLE FILES ]"
     footer "$?"
 } >> $TS_OUTPUT 2>> $TS_ERRLOG
 
+rm -f $INPUT
+INPUT=
+
+OLD_COLUMNS=$OUT_COLUMNS
+OUT_COLUMNS=SIZE,FILE
+
+{
+       run_dd_test "EMPTY" 0
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 1b 1
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 1k 1024
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 10k 10240
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+ts_log_both "[ GRAND TOTAL SIZE ]"
+{
+    $TS_CMD_FINCORE --raw --output $OUT_COLUMNS --bytes --noheadings --total $INPUT
+    footer "$?"
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+rm -f $INPUT
+INPUT=
+
+OUT_COLUMNS=PAGES,FILE
+
+{
+       run_dd_test "EMPTY" 0
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 1b 1
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 'ONE PAGE' $PAGE_SIZE
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 'TWO PAGES' $(( 2 * PAGE_SIZE ))
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+{
+       run_dd_test 'TEN PAGES' $(( 10 * PAGE_SIZE ))
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+ts_log_both "[ GRAND TOTAL PAGES ]"
+{
+    $TS_CMD_FINCORE --raw --output $OUT_COLUMNS --bytes --noheadings --total $INPUT
+    footer "$?"
+} >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+OUT_COLUMNS=$OLD_COLUMNS
+
 if [ -n "$RECURSIVE" ]; then
        dir=$(make_input_name dir)
        mkdir -p "$dir"