Changeset 120d5bc in mainline for uspace/app/df/df.c


Ignore:
Timestamp:
2017-09-13T20:49:43Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5918c00
Parents:
6c4eedf
Message:

Let df give 'human-readable' output by default. Use cap.h for better capacity formatting. Let -b print block size and numbers of blocks for each FS.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/df/df.c

    r6c4eedf r120d5bc  
    2828
    2929/** @addtogroup df
    30  * @brief Df utility.
     30 * @brief Print amounts of free and used disk space.
    3131 * @{
    3232 */
     
    3535 */
    3636
     37#include <cap.h>
     38#include <stdbool.h>
    3739#include <stdio.h>
    3840#include <stdlib.h>
     
    4648#define NAME  "df"
    4749
    48 #define HEADER_TABLE    "Filesystem     %4u-blocks           Used      Available Used%% Mounted on"
    49 #define HEADER_TABLE_HR "Filesystem           Size           Used      Available Used%% Mounted on"
     50#define HEADER_TABLE     "Filesystem           Size           Used      Available Used%% Mounted on"
     51#define HEADER_TABLE_BLK "Filesystem  Blk. Size     Total        Used   Available Used%% Mounted on"
    5052
    5153#define PERCENTAGE(x, tot) (tot ? (100ULL * (x) / (tot)) : 0)
    52 #define FSBK_TO_BK(x, fsbk, bk) \
    53         (((fsbk) != 0 && (fsbk) < (bk)) ? \
    54                 (unsigned long long) ((x) / ((bk) / (fsbk))) : \
    55                 (unsigned long long) ((x) * ((fsbk) / (bk))))
    56 
    57 static unsigned int unit_size;
    58 static unsigned int human_readable;
    59 
    60 static void size_to_human_readable(char *buf, uint64_t bytes);
     54
     55static bool display_blocks;
     56
     57static int size_to_human_readable(uint64_t, size_t, char **);
    6158static void print_header(void);
    62 static void print_statfs(struct statfs *, char *, char *);
     59static int print_statfs(struct statfs *, char *, char *);
    6360static void print_usage(void);
    6461
     
    6764        int optres, errflg = 0;
    6865        struct statfs st;
    69 
    70         unit_size = 512;
    71         human_readable = 0;
    72 
    73         /******************************************/
    74         /*   Parse command line options...        */
    75         /******************************************/
    76         while ((optres = getopt(argc, argv, ":uhb:")) != -1) {
     66        int rc;
     67
     68        display_blocks = false;
     69
     70        /* Parse command-line options */
     71        while ((optres = getopt(argc, argv, ":ubh")) != -1) {
    7772                switch(optres) {
    78                 case 'u':
     73                case 'h':
    7974                        print_usage();
    8075                        return 0;
    8176
    82                 case 'h':
    83                         human_readable = 1;
    84                         break;
    85 
    8677                case 'b':
    87                         str_uint32_t(optarg, NULL, 0, 0, &unit_size);
     78                        display_blocks = true;
    8879                        break;
    8980 
     
    123114        list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
    124115                if (vfs_statfs_path(mtab_ent->mp, &st) == 0) {
    125                         print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
     116                        rc = print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
     117                        if (rc != EOK)
     118                                return 1;
    126119                } else {
    127120                        fprintf(stderr, "Cannot get information for '%s' (%d).\n",
     
    134127}
    135128
    136 static void size_to_human_readable(char *buf, uint64_t bytes)
    137 {
    138         const char *units = "BkMGTPEZY";
    139         int i = 0;
    140 
    141         while (bytes >= 1024) {
    142                 bytes /= 1024;
    143                 i++;
    144         }
    145 
    146         snprintf(buf, 6, "%4llu%c", (unsigned long long) bytes, units[i]);
     129static int size_to_human_readable(uint64_t nblocks, size_t block_size, char **rptr)
     130{
     131        cap_spec_t cap;
     132
     133        cap_from_blocks(nblocks, block_size, &cap);
     134        cap_simplify(&cap);
     135        return cap_format(&cap, rptr);
    147136}
    148137
    149138static void print_header(void)
    150139{
    151         if (human_readable)
    152                 printf(HEADER_TABLE_HR);
     140        if (!display_blocks)
     141                printf(HEADER_TABLE);
    153142        else
    154                 printf(HEADER_TABLE, unit_size);
     143                printf(HEADER_TABLE_BLK);
    155144
    156145        putchar('\n');
    157146}
    158147
    159 static void print_statfs(struct statfs *st, char *name, char *mountpoint)
     148static int print_statfs(struct statfs *st, char *name, char *mountpoint)
    160149{
    161150        uint64_t const used_blocks = st->f_blocks - st->f_bfree;
    162151        unsigned const perc_used = PERCENTAGE(used_blocks, st->f_blocks);
     152        char *str;
     153        int rc;
    163154
    164155        printf("%10s", name);
    165156
    166         if (human_readable) {
    167                 char tmp[1024];
    168 
     157        if (!display_blocks) {
    169158                /* Print size */
    170                 size_to_human_readable(tmp, st->f_blocks *  st->f_bsize);
    171                 printf(" %14s", tmp);
     159                rc = size_to_human_readable(st->f_blocks, st->f_bsize, &str);
     160                if (rc != EOK)
     161                        goto error;
     162                printf(" %14s", str);
     163                free(str);
    172164
    173165                /* Number of used blocks */
    174                 size_to_human_readable(tmp, used_blocks  *  st->f_bsize);
    175                 printf(" %14s", tmp);
     166                rc = size_to_human_readable(used_blocks, st->f_bsize, &str);
     167                if (rc != EOK)
     168                        goto error;
     169                printf(" %14s", str);
     170                free(str);
    176171
    177172                /* Number of available blocks */
    178                 size_to_human_readable(tmp, st->f_bfree *  st->f_bsize);
    179                 printf(" %14s", tmp);
     173                rc = size_to_human_readable(st->f_bfree, st->f_bsize, &str);
     174                if (rc != EOK)
     175                        goto error;
     176                printf(" %14s", str);
     177                free(str);
    180178
    181179                /* Percentage of used blocks */
     
    185183                printf(" %s\n", mountpoint);
    186184        } else {
    187                 /* Blocks / Used blocks / Available blocks / Used% / Mounted on */
    188                 printf(" %15llu %14llu %14llu %4u%% %s\n",
    189                     FSBK_TO_BK(st->f_blocks, st->f_bsize, unit_size),
    190                     FSBK_TO_BK(used_blocks, st->f_bsize, unit_size),
    191                     FSBK_TO_BK(st->f_bfree, st->f_bsize, unit_size),
    192                     perc_used,
    193                     mountpoint);
    194         }
    195 
     185                /* Block size / Blocks / Used blocks / Available blocks / Used% / Mounted on */
     186                printf(" %10" PRIu32 " %9" PRIu64 " %11" PRIu64 " %11" PRIu64 " %4u%% %s\n",
     187                    st->f_bsize, st->f_blocks, used_blocks, st->f_bfree,
     188                    perc_used, mountpoint);
     189        }
     190
     191        return EOK;
     192error:
     193        printf("\nError: Out of memory.\n");
     194        return ENOMEM;
    196195}
    197196
    198197static void print_usage(void)
    199198{
    200         printf("syntax: %s [-u] [-h] [-b <size>] \n", NAME);
    201         printf("  u : Show usage.\n");
    202         printf("  h : \"Human-readable\" output.\n");
    203         printf("  b : Scale block sizes by selected size.\n");
    204         printf("\n");
     199        printf("Syntax: %s [<options>] \n", NAME);
     200        printf("Options:\n");
     201        printf("  -h Print help\n");
     202        printf("  -b Print exact block sizes and numbers\n");
    205203}
    206204
Note: See TracChangeset for help on using the changeset viewer.