diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | doc/coreutils.texi | 10 | ||||
-rw-r--r-- | src/stat.c | 41 | ||||
-rwxr-xr-x | tests/misc/stat-fmt.sh | 15 |
4 files changed, 62 insertions, 7 deletions
@@ -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 95419b44e..927e552ab 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 53a6cb7bb..a43eca4d2 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 baa7ca775..1245ddb9e 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 |