source: mainline/uspace/app/df/df.c@ 00d23a2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 00d23a2 was 120d5bc, checked in by Jiri Svoboda <jiri@…>, 8 years ago

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.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2013 Manuele Conti
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup df
30 * @brief Print amounts of free and used disk space.
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <cap.h>
38#include <stdbool.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <stdint.h>
42#include <getopt.h>
43#include <errno.h>
44#include <adt/list.h>
45#include <vfs/vfs.h>
46#include <vfs/vfs_mtab.h>
47
48#define NAME "df"
49
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"
52
53#define PERCENTAGE(x, tot) (tot ? (100ULL * (x) / (tot)) : 0)
54
55static bool display_blocks;
56
57static int size_to_human_readable(uint64_t, size_t, char **);
58static void print_header(void);
59static int print_statfs(struct statfs *, char *, char *);
60static void print_usage(void);
61
62int main(int argc, char *argv[])
63{
64 int optres, errflg = 0;
65 struct statfs st;
66 int rc;
67
68 display_blocks = false;
69
70 /* Parse command-line options */
71 while ((optres = getopt(argc, argv, ":ubh")) != -1) {
72 switch(optres) {
73 case 'h':
74 print_usage();
75 return 0;
76
77 case 'b':
78 display_blocks = true;
79 break;
80
81 case ':':
82 fprintf(stderr, "Option -%c requires an operand\n",
83 optopt);
84 errflg++;
85 break;
86
87 case '?':
88 fprintf(stderr, "Unrecognized option: -%c\n", optopt);
89 errflg++;
90 break;
91
92 default:
93 fprintf(stderr,
94 "Unknown error while parsing command line options");
95 errflg++;
96 break;
97 }
98 }
99
100 if (optind > argc) {
101 fprintf(stderr, "Too many input parameters\n");
102 errflg++;
103 }
104
105 if (errflg) {
106 print_usage();
107 return 1;
108 }
109
110 LIST_INITIALIZE(mtab_list);
111 vfs_get_mtab_list(&mtab_list);
112
113 print_header();
114 list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
115 if (vfs_statfs_path(mtab_ent->mp, &st) == 0) {
116 rc = print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
117 if (rc != EOK)
118 return 1;
119 } else {
120 fprintf(stderr, "Cannot get information for '%s' (%d).\n",
121 mtab_ent->mp, errno);
122 }
123 }
124
125 putchar('\n');
126 return 0;
127}
128
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);
136}
137
138static void print_header(void)
139{
140 if (!display_blocks)
141 printf(HEADER_TABLE);
142 else
143 printf(HEADER_TABLE_BLK);
144
145 putchar('\n');
146}
147
148static int print_statfs(struct statfs *st, char *name, char *mountpoint)
149{
150 uint64_t const used_blocks = st->f_blocks - st->f_bfree;
151 unsigned const perc_used = PERCENTAGE(used_blocks, st->f_blocks);
152 char *str;
153 int rc;
154
155 printf("%10s", name);
156
157 if (!display_blocks) {
158 /* Print size */
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);
164
165 /* Number of used blocks */
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);
171
172 /* Number of available blocks */
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);
178
179 /* Percentage of used blocks */
180 printf(" %4u%%", perc_used);
181
182 /* Mount point */
183 printf(" %s\n", mountpoint);
184 } else {
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;
195}
196
197static void print_usage(void)
198{
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");
203}
204
205/** @}
206 */
Note: See TracBrowser for help on using the repository browser.