summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Pokorny <[email protected]>2020-05-06 17:17:38 -0700
committerGitHub <[email protected]>2020-05-06 17:17:38 -0700
commita36bad17596e5cbc472a0d1fecb200a6b2e3530d (patch)
tree706d72bdd5db9a3a3af0dc61b1b7c8b0657e4edc
parent1b664952ae34d28c0408c20947f8aa5420c4ab63 (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.c34
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);