File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020
0021 #include <rtems/shell.h>
0022
0023 #define __need_getopt_newlib
0024 #include <getopt.h>
0025 #include <string.h>
0026 #include <inttypes.h>
0027
0028 static const char suffixes[] =
0029 { 'B', 'K', 'M', 'G', 'T' };
0030
0031 struct df_context
0032 {
0033 unsigned block_size;
0034 };
0035
0036 static unsigned rtems_shell_df_parse_size(const char *str)
0037 {
0038 unsigned result;
0039 char suffix;
0040 int i;
0041
0042 if (sscanf(str, "%d%c", &result, &suffix) == 2)
0043 {
0044 for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
0045 {
0046 if (suffix == suffixes[i])
0047 break;
0048 result *= 1024;
0049 }
0050 }
0051 else if (sscanf(str, "%d", &result) != 1)
0052 {
0053 result = 0;
0054 }
0055
0056 return result;
0057 }
0058
0059 static char *rtems_shell_df_humanize_size(uint64_t block_size, char *buf,
0060 size_t size)
0061 {
0062 int i = 0;
0063
0064 while (block_size >= 1024 && i < sizeof(suffixes) / sizeof(suffixes[0]) - 1)
0065 {
0066 block_size /= 1024;
0067 i++;
0068 }
0069
0070 snprintf(buf, size, "%"PRIu64"%c", block_size, suffixes[i]);
0071 return buf;
0072 }
0073
0074 static bool rtems_shell_df_print_entry(
0075 const rtems_filesystem_mount_table_entry_t *mt_entry, void *arg)
0076 {
0077 struct df_context *context = arg;
0078
0079 struct statvfs svfs;
0080 int code;
0081 char f_buf[20], u_buf[20], a_buf[20];
0082
0083 if ((code = statvfs(mt_entry->target, &svfs)))
0084 return false;
0085
0086 if (context->block_size > 0)
0087 {
0088 printf(
0089 "%-15s %10" PRIu64 " %9" PRIu64 " %11" PRIu64 " %9" PRIu64 "%% %14s\n",
0090 mt_entry->dev == NULL ? "none" : mt_entry->dev,
0091 (svfs.f_blocks * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0092 ((svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0093 (svfs.f_bfree * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0094 ((svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks),
0095 mt_entry->target == NULL ? "none" : mt_entry->target);
0096 }
0097 else
0098 {
0099 rtems_shell_df_humanize_size(svfs.f_blocks * svfs.f_frsize, f_buf,
0100 sizeof(f_buf));
0101 rtems_shell_df_humanize_size((svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize,
0102 u_buf, sizeof(u_buf));
0103 rtems_shell_df_humanize_size(svfs.f_bfree * svfs.f_frsize, a_buf,
0104 sizeof(a_buf));
0105 printf("%-15s %10s %9s %11s %9" PRIu64 "%% %14s\n",
0106 mt_entry->dev == NULL ? "none" : mt_entry->dev, f_buf, u_buf, a_buf,
0107 (uint64_t)(svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks,
0108 mt_entry->target == NULL ? "none" : mt_entry->target);
0109 }
0110
0111 return false;
0112 }
0113
0114 static int rtems_shell_main_df(int argc, char **argv)
0115 {
0116 int c;
0117 struct getopt_data optdata;
0118 struct df_context context;
0119 char buf[32];
0120
0121 memset(&optdata, 0, sizeof(optdata));
0122 context.block_size = 1024;
0123
0124 while ((c = getopt_r(argc, (char**) argv, ":hB:", &optdata)) != -1)
0125 {
0126 switch (c)
0127 {
0128 case 'h':
0129 context.block_size = 0;
0130 break;
0131 case 'B':
0132 context.block_size = rtems_shell_df_parse_size(optdata.optarg);
0133 break;
0134 default:
0135 return -1;
0136 }
0137 }
0138
0139 if (context.block_size == 0)
0140 printf(
0141 "Filesystem Size Used Available Use%% Mounted on\n");
0142 else
0143 printf(
0144 "Filesystem %s-blocks Used Available Use%% Mounted on\n",
0145 rtems_shell_df_humanize_size(context.block_size, buf, sizeof(buf)));
0146
0147 rtems_filesystem_mount_iterate(rtems_shell_df_print_entry, &context);
0148
0149 return 0;
0150 }
0151
0152 rtems_shell_cmd_t rtems_shell_DF_Command =
0153 {
0154 "df",
0155 "[-hB]\n"
0156 " -h human-readable output\n"
0157 " -B scale sizes by SIZE before printing them\n",
0158 "files",
0159 rtems_shell_main_df,
0160 NULL,
0161 NULL
0162 };