diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index 1327c281e..7224124a9 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -69,6 +69,7 @@ test_data = \ $(NULL) uninstalled_test_extra_programs = \ + gio-du \ echo-server \ filter-cat \ gapplication-example-actions \ diff --git a/gio/tests/gio-du.c b/gio/tests/gio-du.c new file mode 100644 index 000000000..4ed9941ed --- /dev/null +++ b/gio/tests/gio-du.c @@ -0,0 +1,146 @@ +#include +#include + +static gboolean option_use_async; +static gint option_format_size; + +static gint outstanding_asyncs; + +static void +print_result (const gchar *filename, + guint64 disk_usage, + guint64 num_dirs, + guint64 num_files, + GError *error, + gchar nl) +{ + if (!error) + { + if (option_format_size) + { + GFormatSizeFlags format_flags; + gchar *str; + + format_flags = (option_format_size > 1) ? G_FORMAT_SIZE_LONG_FORMAT : G_FORMAT_SIZE_DEFAULT; + str = g_format_size_full (disk_usage, format_flags); + g_print ("%s: %s (%"G_GUINT64_FORMAT" dirs, %"G_GUINT64_FORMAT" files)%c", + filename, str, num_dirs, num_files, nl); + g_free (str); + } + else + g_print ("%s: %"G_GUINT64_FORMAT" (%"G_GUINT64_FORMAT" dirs, %"G_GUINT64_FORMAT" files)%c", + filename, disk_usage, num_dirs, num_files, nl); + } + else + { + g_printerr ("%s: %s\n", filename, error->message); + g_error_free (error); + } +} + +static void +async_ready_func (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + const gchar *filename = user_data; + GError *error = NULL; + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; + + g_file_measure_disk_usage_finish (G_FILE (source), result, &disk_usage, &num_dirs, &num_files, &error); + print_result (filename, disk_usage, num_dirs, num_files, error, '\n'); + outstanding_asyncs--; +} + +static void +report_progress (gboolean reporting, + guint64 disk_usage, + guint64 num_dirs, + guint64 num_files, + gpointer user_data) +{ + const gchar *filename = user_data; + + if (!reporting) + g_printerr ("%s: warning: does not support progress reporting\n", filename); + + print_result (filename, disk_usage, num_dirs, num_files, NULL, '\r'); +} + +int +main (int argc, char **argv) +{ + GFileMeasureProgressCallback progress; + GFileMeasureFlags flags = 0; + gint i; + + setlocale (LC_ALL, ""); + + for (i = 1; argv[i] && argv[i][0] == '-'; i++) + { + if (g_str_equal (argv[i], "--")) + break; + + if (g_str_equal (argv[i], "--help")) + { + g_print ("usage: du [--progress] [--async] [-x] [-h] [-h] [--apparent-size] [--any-error] [--] files...\n"); + return 0; + } + else if (g_str_equal (argv[i], "-x")) + flags |= G_FILE_MEASURE_NO_XDEV; + else if (g_str_equal (argv[i], "-h")) + option_format_size++; + else if (g_str_equal (argv[i], "--apparent-size")) + flags |= G_FILE_MEASURE_APPARENT_SIZE; + else if (g_str_equal (argv[i], "--any-error")) + flags |= G_FILE_MEASURE_REPORT_ANY_ERROR; + else if (g_str_equal (argv[i], "--async")) + option_use_async = TRUE; + else if (g_str_equal (argv[i], "--progress")) + progress = report_progress; + else + { + g_printerr ("unrecognised flag %s\n", argv[i]); + } + } + + if (!argv[i]) + { + g_printerr ("usage: du [--progress] [--async] [-x] [-h] [-h] [--apparent-size] [--any-error] [--] files...\n"); + return 1; + } + + while (argv[i]) + { + GFile *file = g_file_new_for_commandline_arg (argv[i]); + + if (option_use_async) + { + g_file_measure_disk_usage_async (file, flags, G_PRIORITY_DEFAULT, NULL, + progress, argv[1], async_ready_func, argv[i]); + outstanding_asyncs++; + } + else + { + GError *error = NULL; + guint64 disk_usage; + guint64 num_dirs; + guint64 num_files; + + g_file_measure_disk_usage (file, flags, NULL, progress, argv[1], + &disk_usage, &num_dirs, &num_files, &error); + print_result (argv[i], disk_usage, num_dirs, num_files, error, '\n'); + } + + g_object_unref (file); + + i++; + } + + while (outstanding_asyncs) + g_main_context_iteration (NULL, TRUE); + + return 0; +}