mirror of
git://git.sv.gnu.org/findutils.git
synced 2026-01-28 20:43:21 +01:00
Initial code to allow control over how -ls quote (or does not quote) control characters; not enabled yet
This commit is contained in:
12
NEWS
12
NEWS
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
13
find/defs.h
13
find/defs.h
@@ -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. */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
14
find/pred.c
14
find/pred.c
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user