diff options
author | Philip Pokorny <[email protected]> | 2020-05-06 17:17:38 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-06 17:17:38 -0700 |
commit | a36bad17596e5cbc472a0d1fecb200a6b2e3530d (patch) | |
tree | 706d72bdd5db9a3a3af0dc61b1b7c8b0657e4edc | |
parent | 1b664952ae34d28c0408c20947f8aa5420c4ab63 (diff) |
Fix column width calculation issue with certain terminal widths
If the reported terminal width is 0 or less than 42, the signed variable
width was set to a negative number that was then assigned to the
unsigned column width becoming a huge number.
Add comments and change logic to better explain what's happening.
Reviewed-by: Tony Hutter <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Philip Pokorny <[email protected]>
Closes #10247
-rw-r--r-- | cmd/zpool/zpool_main.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index d62a6eb3c..e154e40e4 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -5148,22 +5148,48 @@ print_zpool_script_list(char *subcommand) /* * Set the minimum pool/vdev name column width. The width must be at least 10, * but may be as large as the column width - 42 so it still fits on one line. + * NOTE: 42 is the width of the default capacity/operations/bandwidth output */ static int get_namewidth_iostat(zpool_handle_t *zhp, void *data) { iostat_cbdata_t *cb = data; - int width, columns; + int width, available_width; + /* + * get_namewidth() returns the maximum width of any name in that column + * for any pool/vdev/device line that will be output. + */ width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, cb->cb_verbose); - columns = get_columns(); + /* + * The width we are calculating is the width of the header and also the + * padding width for names that are less than maximum width. The stats + * take up 42 characters, so the width available for names is: + */ + available_width = get_columns() - 42; + + /* + * If the maximum width fits on a screen, then great! Make everything + * line up by justifying all lines to the same width. If that max + * width is larger than what's available, the name plus stats won't fit + * on one line, and justifying to that width would cause every line to + * wrap on the screen. We only want lines with long names to wrap. + * Limit the padding to what won't wrap. + */ + if (width > available_width) + width = available_width; + + /* + * And regardless of whatever the screen width is (get_columns can + * return 0 if the width is not known or less than 42 for a narrow + * terminal) have the width be a minimum of 10. + */ if (width < 10) width = 10; - if (width > columns - 42) - width = columns - 42; + /* Save the calculated width */ cb->cb_namewidth = width; return (0); |