]> git.saurik.com Git - apple/libc.git/blame - gen/FreeBSD/glob.c.patch
Libc-763.12.tar.gz
[apple/libc.git] / gen / FreeBSD / glob.c.patch
CommitLineData
fbd86d4c
A
1--- glob.c.orig 2011-01-25 17:41:37.000000000 -0800
2+++ glob.c 2011-01-26 11:50:09.000000000 -0800
3@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)glob.c 8.3 (
3d9156a7 4 #include <sys/cdefs.h>
fbd86d4c 5 __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.28 2010/05/12 17:44:00 gordon Exp $");
3d9156a7
A
6
7+#include "xlocale_private.h"
8+
9 /*
10 * glob(3) -- a superset of the one defined in POSIX 1003.2.
11 *
fbd86d4c
A
12@@ -89,6 +91,19 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/glo
13
14 #include "collate.h"
15
16+#define GLOB_LIMIT_STRING 65536 /* number of readdirs */
17+#define GLOB_LIMIT_STAT 128 /* number of stat system calls */
18+#define GLOB_LIMIT_READDIR 16384 /* total buffer size of path strings */
19+#define GLOB_LIMIT_PATH 1024 /* number of path elements */
20+#define GLOB_LIMIT_BRACE 128 /* Number of brace calls */
21+
22+struct glob_limit {
23+ size_t l_string;
24+ size_t l_stat;
25+ size_t l_readdir;
26+ size_t l_brace;
27+};
28+
29 #define DOLLAR '$'
30 #define DOT '.'
31 #define EOS '\0'
32@@ -139,62 +154,64 @@ typedef char Char;
224c7076 33 #define ismeta(c) (((c)&M_QUOTE) != 0)
3d9156a7 34
b5d655f7
A
35
36-static int compare(const void *, const void *);
fbd86d4c 37-static int g_Ctoc(const Char *, char *, size_t);
b5d655f7
A
38-static int g_lstat(Char *, struct stat *, glob_t *);
39-static DIR *g_opendir(Char *, glob_t *);
fbd86d4c 40-static const Char *g_strchr(const Char *, wchar_t);
b5d655f7 41+#define compare __gl_compare
224c7076 42+#define g_Ctoc __gl_g_Ctoc
b5d655f7 43+#define g_strchr __gl_g_strchr
224c7076 44+#define globextend __gl_globextend
b5d655f7
A
45+#define globtilde __gl_globtilde
46+#define match __gl_match
fbd86d4c
A
47+__private_extern__ int compare(const void *, const void *);
48+__private_extern__ int g_Ctoc(const Char *, char *, size_t, locale_t);
49+__private_extern__ const Char *g_strchr(const Char *, wchar_t);
50+__private_extern__ int globextend(const Char *, glob_t *, struct glob_limit *, locale_t);
b5d655f7
A
51+__private_extern__ const Char *
52+ globtilde(const Char *, Char *, size_t, glob_t *);
fbd86d4c 53+__private_extern__ int match(Char *, Char *, Char *, locale_t);
224c7076 54+
b5d655f7
A
55+
56+static int g_lstat(Char *, struct stat *, glob_t *, locale_t);
3d9156a7 57+static DIR *g_opendir(Char *, glob_t *, locale_t);
3d9156a7
A
58 #ifdef notdef
59 static Char *g_strcat(Char *, const Char *);
60 #endif
61-static int g_stat(Char *, struct stat *, glob_t *);
fbd86d4c
A
62-static int glob0(const Char *, glob_t *, size_t *);
63-static int glob1(Char *, glob_t *, size_t *);
64-static int glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *);
65-static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *);
66-static int globextend(const Char *, glob_t *, size_t *);
b5d655f7
A
67-static const Char *
68- globtilde(const Char *, Char *, size_t, glob_t *);
fbd86d4c
A
69-static int globexp1(const Char *, glob_t *, size_t *);
70-static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *);
3d9156a7 71-static int match(Char *, Char *, Char *);
b5d655f7 72+static int g_stat(Char *, struct stat *, glob_t *, locale_t);
fbd86d4c
A
73+static int glob0(const Char *, glob_t *, struct glob_limit *, locale_t);
74+static int glob1(Char *, glob_t *, struct glob_limit *, locale_t);
75+static int glob2(Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *, locale_t);
76+static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *, locale_t);
77+static int globexp1(const Char *, glob_t *, struct glob_limit *, locale_t);
78+static int globexp2(const Char *, const Char *, glob_t *, int *, struct glob_limit *, locale_t);
3d9156a7
A
79 #ifdef DEBUG
80 static void qprintf(const char *, Char *);
81 #endif
34e8f829
A
82
83-int
fbd86d4c 84-glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob)
34e8f829 85+static int
fbd86d4c 86+__glob(const char *pattern, glob_t *pglob)
34e8f829 87 {
fbd86d4c
A
88 const char *patnext;
89- size_t limit;
90+ struct glob_limit limit = { 0, 0, 0, 0 };
91 Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot;
3d9156a7
A
92 mbstate_t mbs;
93 wchar_t wc;
94 size_t clen;
95+ locale_t loc = __current_locale();
96+ int mb_cur_max = MB_CUR_MAX_L(loc);
97
fbd86d4c 98 patnext = pattern;
34e8f829
A
99- if (!(flags & GLOB_APPEND)) {
100+ if (!(pglob->gl_flags & GLOB_APPEND)) {
101 pglob->gl_pathc = 0;
102 pglob->gl_pathv = NULL;
103- if (!(flags & GLOB_DOOFFS))
104+ if (!(pglob->gl_flags & GLOB_DOOFFS))
105 pglob->gl_offs = 0;
106 }
107- if (flags & GLOB_LIMIT) {
fbd86d4c
A
108- limit = pglob->gl_matchc;
109- if (limit == 0)
110- limit = ARG_MAX;
111- } else
112- limit = 0;
34e8f829
A
113- pglob->gl_flags = flags & ~GLOB_MAGCHAR;
114- pglob->gl_errfunc = errfunc;
115 pglob->gl_matchc = 0;
116
117 bufnext = patbuf;
3d9156a7 118 bufend = bufnext + MAXPATHLEN - 1;
34e8f829
A
119- if (flags & GLOB_NOESCAPE) {
120+ if (pglob->gl_flags & GLOB_NOESCAPE) {
3d9156a7
A
121 memset(&mbs, 0, sizeof(mbs));
122- while (bufend - bufnext >= MB_CUR_MAX) {
123- clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
124+ while (bufend - bufnext >= mb_cur_max) {
fbd86d4c 125+ clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc);
3d9156a7
A
126 if (clen == (size_t)-1 || clen == (size_t)-2)
127 return (GLOB_NOMATCH);
128 else if (clen == 0)
fbd86d4c 129@@ -205,7 +222,7 @@ glob(const char *pattern, int flags, int
3d9156a7
A
130 } else {
131 /* Protect the quoted characters. */
132 memset(&mbs, 0, sizeof(mbs));
133- while (bufend - bufnext >= MB_CUR_MAX) {
134+ while (bufend - bufnext >= mb_cur_max) {
135 if (*patnext == QUOTE) {
136 if (*++patnext == EOS) {
137 *bufnext++ = QUOTE | M_PROTECT;
fbd86d4c 138@@ -214,7 +231,7 @@ glob(const char *pattern, int flags, int
3d9156a7
A
139 prot = M_PROTECT;
140 } else
141 prot = 0;
142- clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
fbd86d4c 143+ clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc);
3d9156a7
A
144 if (clen == (size_t)-1 || clen == (size_t)-2)
145 return (GLOB_NOMATCH);
146 else if (clen == 0)
fbd86d4c 147@@ -225,11 +242,34 @@ glob(const char *pattern, int flags, int
34e8f829 148 }
3d9156a7
A
149 *bufnext = EOS;
150
34e8f829 151- if (flags & GLOB_BRACE)
3d9156a7 152- return globexp1(patbuf, pglob, &limit);
34e8f829 153+ if (pglob->gl_flags & GLOB_BRACE)
3d9156a7
A
154+ return globexp1(patbuf, pglob, &limit, loc);
155 else
156- return glob0(patbuf, pglob, &limit);
157+ return glob0(patbuf, pglob, &limit, loc);
34e8f829
A
158+}
159+
160+int
fbd86d4c 161+glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob)
34e8f829
A
162+{
163+#ifdef __BLOCKS__
164+ pglob->gl_flags = flags & ~(GLOB_MAGCHAR | _GLOB_ERR_BLOCK);
165+#else /* !__BLOCKS__ */
166+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
167+#endif /* __BLOCKS__ */
168+ pglob->gl_errfunc = errfunc;
169+ return __glob(pattern, pglob);
170+}
171+
172+#ifdef __BLOCKS__
173+int
fbd86d4c 174+glob_b(const char *pattern, int flags, int (^errblk)(const char *, int), glob_t *pglob)
34e8f829
A
175+{
176+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
177+ pglob->gl_flags |= _GLOB_ERR_BLOCK;
178+ pglob->gl_errblk = errblk;
179+ return __glob(pattern, pglob);
3d9156a7 180 }
34e8f829 181+#endif /* __BLOCKS__ */
3d9156a7
A
182
183 /*
34e8f829 184 * Expand recursively a glob {} pattern. When there is no more expansion
fbd86d4c 185@@ -237,20 +277,26 @@ glob(const char *pattern, int flags, int
3d9156a7
A
186 * characters
187 */
b5d655f7 188 static int
fbd86d4c
A
189-globexp1(const Char *pattern, glob_t *pglob, size_t *limit)
190+globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
191 {
192 const Char* ptr = pattern;
193 int rv;
194
fbd86d4c
A
195+ if ((pglob->gl_flags & GLOB_LIMIT) &&
196+ limit->l_brace++ >= GLOB_LIMIT_BRACE) {
197+ errno = 0;
198+ return GLOB_NOSPACE;
199+ }
200+
3d9156a7
A
201 /* Protect a single {}, for find(1), like csh */
202 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
203- return glob0(pattern, pglob, limit);
204+ return glob0(pattern, pglob, limit, loc);
205
fbd86d4c 206 while ((ptr = g_strchr(ptr, LBRACE)) != NULL)
3d9156a7
A
207- if (!globexp2(ptr, pattern, pglob, &rv, limit))
208+ if (!globexp2(ptr, pattern, pglob, &rv, limit, loc))
209 return rv;
210
211- return glob0(pattern, pglob, limit);
212+ return glob0(pattern, pglob, limit, loc);
213 }
214
215
fbd86d4c 216@@ -260,7 +306,7 @@ globexp1(const Char *pattern, glob_t *pg
3d9156a7
A
217 * If it fails then it tries to glob the rest of the pattern and returns.
218 */
219 static int
fbd86d4c
A
220-globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, size_t *limit)
221+globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, struct glob_limit *limit, locale_t loc)
3d9156a7
A
222 {
223 int i;
224 Char *lm, *ls;
fbd86d4c 225@@ -297,7 +343,7 @@ globexp2(const Char *ptr, const Char *pa
3d9156a7
A
226
227 /* Non matching braces; just glob the pattern */
228 if (i != 0 || *pe == EOS) {
229- *rv = glob0(patbuf, pglob, limit);
230+ *rv = glob0(patbuf, pglob, limit, loc);
231 return 0;
232 }
233
fbd86d4c 234@@ -344,7 +390,7 @@ globexp2(const Char *ptr, const Char *pa
3d9156a7
A
235 #ifdef DEBUG
236 qprintf("globexp2:", patbuf);
237 #endif
238- *rv = globexp1(patbuf, pglob, limit);
239+ *rv = globexp1(patbuf, pglob, limit, loc);
240
241 /* move after the comma, to the next string */
242 pl = pm + 1;
fbd86d4c 243@@ -360,10 +406,11 @@ globexp2(const Char *ptr, const Char *pa
b5d655f7
A
244
245
246
247+#ifndef BUILDING_VARIANT
248 /*
249 * expand tilde from the passwd file.
250 */
251-static const Char *
252+__private_extern__ const Char *
fbd86d4c
A
253 globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
254 {
255 struct passwd *pwd;
256@@ -421,6 +468,7 @@ globtilde(const Char *pattern, Char *pat
b5d655f7
A
257
258 return patbuf;
259 }
260+#endif /* BUILDING_VARIANT */
261
262
263 /*
fbd86d4c 264@@ -430,7 +478,7 @@ globtilde(const Char *pattern, Char *pat
3d9156a7
A
265 * if things went well, nonzero if errors occurred.
266 */
b5d655f7 267 static int
fbd86d4c
A
268-glob0(const Char *pattern, glob_t *pglob, size_t *limit)
269+glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
270 {
271 const Char *qpatnext;
fbd86d4c
A
272 int err;
273@@ -443,6 +491,10 @@ glob0(const Char *pattern, glob_t *pglob
224c7076
A
274
275 /* We don't need to check for buffer overflow any more. */
276 while ((c = *qpatnext++) != EOS) {
277+ if (c & M_PROTECT) {
278+ *bufnext++ = CHAR(c);
279+ continue;
280+ } /* else */
281 switch (c) {
282 case LBRACKET:
283 c = *qpatnext;
fbd86d4c 284@@ -493,7 +545,7 @@ glob0(const Char *pattern, glob_t *pglob
3d9156a7
A
285 qprintf("glob0:", patbuf);
286 #endif
287
288- if ((err = glob1(patbuf, pglob, limit)) != 0)
289+ if ((err = glob1(patbuf, pglob, limit, loc)) != 0)
290 return(err);
291
292 /*
fbd86d4c 293@@ -506,7 +558,7 @@ glob0(const Char *pattern, glob_t *pglob
3d9156a7
A
294 if (((pglob->gl_flags & GLOB_NOCHECK) ||
295 ((pglob->gl_flags & GLOB_NOMAGIC) &&
296 !(pglob->gl_flags & GLOB_MAGCHAR))))
297- return(globextend(pattern, pglob, limit));
298+ return(globextend(pattern, pglob, limit, loc));
299 else
300 return(GLOB_NOMATCH);
301 }
fbd86d4c 302@@ -516,14 +568,16 @@ glob0(const Char *pattern, glob_t *pglob
b5d655f7
A
303 return(0);
304 }
305
306-static int
307+#ifndef BUILDING_VARIANT
308+__private_extern__ int
fbd86d4c 309 compare(const void *p, const void *q)
224c7076
A
310 {
311- return(strcmp(*(char **)p, *(char **)q));
312+ return(strcoll(*(char **)p, *(char **)q));
3d9156a7 313 }
b5d655f7 314+#endif /* BUILDING_VARIANT */
3d9156a7
A
315
316 static int
fbd86d4c
A
317-glob1(Char *pattern, glob_t *pglob, size_t *limit)
318+glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
319 {
320 Char pathbuf[MAXPATHLEN];
321
fbd86d4c 322@@ -531,7 +585,7 @@ glob1(Char *pattern, glob_t *pglob, size
3d9156a7
A
323 if (*pattern == EOS)
324 return(0);
325 return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1,
326- pattern, pglob, limit));
327+ pattern, pglob, limit, loc));
328 }
329
330 /*
fbd86d4c 331@@ -541,7 +595,7 @@ glob1(Char *pattern, glob_t *pglob, size
3d9156a7 332 */
b5d655f7 333 static int
fbd86d4c
A
334 glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern,
335- glob_t *pglob, size_t *limit)
336+ glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
337 {
338 struct stat sb;
339 Char *p, *q;
fbd86d4c 340@@ -554,13 +608,20 @@ glob2(Char *pathbuf, Char *pathend, Char
3d9156a7
A
341 for (anymeta = 0;;) {
342 if (*pattern == EOS) { /* End of pattern? */
343 *pathend = EOS;
344- if (g_lstat(pathbuf, &sb, pglob))
345+ if (g_lstat(pathbuf, &sb, pglob, loc))
346 return(0);
347
fbd86d4c
A
348+ if ((pglob->gl_flags & GLOB_LIMIT) &&
349+ limit->l_stat++ >= GLOB_LIMIT_STAT) {
350+ errno = 0;
351+ *pathend++ = SEP;
352+ *pathend = EOS;
353+ return GLOB_NOSPACE;
354+ }
3d9156a7
A
355 if (((pglob->gl_flags & GLOB_MARK) &&
356 pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
357 || (S_ISLNK(sb.st_mode) &&
358- (g_stat(pathbuf, &sb, pglob) == 0) &&
359+ (g_stat(pathbuf, &sb, pglob, loc) == 0) &&
360 S_ISDIR(sb.st_mode)))) {
361 if (pathend + 1 > pathend_last)
362 return (GLOB_ABORTED);
fbd86d4c 363@@ -568,7 +629,7 @@ glob2(Char *pathbuf, Char *pathend, Char
3d9156a7
A
364 *pathend = EOS;
365 }
366 ++pglob->gl_matchc;
367- return(globextend(pathbuf, pglob, limit));
368+ return(globextend(pathbuf, pglob, limit, loc));
369 }
370
371 /* Find end of next segment, copy tentatively to pathend. */
fbd86d4c 372@@ -592,7 +653,7 @@ glob2(Char *pathbuf, Char *pathend, Char
3d9156a7
A
373 }
374 } else /* Need expansion, recurse. */
375 return(glob3(pathbuf, pathend, pathend_last, pattern, p,
376- pglob, limit));
377+ pglob, limit, loc));
378 }
379 /* NOTREACHED */
380 }
fbd86d4c 381@@ -600,7 +661,7 @@ glob2(Char *pathbuf, Char *pathend, Char
b5d655f7 382 static int
fbd86d4c
A
383 glob3(Char *pathbuf, Char *pathend, Char *pathend_last,
384 Char *pattern, Char *restpattern,
385- glob_t *pglob, size_t *limit)
386+ glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
387 {
388 struct dirent *dp;
389 DIR *dirp;
fbd86d4c 390@@ -620,15 +681,22 @@ glob3(Char *pathbuf, Char *pathend, Char
3d9156a7
A
391 *pathend = EOS;
392 errno = 0;
393
394- if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
395+ if ((dirp = g_opendir(pathbuf, pglob, loc)) == NULL) {
396 /* TODO: don't call for ENOENT or ENOTDIR? */
397 if (pglob->gl_errfunc) {
398- if (g_Ctoc(pathbuf, buf, sizeof(buf)))
399+ if (g_Ctoc(pathbuf, buf, sizeof(buf), loc))
400 return (GLOB_ABORTED);
224c7076
A
401- if (pglob->gl_errfunc(buf, errno) ||
402- pglob->gl_flags & GLOB_ERR)
34e8f829
A
403+#ifdef __BLOCKS__
404+ if (pglob->gl_flags & _GLOB_ERR_BLOCK) {
405+ if (pglob->gl_errblk(buf, errno))
406+ return (GLOB_ABORTED);
407+ } else
408+#endif /* __BLOCKS__ */
224c7076
A
409+ if (pglob->gl_errfunc(buf, errno))
410 return (GLOB_ABORTED);
411 }
412+ if (pglob->gl_flags & GLOB_ERR)
413+ return (GLOB_ABORTED);
414 return(0);
415 }
416
fbd86d4c
A
417@@ -646,6 +714,14 @@ glob3(Char *pathbuf, Char *pathend, Char
418 size_t clen;
419 mbstate_t mbs;
420
421+ if ((pglob->gl_flags & GLOB_LIMIT) &&
422+ limit->l_readdir++ >= GLOB_LIMIT_READDIR) {
423+ errno = 0;
424+ *pathend++ = SEP;
425+ *pathend = EOS;
426+ return GLOB_NOSPACE;
427+ }
428+
429 /* Initial DOT must be matched literally. */
430 if (dp->d_name[0] == DOT && *pattern != DOT)
431 continue;
432@@ -653,7 +729,7 @@ glob3(Char *pathbuf, Char *pathend, Char
3d9156a7 433 dc = pathend;
fbd86d4c 434 sc = dp->d_name;
3d9156a7
A
435 while (dc < pathend_last) {
436- clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
fbd86d4c 437+ clen = mbrtowc_l(&wc, sc, MB_LEN_MAX, &mbs, loc);
3d9156a7
A
438 if (clen == (size_t)-1 || clen == (size_t)-2) {
439 wc = *sc;
440 clen = 1;
fbd86d4c 441@@ -663,12 +739,12 @@ glob3(Char *pathbuf, Char *pathend, Char
3d9156a7
A
442 break;
443 sc += clen;
444 }
445- if (!match(pathend, pattern, restpattern)) {
446+ if (!match(pathend, pattern, restpattern, loc)) {
447 *pathend = EOS;
448 continue;
449 }
450 err = glob2(pathbuf, --dc, pathend_last, restpattern,
451- pglob, limit);
452+ pglob, limit, loc);
453 if (err)
454 break;
455 }
fbd86d4c 456@@ -681,6 +757,7 @@ glob3(Char *pathbuf, Char *pathend, Char
b5d655f7
A
457 }
458
459
460+#ifndef BUILDING_VARIANT
461 /*
462 * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
463 * add the new item, and update gl_pathc.
fbd86d4c 464@@ -695,20 +772,18 @@ glob3(Char *pathbuf, Char *pathend, Char
224c7076 465 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
3d9156a7
A
466 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
467 */
224c7076 468-static int
fbd86d4c 469-globextend(const Char *path, glob_t *pglob, size_t *limit)
224c7076 470+__private_extern__ int
fbd86d4c 471+globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, locale_t loc)
3d9156a7
A
472 {
473 char **pathv;
fbd86d4c
A
474 size_t i, newsize, len;
475 char *copy;
476 const Char *p;
477
478- if (*limit && pglob->gl_pathc > *limit) {
479- errno = 0;
480- return (GLOB_NOSPACE);
481- }
482-
483 newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
484+ if ((pglob->gl_flags & GLOB_LIMIT) &&
485+ newsize > GLOB_LIMIT_PATH * sizeof(*pathv))
486+ goto nospace;
487 pathv = pglob->gl_pathv ?
488 realloc((char *)pglob->gl_pathv, newsize) :
489 malloc(newsize);
490@@ -730,24 +805,33 @@ globextend(const Char *path, glob_t *pgl
3d9156a7
A
491
492 for (p = path; *p++;)
493 continue;
494- len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */
495+ len = MB_CUR_MAX_L(loc) * (size_t)(p - path); /* XXX overallocation */
fbd86d4c 496+ limit->l_string += len;
3d9156a7
A
497 if ((copy = malloc(len)) != NULL) {
498- if (g_Ctoc(path, copy, len)) {
499+ if (g_Ctoc(path, copy, len, loc)) {
500 free(copy);
501 return (GLOB_NOSPACE);
502 }
fbd86d4c
A
503 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
504 }
505 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
506+
507+ if ((pglob->gl_flags & GLOB_LIMIT) &&
508+ (newsize + limit->l_string) >= GLOB_LIMIT_STRING)
509+ goto nospace;
510+
511 return(copy == NULL ? GLOB_NOSPACE : 0);
512+nospace:
513+ errno = 0;
514+ return GLOB_NOSPACE;
515 }
516
517 /*
b5d655f7 518 * pattern matching function for filenames. Each occurrence of the *
3d9156a7
A
519 * pattern causes a recursion level.
520 */
b5d655f7 521-static int
fbd86d4c 522-match(Char *name, Char *pat, Char *patend)
b5d655f7 523+__private_extern__ int
fbd86d4c 524+match(Char *name, Char *pat, Char *patend, locale_t loc)
3d9156a7
A
525 {
526 int ok, negate_range;
527 Char c, k;
fbd86d4c 528@@ -759,7 +843,7 @@ match(Char *name, Char *pat, Char *paten
3d9156a7
A
529 if (pat == patend)
530 return(1);
531 do
532- if (match(name, pat, patend))
533+ if (match(name, pat, patend, loc))
534 return(1);
535 while (*name++ != EOS);
536 return(0);
fbd86d4c 537@@ -775,10 +859,10 @@ match(Char *name, Char *pat, Char *paten
3d9156a7
A
538 ++pat;
539 while (((c = *pat++) & M_MASK) != M_END)
540 if ((*pat & M_MASK) == M_RNG) {
541- if (__collate_load_error ?
542+ if (loc->__collate_load_error ?
543 CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) :
544- __collate_range_cmp(CHAR(c), CHAR(k)) <= 0
545- && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0
546+ __collate_range_cmp(CHAR(c), CHAR(k), loc) <= 0
547+ && __collate_range_cmp(CHAR(k), CHAR(pat[1]), loc) <= 0
548 )
549 ok = 1;
550 pat += 2;
fbd86d4c 551@@ -812,16 +896,17 @@ globfree(glob_t *pglob)
b5d655f7
A
552 pglob->gl_pathv = NULL;
553 }
3d9156a7 554 }
b5d655f7 555+#endif /* !BUILDING_VARIANT */
3d9156a7
A
556
557 static DIR *
fbd86d4c
A
558-g_opendir(Char *str, glob_t *pglob)
559+g_opendir(Char *str, glob_t *pglob, locale_t loc)
3d9156a7
A
560 {
561 char buf[MAXPATHLEN];
562
563 if (!*str)
564 strcpy(buf, ".");
565 else {
566- if (g_Ctoc(str, buf, sizeof(buf)))
567+ if (g_Ctoc(str, buf, sizeof(buf), loc))
568 return (NULL);
569 }
570
fbd86d4c 571@@ -832,11 +917,11 @@ g_opendir(Char *str, glob_t *pglob)
3d9156a7
A
572 }
573
574 static int
fbd86d4c
A
575-g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
576+g_lstat(Char *fn, struct stat *sb, glob_t *pglob, locale_t loc)
3d9156a7
A
577 {
578 char buf[MAXPATHLEN];
579
580- if (g_Ctoc(fn, buf, sizeof(buf))) {
581+ if (g_Ctoc(fn, buf, sizeof(buf), loc)) {
582 errno = ENAMETOOLONG;
583 return (-1);
584 }
fbd86d4c 585@@ -846,11 +931,11 @@ g_lstat(Char *fn, struct stat *sb, glob_
3d9156a7
A
586 }
587
588 static int
fbd86d4c
A
589-g_stat(Char *fn, struct stat *sb, glob_t *pglob)
590+g_stat(Char *fn, struct stat *sb, glob_t *pglob, locale_t loc)
3d9156a7
A
591 {
592 char buf[MAXPATHLEN];
593
594- if (g_Ctoc(fn, buf, sizeof(buf))) {
595+ if (g_Ctoc(fn, buf, sizeof(buf), loc)) {
596 errno = ENAMETOOLONG;
597 return (-1);
598 }
fbd86d4c 599@@ -859,7 +944,8 @@ g_stat(Char *fn, struct stat *sb, glob_t
224c7076 600 return(stat(buf, sb));
3d9156a7
A
601 }
602
fbd86d4c 603-static const Char *
224c7076 604+#ifndef BUILDING_VARIANT
fbd86d4c
A
605+__private_extern__ const Char *
606 g_strchr(const Char *str, wchar_t ch)
607 {
608
609@@ -870,15 +956,16 @@ g_strchr(const Char *str, wchar_t ch)
224c7076
A
610 return (NULL);
611 }
612
613-static int
fbd86d4c 614-g_Ctoc(const Char *str, char *buf, size_t len)
224c7076 615+__private_extern__ int
fbd86d4c 616+g_Ctoc(const Char *str, char *buf, size_t len, locale_t loc)
3d9156a7
A
617 {
618 mbstate_t mbs;
619 size_t clen;
620+ int mb_cur_max = MB_CUR_MAX_L(loc);
621
622 memset(&mbs, 0, sizeof(mbs));
623- while (len >= MB_CUR_MAX) {
624- clen = wcrtomb(buf, *str, &mbs);
625+ while (len >= mb_cur_max) {
626+ clen = wcrtomb_l(buf, *str, &mbs, loc);
627 if (clen == (size_t)-1)
628 return (1);
629 if (*str == L'\0')
fbd86d4c 630@@ -908,3 +995,4 @@ qprintf(const char *str, Char *s)
224c7076
A
631 (void)printf("\n");
632 }
633 #endif
634+#endif /* !BUILDING_VARIANT */