Initial code to allow control over how -ls quote (or does not quote) control characters; not enabled yet

This commit is contained in:
James Youngman
2005-12-12 06:59:18 +00:00
parent 0fb6853f15
commit 2d5be965c2
10 changed files with 137 additions and 15 deletions

12
NEWS
View File

@@ -14,7 +14,7 @@ the configure option '--without-fts'.
New tests, -readable, -writable, -executable. These check that a file
can be read, written or executed respectively.
* Major changes in release 4.2.27-CVS
* Major changes in release 4.2.27
** Warnings of Future Changes
@@ -39,6 +39,10 @@ remounted elsewhere using "mount --bind". (Savannah bug #14921).
** Documentation Changes
Following some extensive and detailed review comments from Aaron
Hawley, the material in the manual pages and the Texinfo manual are
now synchronised.
The %M format specifier of "find -printf" is now documented, although
it has existed since release 4.2.5.
@@ -87,6 +91,12 @@ affected (albeit for longer command lines). In theory the same
problem could affect 'find -exec {} +', but that's much less likely
(even so, the bug is fixed there too).
Bugfix for an unusual failure mode (Savannah bug #14842) where an
attempt to allocate more space for directory contents succeeds but is
incorrectly diagnosed as a failure. The likelihood of you
experiencing this depends on your architecture, operating system and
resource limits. This failure has been observed in a directory
containing 35396 entries.
** Documentation Changes

View File

@@ -1421,6 +1421,47 @@ you are searching might contain a newline, you should use
@samp{-fprint0} instead.
@end deffn
@c @deffn Option -show-control-chars how
@c This option affects how some of @code{find}'s actions treat
@c unprintable characters in file names. If @samp{how} is
@c @samp{literal}, any subsequent actions (i.e. actions further on in the
@c command line) print file names as-is.
@c
@c If this option is not specified, it currently defaults to @samp{safe}.
@c If @samp{how} is @samp{safe}, C-like backslash escapes are used to
@c indicate the non-printable characters for @samp{-ls} and @samp{-fls}.
@c On the other hand, @samp{-print}, @samp{-fprint}, @samp{-fprintf} and
@c @code{-printf} all quote unprintable characters if the data is going
@c to a tty, and otherwise the data is emitted literally.
@c
@c @table @code
@c @item -ls
@c Escaped if @samp{how} is @samp{safe}
@c @item -fls
@c Escaped if @samp{how} is @samp{safe}
@c @item -print
@c Always quoted if stdout is a tty,
@c @samp{-show-control-chars} is ignored
@c @item -print0
@c Always literal, never escaped
@c @item -fprint
@c Always quoted if the destination is a tty;
@c @samp{-show-control-chars} is ignored
@c @item -fprint0
@c Always literal, never escaped
@c @item -fprintf
@c If the destination is a tty, the @samp{%f},
@c @samp{%F}, @samp{%h}, @samp{%l}, @samp{%p},
@c and @samp{%P} directives produce quoted
@c strings if stdout is a tty and are treated
@c literally otherwise.
@c @item -printf
@c As for @code{-fprintf}.
@c @end table
@c @end deffn
@node Print File Information
@section Print File Information

View File

@@ -308,6 +308,9 @@ struct predicate
/* True if this predicate node requires knowledge of the file type. */
boolean need_type;
/* True if this predicate should display control characters literally */
boolean literal_control_chars;
/* Information needed by the predicate processor.
Next to each member are listed the predicates that use it. */
union
@@ -356,7 +359,6 @@ char *dirname PARAMS((char *path));
void error PARAMS((int status, int errnum, char *message, ...));
/* listfile.c */
void list_file PARAMS((char *name, char *relname, struct stat *statp, time_t current_time, int output_block_size, FILE *stream));
char *get_link_name PARAMS((char *name, char *relname));
/* stpcpy.c */
@@ -549,9 +551,14 @@ struct options
* no longer exists by the time we get around to processing it.
*/
boolean ignore_readdir_race;
/* If true, pass control characters through. If false, escape them
* or turn them into harmless things.
*/
boolean literal_control_chars;
/* If true, we issue warning messages
*/
/* If true, we issue warning messages
*/
boolean warnings;
time_t start_time; /* Time at start of execution. */

View File

@@ -162,10 +162,12 @@ main (int argc, char **argv)
if (isatty(0))
{
options.warnings = true;
options.literal_control_chars = false;
}
else
{
options.warnings = false;
options.literal_control_chars = false; /* may change */
}

View File

@@ -445,10 +445,12 @@ main (int argc, char **argv)
if (isatty(0))
{
options.warnings = true;
options.literal_control_chars = false;
}
else
{
options.warnings = false;
options.literal_control_chars = false; /* may change */
}

View File

@@ -135,6 +135,7 @@ static boolean parse_readable PARAMS((const struct parser_table*, char *arg
static boolean parse_regex PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_regextype PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_samefile PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_show_control_chars PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_size PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_true PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_type PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
@@ -276,6 +277,9 @@ static struct parser_table const parse_table[] =
PARSE_TEST ("regex", regex), /* GNU */
PARSE_OPTION ("regextype", regextype), /* GNU */
PARSE_TEST ("samefile", samefile), /* GNU */
#if 0
PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */
#endif
PARSE_TEST ("size", size),
PARSE_TEST ("type", type),
PARSE_TEST ("uid", uid), /* GNU */
@@ -1644,6 +1648,42 @@ parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
return true;
}
#if 0
static boolean
parse_show_control_chars (const struct parser_table* entry, char **argv, int *arg_ptr)
{
const char *arg;
const char *errmsg = _("The -show-control-chars option takes a single argument which "
"must be 'literal' or 'safe'");
if ((argv == NULL) || (argv[*arg_ptr] == NULL))
{
error (1, errno, "%s", errmsg);
return false;
}
else
{
arg = argv[*arg_ptr];
if (0 == strcmp("literal", arg))
{
options.literal_control_chars = true;
}
else if (0 == strcmp("safe", arg))
{
options.literal_control_chars = false;
}
else
{
error (1, errno, "%s", errmsg);
return false;
}
(*arg_ptr)++; /* consume the argument. */
return true;
}
}
#endif
static boolean
parse_true (const struct parser_table* entry, char **argv, int *arg_ptr)

View File

@@ -37,6 +37,7 @@
#include "printquoted.h"
#include "buildcmd.h"
#include "yesno.h"
#include "listfile.h"
#if ENABLE_NLS
# include <libintl.h>
@@ -527,8 +528,9 @@ boolean
pred_fls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
options.output_block_size, pred_ptr->args.stream);
return (true);
options.output_block_size,
pred_ptr->literal_control_chars, pred_ptr->args.stream);
return true;
}
boolean
@@ -1060,11 +1062,11 @@ insert_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr,
boolean
pred_ls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
(void) pred_ptr;
list_file (pathname, state.rel_pathname, stat_buf, options.start_time,
options.output_block_size, stdout);
return (true);
options.output_block_size,
pred_ptr->literal_control_chars,
stdout);
return true;
}
boolean

