1 --- glob.c.orig 2004-11-25 11:38:01.000000000 -0800
2 +++ glob.c 2006-07-04 12:47:05.000000000 -0700
5 __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.22 2004/07/29 03:48:52 tjr Exp $");
7 +#include "xlocale_private.h"
10 * glob(3) -- a superset of the one defined in POSIX 1003.2.
13 #define M_SET META('[')
14 #define ismeta(c) (((c)&M_QUOTE) != 0)
16 +static int g_lstat(Char *, struct stat *, glob_t *, locale_t);
17 +static int g_stat(Char *, struct stat *, glob_t *, locale_t);
19 +#define g_Ctoc __gl_g_Ctoc
20 +#define glob0 __gl_glob0
21 +#define glob2_32 __gl_glob0_32
22 +#define glob2_64 __gl_glob0_64
23 +#define glob3 __gl_glob3
24 +#define globexp1 __gl_globexp1
25 +#define globextend __gl_globextend
26 +__private_extern__ int g_Ctoc(const Char *, char *, u_int, locale_t);
27 +__private_extern__ int glob0(const Char *, glob_t *, int *, locale_t);
28 +__private_extern__ int glob2_32(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t);
29 +__private_extern__ int glob2_64(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t);
30 +__private_extern__ int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *, locale_t);
31 +__private_extern__ int globexp1(const Char *, glob_t *, int *, locale_t);
32 +__private_extern__ int globextend(const Char *, glob_t *, int *, locale_t);
34 +#ifndef BUILDING_VARIANT
35 +#define glob2(a,b,c,d,e,f,g) (((e)->gl_flags & GLOB_INODE64) ? glob2_64((a),(b),(c),(d),(e),(f),(g)) : glob2_32((a),(b),(c),(d),(e),(f),(g)))
37 static int compare(const void *, const void *);
38 -static int g_Ctoc(const Char *, char *, u_int);
39 -static int g_lstat(Char *, struct stat *, glob_t *);
40 -static DIR *g_opendir(Char *, glob_t *);
41 +static DIR *g_opendir(Char *, glob_t *, locale_t);
42 static Char *g_strchr(Char *, wchar_t);
44 static Char *g_strcat(Char *, const Char *);
46 -static int g_stat(Char *, struct stat *, glob_t *);
47 -static int glob0(const Char *, glob_t *, int *);
48 -static int glob1(Char *, glob_t *, int *);
49 -static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *);
50 -static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *);
51 -static int globextend(const Char *, glob_t *, int *);
52 +static int glob1(Char *, glob_t *, int *, locale_t);
54 globtilde(const Char *, Char *, size_t, glob_t *);
55 -static int globexp1(const Char *, glob_t *, int *);
56 -static int globexp2(const Char *, const Char *, glob_t *, int *, int *);
57 -static int match(Char *, Char *, Char *);
58 +static int globexp2(const Char *, const Char *, glob_t *, int *, int *, locale_t);
59 +static int match(Char *, Char *, Char *, locale_t);
61 static void qprintf(const char *, Char *);
63 +#endif /* !BUILDING_VARIANT */
66 glob(pattern, flags, errfunc, pglob)
71 + locale_t loc = __current_locale();
72 + int mb_cur_max = MB_CUR_MAX_L(loc);
74 patnext = (u_char *) pattern;
75 if (!(flags & GLOB_APPEND)) {
80 +#if __DARWIN_64_BIT_INO_T
81 pglob->gl_flags = flags & ~GLOB_MAGCHAR;
82 + pglob->gl_flags |= GLOB_INODE64;
83 +#else /* !__DARWIN_64_BIT_INO_T */
84 + pglob->gl_flags = flags & ~(GLOB_MAGCHAR | GLOB_INODE64);
85 +#endif /* __DARWIN_64_BIT_INO_T */
86 pglob->gl_errfunc = errfunc;
90 bufend = bufnext + MAXPATHLEN - 1;
91 if (flags & GLOB_NOESCAPE) {
92 memset(&mbs, 0, sizeof(mbs));
93 - while (bufend - bufnext >= MB_CUR_MAX) {
94 - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
95 + while (bufend - bufnext >= mb_cur_max) {
96 + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc);
97 if (clen == (size_t)-1 || clen == (size_t)-2)
98 return (GLOB_NOMATCH);
102 /* Protect the quoted characters. */
103 memset(&mbs, 0, sizeof(mbs));
104 - while (bufend - bufnext >= MB_CUR_MAX) {
105 + while (bufend - bufnext >= mb_cur_max) {
106 if (*patnext == QUOTE) {
107 if (*++patnext == EOS) {
108 *bufnext++ = QUOTE | M_PROTECT;
113 - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
114 + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc);
115 if (clen == (size_t)-1 || clen == (size_t)-2)
116 return (GLOB_NOMATCH);
118 @@ -233,34 +255,36 @@
121 if (flags & GLOB_BRACE)
122 - return globexp1(patbuf, pglob, &limit);
123 + return globexp1(patbuf, pglob, &limit, loc);
125 - return glob0(patbuf, pglob, &limit);
126 + return glob0(patbuf, pglob, &limit, loc);
129 +#ifndef BUILDING_VARIANT
131 * Expand recursively a glob {} pattern. When there is no more expansion
132 * invoke the standard globbing routine to glob the rest of the magic
136 -globexp1(pattern, pglob, limit)
137 +__private_extern__ int
138 +globexp1(pattern, pglob, limit, loc)
144 const Char* ptr = pattern;
147 /* Protect a single {}, for find(1), like csh */
148 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
149 - return glob0(pattern, pglob, limit);
150 + return glob0(pattern, pglob, limit, loc);
152 while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
153 - if (!globexp2(ptr, pattern, pglob, &rv, limit))
154 + if (!globexp2(ptr, pattern, pglob, &rv, limit, loc))
157 - return glob0(pattern, pglob, limit);
158 + return glob0(pattern, pglob, limit, loc);
162 @@ -270,10 +294,11 @@
163 * If it fails then it tries to glob the rest of the pattern and returns.
166 -globexp2(ptr, pattern, pglob, rv, limit)
167 +globexp2(ptr, pattern, pglob, rv, limit, loc)
168 const Char *ptr, *pattern;
177 /* Non matching braces; just glob the pattern */
178 if (i != 0 || *pe == EOS) {
179 - *rv = glob0(patbuf, pglob, limit);
180 + *rv = glob0(patbuf, pglob, limit, loc);
186 qprintf("globexp2:", patbuf);
188 - *rv = globexp1(patbuf, pglob, limit);
189 + *rv = globexp1(patbuf, pglob, limit, loc);
191 /* move after the comma, to the next string */
193 @@ -446,14 +471,16 @@
194 * sorts the list (unless unsorted operation is requested). Returns 0
195 * if things went well, nonzero if errors occurred.
198 -glob0(pattern, pglob, limit)
199 +__private_extern__ int
200 +glob0(pattern, pglob, limit, loc)
206 const Char *qpatnext;
207 - int c, err, oldpathc;
210 Char *bufnext, patbuf[MAXPATHLEN];
212 qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
215 /* We don't need to check for buffer overflow any more. */
216 while ((c = *qpatnext++) != EOS) {
217 + if (c & M_PROTECT) {
218 + *bufnext++ = CHAR(c);
225 qprintf("glob0:", patbuf);
228 - if ((err = glob1(patbuf, pglob, limit)) != 0)
229 + if ((err = glob1(patbuf, pglob, limit, loc)) != 0)
234 if (((pglob->gl_flags & GLOB_NOCHECK) ||
235 ((pglob->gl_flags & GLOB_NOMAGIC) &&
236 !(pglob->gl_flags & GLOB_MAGCHAR))))
237 - return(globextend(pattern, pglob, limit));
238 + return(globextend(pattern, pglob, limit, loc));
240 return(GLOB_NOMATCH);
242 @@ -539,14 +570,15 @@
246 - return(strcmp(*(char **)p, *(char **)q));
247 + return(strcoll(*(char **)p, *(char **)q));
251 -glob1(pattern, pglob, limit)
252 +glob1(pattern, pglob, limit, loc)
258 Char pathbuf[MAXPATHLEN];
260 @@ -554,19 +586,25 @@
263 return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1,
264 - pattern, pglob, limit));
265 + pattern, pglob, limit, loc));
267 +#endif /* !BUILDING_VARIANT */
270 * The functions glob2 and glob3 are mutually recursive; there is one level
271 * of recursion for each segment in the pattern that contains one or more
275 -glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit)
276 +__private_extern__ int
277 +#if __DARWIN_64_BIT_INO_T
278 +glob2_64(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc)
279 +#else /* !__DARWIN_64_BIT_INO_T */
280 +glob2_32(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc)
281 +#endif /* __DARWIN_64_BIT_INO_T */
282 Char *pathbuf, *pathend, *pathend_last, *pattern;
289 @@ -579,13 +617,13 @@
290 for (anymeta = 0;;) {
291 if (*pattern == EOS) { /* End of pattern? */
293 - if (g_lstat(pathbuf, &sb, pglob))
294 + if (g_lstat(pathbuf, &sb, pglob, loc))
297 if (((pglob->gl_flags & GLOB_MARK) &&
298 pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
299 || (S_ISLNK(sb.st_mode) &&
300 - (g_stat(pathbuf, &sb, pglob) == 0) &&
301 + (g_stat(pathbuf, &sb, pglob, loc) == 0) &&
302 S_ISDIR(sb.st_mode)))) {
303 if (pathend + 1 > pathend_last)
304 return (GLOB_ABORTED);
309 - return(globextend(pathbuf, pglob, limit));
310 + return(globextend(pathbuf, pglob, limit, loc));
313 /* Find end of next segment, copy tentatively to pathend. */
314 @@ -617,16 +655,18 @@
316 } else /* Need expansion, recurse. */
317 return(glob3(pathbuf, pathend, pathend_last, pattern, p,
319 + pglob, limit, loc));
325 -glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit)
326 +#ifndef BUILDING_VARIANT
327 +__private_extern__ int
328 +glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit, loc)
329 Char *pathbuf, *pathend, *pathend_last, *pattern, *restpattern;
336 @@ -646,15 +686,16 @@
340 - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
341 + if ((dirp = g_opendir(pathbuf, pglob, loc)) == NULL) {
342 /* TODO: don't call for ENOENT or ENOTDIR? */
343 if (pglob->gl_errfunc) {
344 - if (g_Ctoc(pathbuf, buf, sizeof(buf)))
345 + if (g_Ctoc(pathbuf, buf, sizeof(buf), loc))
346 return (GLOB_ABORTED);
347 - if (pglob->gl_errfunc(buf, errno) ||
348 - pglob->gl_flags & GLOB_ERR)
349 + if (pglob->gl_errfunc(buf, errno))
350 return (GLOB_ABORTED);
352 + if (pglob->gl_flags & GLOB_ERR)
353 + return (GLOB_ABORTED);
359 sc = (u_char *) dp->d_name;
360 while (dc < pathend_last) {
361 - clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
362 + clen = mbrtowc_l(&wc, (const char *)sc, MB_LEN_MAX, &mbs, loc);
363 if (clen == (size_t)-1 || clen == (size_t)-2) {
366 @@ -689,12 +730,12 @@
370 - if (!match(pathend, pattern, restpattern)) {
371 + if (!match(pathend, pattern, restpattern, loc)) {
375 err = glob2(pathbuf, --dc, pathend_last, restpattern,
377 + pglob, limit, loc);
381 @@ -721,11 +762,12 @@
382 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
383 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
386 -globextend(path, pglob, limit)
387 +__private_extern__ int
388 +globextend(path, pglob, limit, loc)
398 for (p = path; *p++;)
400 - len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */
401 + len = MB_CUR_MAX_L(loc) * (size_t)(p - path); /* XXX overallocation */
402 if ((copy = malloc(len)) != NULL) {
403 - if (g_Ctoc(path, copy, len)) {
404 + if (g_Ctoc(path, copy, len, loc)) {
406 return (GLOB_NOSPACE);
409 * pattern causes a recursion level.
412 -match(name, pat, patend)
413 +match(name, pat, patend, loc)
414 Char *name, *pat, *patend;
417 int ok, negate_range;
423 - if (match(name, pat, patend))
424 + if (match(name, pat, patend, loc))
426 while (*name++ != EOS);
428 @@ -806,10 +849,10 @@
430 while (((c = *pat++) & M_MASK) != M_END)
431 if ((*pat & M_MASK) == M_RNG) {
432 - if (__collate_load_error ?
433 + if (loc->__collate_load_error ?
434 CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) :
435 - __collate_range_cmp(CHAR(c), CHAR(k)) <= 0
436 - && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0
437 + __collate_range_cmp(CHAR(c), CHAR(k), loc) <= 0
438 + && __collate_range_cmp(CHAR(k), CHAR(pat[1]), loc) <= 0
442 @@ -846,16 +889,17 @@
446 -g_opendir(str, pglob)
447 +g_opendir(str, pglob, loc)
452 char buf[MAXPATHLEN];
457 - if (g_Ctoc(str, buf, sizeof(buf)))
458 + if (g_Ctoc(str, buf, sizeof(buf), loc))
462 @@ -864,16 +908,18 @@
464 return(opendir(buf));
466 +#endif /* !BUILDING_VARIANT */
469 -g_lstat(fn, sb, pglob)
470 +g_lstat(fn, sb, pglob, loc)
476 char buf[MAXPATHLEN];
478 - if (g_Ctoc(fn, buf, sizeof(buf))) {
479 + if (g_Ctoc(fn, buf, sizeof(buf), loc)) {
480 errno = ENAMETOOLONG;
483 @@ -883,14 +929,15 @@
487 -g_stat(fn, sb, pglob)
488 +g_stat(fn, sb, pglob, loc)
494 char buf[MAXPATHLEN];
496 - if (g_Ctoc(fn, buf, sizeof(buf))) {
497 + if (g_Ctoc(fn, buf, sizeof(buf), loc)) {
498 errno = ENAMETOOLONG;
502 return(stat(buf, sb));
505 +#ifndef BUILDING_VARIANT
509 @@ -911,18 +959,20 @@
514 -g_Ctoc(str, buf, len)
515 +__private_extern__ int
516 +g_Ctoc(str, buf, len, loc)
524 + int mb_cur_max = MB_CUR_MAX_L(loc);
526 memset(&mbs, 0, sizeof(mbs));
527 - while (len >= MB_CUR_MAX) {
528 - clen = wcrtomb(buf, *str, &mbs);
529 + while (len >= mb_cur_max) {
530 + clen = wcrtomb_l(buf, *str, &mbs, loc);
531 if (clen == (size_t)-1)
538 +#endif /* !BUILDING_VARIANT */