[PATCH 6/7] grep: Skip grepping symlinks to directories

Denys Vlasenko vda.linux at googlemail.com
Tue Oct 31 14:27:44 UTC 2017


Applied, thanks

On Sat, Oct 7, 2017 at 7:53 PM, James Clarke <jrtc27 at jrtc27.com> wrote:
> When grep is passed -r, recursive_action will treat any symlinks to
> directories not in the root as normal files, since it lstat's them and
> is therefore told they are not directories. However, file_action_grep
> will still try to fopen and read from them to see whether they match,
> which varies in behaviour across platforms. Linux will give EISDIR and
> thus grep will not find any matching lines, but FreeBSD will give the
> raw contents of the directory itself, which may match the given pattern.
> Also, if grep is passed -c, it will even print a count for these
> symlinks, even on Linux.
>
> Since this recursive_action behaviour is required for the correct
> functioning of other applets, such as tar, grep should handle this
> special case and skip any such symlinks.
>
> Signed-off-by: James Clarke <jrtc27 at jrtc27.com>
> ---
>  findutils/grep.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/findutils/grep.c b/findutils/grep.c
> index f72175afb..0cb0aac64 100644
> --- a/findutils/grep.c
> +++ b/findutils/grep.c
> @@ -639,11 +639,29 @@ static void load_regexes_from_file(llist_t *fopt)
>  }
>
>  static int FAST_FUNC file_action_grep(const char *filename,
> -                       struct stat *statbuf UNUSED_PARAM,
> +                       struct stat *statbuf,
>                         void* matched,
>                         int depth UNUSED_PARAM)
>  {
> -       FILE *file = fopen_for_read(filename);
> +       FILE *file;
> +       struct stat statbufFollow;
> +
> +       /* If we are given a link to a directory, we should bail out now, rather
> +        * than trying to open the "file" and hoping getline gives us nothing,
> +        * since that is not portable across operating systems (FreeBSD for example
> +        * will return the raw directory contents). */
> +       if (S_ISLNK(statbuf->st_mode)) {
> +               if (stat(filename, &statbufFollow) < 0) {
> +                       if (!SUPPRESS_ERR_MSGS)
> +                               bb_simple_perror_msg(filename);
> +                       return 0;
> +               }
> +
> +               if (S_ISDIR(statbufFollow.st_mode))
> +                       return 1;
> +       }
> +
> +       file = fopen_for_read(filename);
>         if (file == NULL) {
>                 if (!SUPPRESS_ERR_MSGS)
>                         bb_simple_perror_msg(filename);
> --
> 2.14.1
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list