On 12/1/12 10:41 AM, Ulf Magnusson wrote:
> GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
>
> Take the following example, assumed to be run in an empty directory:
>
> $ mkdir a
> $ echo **
> a
> $ echo **/**
> a a
> $ echo **/**/**
> a a a
>
> I would expect the result to be just 'a' in all cases.
>
> You also get back a null filename, as shown by
>
> $ for f in **/**/**; do echo "'$f'"; done
> ''
> 'a'
> 'a'
> 'a'
Thanks for the report. This is definitely a problem. It will be fixed
in the next version of bash, and may be released as a future patch. I've
attached a patch for you to test; it fixes the problem for me without
introducing any new errors.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.2-patched/lib/glob/glob.c 2012-07-14 15:53:13.0 -0400
--- lib/glob/glob.c 2012-12-04 21:03:07.0 -0500
***
*** 934,938
--- 1075,1081
{
char **temp_results;
+ int shouldbreak;
+ shouldbreak = 0;
/* XXX -- we've recursively scanned any directories resulting from
a `**', so turn off the flag. We turn it on again below if
***
*** 966,970
name to the results; we've already done it in glob_vector */
if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
! array = temp_results;
else
array = glob_dir_to_array (directories[i], temp_results, flags);
--- 1109,1144
name to the results; we've already done it in glob_vector */
if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
! {
! /* When do we remove null elements from temp_results? And
! how to avoid duplicate elements in the final result? */
! /* If (dflags & GX_NULLDIR) glob_filename potentially left a
! NULL placeholder in the temp results just in case
! glob_vector/glob_dir_to_array did something with it, but
! if it didn't, and we're not supposed to be passing them
! through for some reason ((flags & GX_NULLDIR) == 0) we
! need to remove all the NULL elements from the beginning
! of TEMP_RESULTS. */
! /* If we have a null directory name and ** as the filename,
! we have just searched for everything from the current
! directory on down. Break now (shouldbreak = 1) to avoid
! duplicate entries in the final result. */
! #define NULL_PLACEHOLDER(x) ((x) && *(x) && **(x) == 0)
! if ((dflags & GX_NULLDIR) && (flags & GX_NULLDIR) == 0 &&
! NULL_PLACEHOLDER (temp_results))
! #undef NULL_PLACEHOLDER
! {
! register int i, n;
! for (n = 0; temp_results[n] && *temp_results[n] == 0; n++)
! ;
! i = n;
! do
! temp_results[i - n] = temp_results[i];
! while (temp_results[i++] != 0);
! array = temp_results;
! shouldbreak = 1;
! }
! else
! array = temp_results;
! }
else
array = glob_dir_to_array (directories[i], temp_results, flags);
***
*** 987,990
--- 1161,1169
if (array != temp_results)
free ((char *) array);
+ else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
+ free (temp_results); /* expanding ** case above */
+
+ if (shouldbreak)
+ break;
}
}