mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2026-10-24 02:08:57 +03:00
realpath: quote problematic names on tty
* doc/coreutils.texi: Mention $QUOTING_STYLE is significant. * src/realpath.c (print_relative_path): New function to buffer relative paths when quoting, and otherwise stream them. (main): Look up $QUOTING_STYLE when outputting to a tty and --zero is not specified. * tests/misc/realpath.sh: Add a test case. * NEWS: Mention the improvement.
This commit is contained in:
4
NEWS
4
NEWS
@@ -84,6 +84,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
'install -C' will now avoid updating file metadata when the destination
|
||||
already has the appropriate ownership and permissions.
|
||||
|
||||
'realpath' now quotes output in shell-escape style when
|
||||
standard output is a terminal. The QUOTING_STYLE environment variable
|
||||
can be used to adjust or disable the quoting.
|
||||
|
||||
'ls -m' now quotes files names containing commas when appropriate,
|
||||
so users can better distinguish separating commas.
|
||||
|
||||
|
||||
@@ -14596,6 +14596,11 @@ only on the file name, and does not touch any actual file.
|
||||
|
||||
@end table
|
||||
|
||||
When standard output is a terminal, file names are quoted using
|
||||
the @samp{shell-escape} style. The environment variable
|
||||
@env{QUOTING_STYLE} can select the quoting style. Valid quoting styles are:
|
||||
@quotingStyles
|
||||
|
||||
@cindex exit status of @command{realpath}
|
||||
Exit status:
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "argmatch.h" /* argmatch($QUOTING_STYLE). */
|
||||
#include "system.h"
|
||||
#include "canonicalize.h"
|
||||
#include "relpath.h"
|
||||
@@ -39,6 +40,7 @@ enum
|
||||
static bool verbose = true;
|
||||
static bool logical;
|
||||
static bool use_nuls;
|
||||
static bool quote_output;
|
||||
static char const *can_relative_to;
|
||||
static char const *can_relative_base;
|
||||
|
||||
@@ -164,6 +166,34 @@ isdir (char const *path)
|
||||
return S_ISDIR (sb.st_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
print_path (char const *path)
|
||||
{
|
||||
fputs (quote_output ? quoteN (path) : path, stdout);
|
||||
}
|
||||
|
||||
/* Print CAN_FNAME relative to can_relative_to, quoting the complete
|
||||
relative file name when appropriate. */
|
||||
static bool
|
||||
print_relative_path (char const *can_fname)
|
||||
{
|
||||
if (!quote_output)
|
||||
return relpath (can_fname, can_relative_to, NULL, 0);
|
||||
|
||||
size_t size;
|
||||
if (ckd_mul (&size, strlen (can_relative_to), 2)
|
||||
|| ckd_add (&size, size, strlen (can_fname))
|
||||
|| ckd_add (&size, size, 1))
|
||||
xalloc_die ();
|
||||
|
||||
char *relative_path = xmalloc (size);
|
||||
bool success = relpath (can_fname, can_relative_to, relative_path, size);
|
||||
if (success)
|
||||
print_path (relative_path);
|
||||
free (relative_path);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_path (char const *fname, int can_mode)
|
||||
{
|
||||
@@ -177,8 +207,8 @@ process_path (char const *fname, int can_mode)
|
||||
|
||||
if (!can_relative_to
|
||||
|| (can_relative_base && !path_prefix (can_relative_base, can_fname))
|
||||
|| (can_relative_to && !relpath (can_fname, can_relative_to, NULL, 0)))
|
||||
fputs (can_fname, stdout);
|
||||
|| (can_relative_to && !print_relative_path (can_fname)))
|
||||
print_path (can_fname);
|
||||
|
||||
putchar (use_nuls ? '\0' : '\n');
|
||||
|
||||
@@ -262,6 +292,18 @@ main (int argc, char **argv)
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (! use_nuls && isatty (STDOUT_FILENO))
|
||||
{
|
||||
int qs = getenv_quoting_style ();
|
||||
if (qs < 0)
|
||||
qs = shell_escape_quoting_style;
|
||||
if (qs != literal_quoting_style)
|
||||
{
|
||||
set_quoting_style (NULL, qs);
|
||||
quote_output = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (relative_base && !relative_to)
|
||||
relative_to = relative_base;
|
||||
|
||||
|
||||
@@ -57,6 +57,22 @@ realpath -e -E --relative-to=dir1/f --relative-base=. . || fail=1
|
||||
returns_ 1 realpath -m '' || fail=1
|
||||
returns_ 1 realpath --relative-base= --relative-to=. . || fail=1
|
||||
|
||||
# QUOTING_STYLE does not affect redirected output.
|
||||
printf 'q name\n' > exp || framework_failure_
|
||||
for style in literal shell-always invalid; do
|
||||
QUOTING_STYLE="$style" \
|
||||
realpath -m --relative-to=. 'q name' > out 2> err || fail=1
|
||||
compare exp out || fail=1
|
||||
compare /dev/null err || fail=1
|
||||
done
|
||||
|
||||
# --zero disables quoting, and does not inspect QUOTING_STYLE.
|
||||
QUOTING_STYLE=invalid \
|
||||
realpath -zm --relative-to=. 'q name' > out 2> err || fail=1
|
||||
printf 'q name\0' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
compare /dev/null err || fail=1
|
||||
|
||||
# symlink resolution
|
||||
this=$(realpath .)
|
||||
test "$(realpath ldir2/..)" = "$this/dir1" || fail=1
|
||||
|
||||
Reference in New Issue
Block a user