From: Pádraig Brady Date: Thu, 3 Nov 2016 15:36:48 +0000 (+0000) Subject: stat: make --format=%N honor the QUOTING_STYLE env var X-Git-Tag: v8.26~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ad400f1adfcb90289107afcbc49469560ba14b5;p=thirdparty%2Fcoreutils.git stat: make --format=%N honor the QUOTING_STYLE env var * doc/coreutils.texi (stat invocation): Describe the QUOTING_STYLE values now supported. * src/stat.c (getenv_quoting_style): A new function called from main, that sets the default quoting style for quotearg. (main): Call getenv_quoting_style() when %N specified. * tests/misc/stat-fmt.sh: Add a test case. * NEWS: Mention the improvement. Fixes http://bugs.gnu.org/23422 --- diff --git a/NEWS b/NEWS index 9548de885c..844e23332e 100644 --- a/NEWS +++ b/NEWS @@ -85,6 +85,9 @@ GNU coreutils NEWS -*- outline -*- tail -f uses polling for "prl_fs" and "smb2", inotify for "m1fs", and attempts inotify for "wslfs". + stat --format=%N for quoting file names now honors the + same QUOTING_STYLE environment variable values as ls. + ** New Features date now accepts the --debug option, to annotate the parsed date string, diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 95419b44ed..927e552ab6 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -7724,6 +7724,7 @@ Use style @var{word} to quote file names and other strings that may contain arbitrary characters. The @var{word} should be one of the following: +@macro quotingStyles @table @samp @item literal Output strings as-is; this is the same as the @option{-N} or @@ -7761,6 +7762,8 @@ surrounding quotation marks appropriate for the locale, and quote @t{'like this'} instead of @t{"like this"} in the default C locale. This looks nicer on many displays. @end table +@end macro +@quotingStyles You can specify the default value of the @option{--quoting-style} option with the environment variable @env{QUOTING_STYLE}@. If that environment @@ -11775,7 +11778,7 @@ The valid @var{format} directives for files with @option{--format} and @item %i - Inode number @item %m - Mount point (See note below) @item %n - File name -@item %N - Quoted file name with dereference if symbolic link +@item %N - Quoted file name with dereference if symbolic link (see below) @item %o - Optimal I/O transfer size hint @item %s - Total size, in bytes @item %t - Major device type in hex (see below) @@ -11797,6 +11800,11 @@ to control the zero padding of the output with the @samp{#} and @samp{0} printf flags. For example to pad to at least 3 wide while making larger numbers unambiguously octal, you can use @samp{%#03a}. +The @samp{%N} format can be set with the environment variable +@env{QUOTING_STYLE}@. If that environment variable is not set, +the default value is @samp{shell-escape}. Valid quoting styles are: +@quotingStyles + The @samp{%t} and @samp{%T} formats operate on the st_rdev member of the stat(2) structure, and are only defined for character and block special files. On some systems or file types, st_rdev may be used to diff --git a/src/stat.c b/src/stat.c index 53a6cb7bb8..a43eca4d29 100644 --- a/src/stat.c +++ b/src/stat.c @@ -59,6 +59,7 @@ #include "system.h" #include "areadlink.h" +#include "argmatch.h" #include "die.h" #include "error.h" #include "file-type.h" @@ -997,6 +998,32 @@ neg_to_zero (struct timespec ts) return z; } +/* Set the quoting style default if the environment variable + QUOTING_STYLE is set. */ + +static void +getenv_quoting_style (void) +{ + char const *q_style = getenv ("QUOTING_STYLE"); + if (q_style) + { + int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals); + if (0 <= i) + set_quoting_style (NULL, quoting_style_vals[i]); + else + { + set_quoting_style (NULL, shell_escape_always_quoting_style); + error (0, 0, _("ignoring invalid value of environment " + "variable QUOTING_STYLE: %s"), quote (q_style)); + } + } + else + set_quoting_style (NULL, shell_escape_always_quoting_style); +} + +/* Equivalent to quotearg(), but explicit to avoid syntax checks. */ +#define quoteN(x) quotearg_style (get_quoting_style (NULL), x) + /* Print stat info. Return zero upon success, nonzero upon failure. */ static bool print_stat (char *pformat, size_t prefix_len, unsigned int m, @@ -1013,7 +1040,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, out_string (pformat, prefix_len, filename); break; case 'N': - out_string (pformat, prefix_len, quoteaf (filename)); + out_string (pformat, prefix_len, quoteN (filename)); if (S_ISLNK (statbuf->st_mode)) { char *linkname = areadlink_with_size (filename, statbuf->st_size); @@ -1024,7 +1051,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m, return true; } printf (" -> "); - out_string (pformat, prefix_len, quoteaf (linkname)); + out_string (pformat, prefix_len, quoteN (linkname)); free (linkname); } break; @@ -1602,11 +1629,15 @@ main (int argc, char *argv[]) } if (format) - format2 = format; + { + if (strstr (format, "%N")) + getenv_quoting_style (); + format2 = format; + } else { - format = default_format (fs, terse, false); - format2 = default_format (fs, terse, true); + format = default_format (fs, terse, /* device= */ false); + format2 = default_format (fs, terse, /* device= */ true); } for (i = optind; i < argc; i++) diff --git a/tests/misc/stat-fmt.sh b/tests/misc/stat-fmt.sh index baa7ca775a..1245ddb9e9 100755 --- a/tests/misc/stat-fmt.sh +++ b/tests/misc/stat-fmt.sh @@ -20,11 +20,24 @@ print_ver_ stat - +# ensure that stat properly handles a format string ending with % for i in $(seq 50); do fmt=$(printf "%${i}s" %) out=$(stat --form="$fmt" .) test "$out" = "$fmt" || fail=1 done +# ensure QUOTING_STYLE is honored by %N +touch "'" || framework_failure_ +# Default since v8.25 +stat -c%N \' >> out || fail=1 +# Default before v8.25 +QUOTING_STYLE=locale stat -c%N \' >> out || fail=1 +cat <<\EOF >exp +"'" +'\'' +EOF +compare exp out || fail=1 + + Exit $fail