View File

@@ -92,7 +92,8 @@ get_new_pred (const struct parser_table *entry)
last_pred->pred_next = NULL;
last_pred->pred_left = NULL;
last_pred->pred_right = NULL;
return (last_pred);
last_pred->literal_control_chars = options.literal_control_chars;
return last_pred;
}
/* Return a pointer to a new predicate, with operator check.

View File

@@ -178,7 +178,7 @@ struct group *getgrgid ();
char * get_link_name (char *name, char *relname);
static void print_name_with_quoting (register char *p, FILE *stream);
static void print_name (register char *p, FILE *stream, int literal_control_chars);
extern char * getgroup (gid_t gid);
extern char * getuser (uid_t uid);
@@ -198,6 +198,7 @@ list_file (char *name,
struct stat *statp,
time_t current_time,
int output_block_size,
int literal_control_chars,
FILE *stream)
{
char modebuf[11];
@@ -302,7 +303,7 @@ list_file (char *name,
1, 1));
}
print_name_with_quoting (name, stream);
print_name (name, stream, literal_control_chars);
#ifdef S_ISLNK
if (S_ISLNK (statp->st_mode))
@@ -312,7 +313,7 @@ list_file (char *name,
if (linkname)
{
fputs (" -> ", stream);
print_name_with_quoting (linkname, stream);
print_name (linkname, stream, literal_control_chars);
free (linkname);
}
}
@@ -320,6 +321,14 @@ list_file (char *name,
putc ('\n', stream);
}
static void
print_name_without_quoting (char *p, FILE *stream)
{
fprintf(stream, "%s", p);
}
static void
print_name_with_quoting (register char *p, FILE *stream)
{
@@ -370,6 +379,14 @@ print_name_with_quoting (register char *p, FILE *stream)
}
}
static void print_name (register char *p, FILE *stream, int literal_control_chars)
{
if (literal_control_chars)
print_name_without_quoting(p, stream);
else
print_name_with_quoting(p, stream);
}
#ifdef S_ISLNK
char *
get_link_name (char *name, char *relname)

View File

@@ -21,7 +21,7 @@
#if !defined LISTFILE_H
# define LISTFILE_H
void list_file (char *name, char *relname, struct stat *statp, time_t current_time, int output_block_size, FILE *stream);
void list_file (char *name, char *relname, struct stat *statp, time_t current_time, int output_block_size, int literal_control_chars, FILE *stream);