summaryrefslogtreecommitdiffstats
path: root/printf.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2018-07-24 19:16:27 -0400
committerTavian Barnes <tavianator@tavianator.com>2018-07-24 19:16:27 -0400
commit199063ab53cbae3b3be199ff902f9f2d001d1058 (patch)
treee533572ad08648917322e35a05fd1465f99bae6b /printf.c
parent86f0049bff0c8c802bb07fcb52ae468608ec0920 (diff)
downloadbfs-199063ab53cbae3b3be199ff902f9f2d001d1058.tar.xz
stat: Don't assume blocks are 512 bytes
POSIX says > The unit for the st_blocks member of the stat structure is not defined > within POSIX.1‐2008. and recommends using DEV_BSIZE from <sys/param.h> if available. Also, for -printf '%S', print 1 instead of NaN for empty files with no blocks.
Diffstat (limited to 'printf.c')
-rw-r--r--printf.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/printf.c b/printf.c
index 6a87f99..0e9110e 100644
--- a/printf.c
+++ b/printf.c
@@ -184,7 +184,8 @@ static int bfs_printf_strftime(FILE *file, const struct bfs_printf_directive *di
/** %b: blocks */
static int bfs_printf_b(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) {
- BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->blocks);
+ uintmax_t blocks = ((uintmax_t)ftwbuf->statbuf->blocks*BFS_STAT_BLKSIZE + 511)/512;
+ BFS_PRINTF_BUF(buf, "%ju", blocks);
return fprintf(file, directive->str, buf);
}
@@ -266,7 +267,8 @@ static int bfs_printf_i(FILE *file, const struct bfs_printf_directive *directive
/** %k: 1K blocks */
static int bfs_printf_k(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) {
- BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)(ftwbuf->statbuf->blocks + 1)/2);
+ uintmax_t blocks = ((uintmax_t)ftwbuf->statbuf->blocks*BFS_STAT_BLKSIZE + 1023)/1024;
+ BFS_PRINTF_BUF(buf, "%ju", blocks);
return fprintf(file, directive->str, buf);
}
@@ -326,7 +328,13 @@ static int bfs_printf_s(FILE *file, const struct bfs_printf_directive *directive
/** %S: sparseness */
static int bfs_printf_S(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) {
- double sparsity = 512.0 * ftwbuf->statbuf->blocks / ftwbuf->statbuf->size;
+ double sparsity;
+ const struct bfs_stat *sb = ftwbuf->statbuf;
+ if (sb->size == 0 && sb->blocks == 0) {
+ sparsity = 1.0;
+ } else {
+ sparsity = (double)BFS_STAT_BLKSIZE*sb->blocks/sb->size;
+ }
return fprintf(file, directive->str, sparsity);
}