From 811493e2a9fc9a4fee2a3161d78a03f8af1c2392 Mon Sep 17 00:00:00 2001
From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Sun, 3 Mar 2019 14:35:18 -0800
Subject: [PATCH] df: support different file system encodings when not using
tty
* src/df.c (replace_problematic_chars): A new wrapper to be
more conservative in our replacement when not connected to a tty.
* tests/df/problematic-chars.sh: Add a test case.
---
src/df.c | 34 +++++++++++++++++++++++++++++++---
tests/df/problematic-chars.sh | 31 +++++++++++++++++++++++++------
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/src/df.c b/src/df.c
index 1eb7bcd479..041f2820d6 100644
--- a/src/df.c
+++ b/src/df.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
@@ -273,10 +274,26 @@ static struct option const long_options[] =
{NULL, 0, NULL, 0}
};
+/* Replace problematic chars with '?'.
+ Since only control characters are currently considered,
+ this should work in all encodings. */
+
+static void
+replace_control_chars (char *cell)
+{
+ char *p = cell;
+ while (*p)
+ {
+ if (c_iscntrl (to_uchar (*p)))
+ *p = '?';
+ p++;
+ }
+}
+
/* Replace problematic chars with '?'. */
static void
-hide_problematic_chars (char *cell)
+replace_invalid_chars (char *cell)
{
char *srcend = cell + strlen (cell);
char *dst = cell;
@@ -310,6 +327,17 @@ hide_problematic_chars (char *cell)
*dst = '\0';
}
+static void
+replace_problematic_chars (char *cell)
+{
+ static int tty_out = -1;
+ if (tty_out < 0)
+ tty_out = isatty (STDOUT_FILENO);
+
+ (tty_out ? replace_invalid_chars : replace_control_chars) (cell) ;
+}
+
+
/* Dynamically allocate a row of pointers in TABLE, which
can then be accessed with standard 2D array notation. */
@@ -591,7 +619,7 @@ get_header (void)
if (!cell)
xalloc_die ();
- hide_problematic_chars (cell);
+ replace_problematic_chars (cell);
table[nrows - 1][col] = cell;
@@ -1205,7 +1233,7 @@ get_dev (char const *disk, char const *mount_point, char const* file,
if (!cell)
assert (!"empty cell");
- hide_problematic_chars (cell);
+ replace_problematic_chars (cell);
size_t cell_width = mbswidth (cell, 0);
columns[col]->width = MAX (columns[col]->width, cell_width);
table[nrows - 1][col] = cell;
diff --git a/tests/df/problematic-chars.sh b/tests/df/problematic-chars.sh
index 34e743bdcc..181149f574 100755
--- a/tests/df/problematic-chars.sh
+++ b/tests/df/problematic-chars.sh
@@ -17,14 +17,17 @@
# along with this program. If not, see .
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
-print_ver_ df
+print_ver_ df printf
require_root_
+
+# Ensure a new line in a mount point only outputs a single line
+
mnt='mount
point'
cwd=$(pwd)
-cleanup_() { cd /; umount "$cwd/$mnt"; }
+cleanup_() { umount "$cwd/$mnt"; }
skip=0
# Create a file system, then mount it.
@@ -33,14 +36,30 @@ dd if=/dev/zero of=blob bs=8192 count=200 > /dev/null 2>&1 \
mkdir "$mnt" || skip=1
mkfs -t ext2 -F blob \
|| skip_ "failed to create ext2 file system"
-
mount -oloop blob "$mnt" || skip=1
-
test $skip = 1 \
&& skip_ "insufficient mount/ext2 support"
-
test $(df "$mnt" | wc -l) = 2 || fail=1
-
test "$fail" = 1 && dump_mount_list_
+
+# Ensure mount points not matching the current user encoding are output
+
+unset LC_ALL
+f=$LOCALE_FR_UTF8
+: ${LOCALE_FR_UTF8=none}
+if test "$LOCALE_FR_UTF8" != "none"; then
+
+ cleanup_ || framework_failure_
+
+ # Create a non UTF8 mount point
+ mnt="$(env printf 'm\xf3unt p\xf3int')"
+ mkdir "$mnt" || framework_failure_
+ mount -oloop blob "$mnt" || skip_ "unable to mount $mnt"
+
+ LC_ALL=$f df --output=target "$mnt" > df.out || fail=1
+ test "$(basename "$(tail -n1 df.out)")" = "$mnt" || fail=1
+fi
+
+
Exit $fail
--
2.47.2