]> git.saurik.com Git - apple/libc.git/blob - gen/FreeBSD/glob.c.patch
Libc-763.11.tar.gz
[apple/libc.git] / gen / FreeBSD / glob.c.patch
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 (
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.28 2010/05/12 17:44:00 gordon Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 /*
10 * glob(3) -- a superset of the one defined in POSIX 1003.2.
11 *
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;
33 #define ismeta(c) (((c)&M_QUOTE) != 0)
34
35
36 -static int compare(const void *, const void *);
37 -static int g_Ctoc(const Char *, char *, size_t);
38 -static int g_lstat(Char *, struct stat *, glob_t *);
39 -static DIR *g_opendir(Char *, glob_t *);
40 -static const Char *g_strchr(const Char *, wchar_t);
41 +#define compare __gl_compare
42 +#define g_Ctoc __gl_g_Ctoc
43 +#define g_strchr __gl_g_strchr
44 +#define globextend __gl_globextend
45 +#define globtilde __gl_globtilde
46 +#define match __gl_match
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);
51 +__private_extern__ const Char *
52 + globtilde(const Char *, Char *, size_t, glob_t *);
53 +__private_extern__ int match(Char *, Char *, Char *, locale_t);
54 +
55 +
56 +static int g_lstat(Char *, struct stat *, glob_t *, locale_t);
57 +static DIR *g_opendir(Char *, glob_t *, locale_t);
58 #ifdef notdef
59 static Char *g_strcat(Char *, const Char *);
60 #endif
61 -static int g_stat(Char *, struct stat *, glob_t *);
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 *);
67 -static const Char *
68 - globtilde(const Char *, Char *, size_t, glob_t *);
69 -static int globexp1(const Char *, glob_t *, size_t *);
70 -static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *);
71 -static int match(Char *, Char *, Char *);
72 +static int g_stat(Char *, struct stat *, glob_t *, locale_t);
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);
79 #ifdef DEBUG
80 static void qprintf(const char *, Char *);
81 #endif
82
83 -int
84 -glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob)
85 +static int
86 +__glob(const char *pattern, glob_t *pglob)
87 {
88 const char *patnext;
89 - size_t limit;
90 + struct glob_limit limit = { 0, 0, 0, 0 };
91 Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot;
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
98 patnext = pattern;
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) {
108 - limit = pglob->gl_matchc;
109 - if (limit == 0)
110 - limit = ARG_MAX;
111 - } else
112 - limit = 0;
113 - pglob->gl_flags = flags & ~GLOB_MAGCHAR;
114 - pglob->gl_errfunc = errfunc;
115 pglob->gl_matchc = 0;
116
117 bufnext = patbuf;
118 bufend = bufnext + MAXPATHLEN - 1;
119 - if (flags & GLOB_NOESCAPE) {
120 + if (pglob->gl_flags & GLOB_NOESCAPE) {
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) {
125 + clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc);
126 if (clen == (size_t)-1 || clen == (size_t)-2)
127 return (GLOB_NOMATCH);
128 else if (clen == 0)
129 @@ -205,7 +222,7 @@ glob(const char *pattern, int flags, int
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;
138 @@ -214,7 +231,7 @@ glob(const char *pattern, int flags, int
139 prot = M_PROTECT;
140 } else
141 prot = 0;
142 - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
143 + clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc);
144 if (clen == (size_t)-1 || clen == (size_t)-2)
145 return (GLOB_NOMATCH);
146 else if (clen == 0)
147 @@ -225,11 +242,34 @@ glob(const char *pattern, int flags, int
148 }
149 *bufnext = EOS;
150
151 - if (flags & GLOB_BRACE)
152 - return globexp1(patbuf, pglob, &limit);
153 + if (pglob->gl_flags & GLOB_BRACE)
154 + return globexp1(patbuf, pglob, &limit, loc);
155 else
156 - return glob0(patbuf, pglob, &limit);
157 + return glob0(patbuf, pglob, &limit, loc);
158 +}
159 +
160 +int
161 +glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob)
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
174 +glob_b(const char *pattern, int flags, int (^errblk)(const char *, int), glob_t *pglob)
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);
180 }
181 +#endif /* __BLOCKS__ */
182
183 /*
184 * Expand recursively a glob {} pattern. When there is no more expansion
185 @@ -237,20 +277,26 @@ glob(const char *pattern, int flags, int
186 * characters
187 */
188 static int
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)
191 {
192 const Char* ptr = pattern;
193 int rv;
194
195 + if ((pglob->gl_flags & GLOB_LIMIT) &&
196 + limit->l_brace++ >= GLOB_LIMIT_BRACE) {
197 + errno = 0;
198 + return GLOB_NOSPACE;
199 + }
200 +
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
206 while ((ptr = g_strchr(ptr, LBRACE)) != NULL)
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
216 @@ -260,7 +306,7 @@ globexp1(const Char *pattern, glob_t *pg
217 * If it fails then it tries to glob the rest of the pattern and returns.
218 */
219 static int
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)
222 {
223 int i;
224 Char *lm, *ls;
225 @@ -297,7 +343,7 @@ globexp2(const Char *ptr, const Char *pa
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
234 @@ -344,7 +390,7 @@ globexp2(const Char *ptr, const Char *pa
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;
243 @@ -360,10 +406,11 @@ globexp2(const Char *ptr, const Char *pa
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 *
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
257
258 return patbuf;
259 }
260 +#endif /* BUILDING_VARIANT */
261
262
263 /*
264 @@ -430,7 +478,7 @@ globtilde(const Char *pattern, Char *pat
265 * if things went well, nonzero if errors occurred.
266 */
267 static int
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)
270 {
271 const Char *qpatnext;
272 int err;
273 @@ -443,6 +491,10 @@ glob0(const Char *pattern, glob_t *pglob
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;
284 @@ -493,7 +545,7 @@ glob0(const Char *pattern, glob_t *pglob
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 /*
293 @@ -506,7 +558,7 @@ glob0(const Char *pattern, glob_t *pglob
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 }
302 @@ -516,14 +568,16 @@ glob0(const Char *pattern, glob_t *pglob
303 return(0);
304 }
305
306 -static int
307 +#ifndef BUILDING_VARIANT
308 +__private_extern__ int
309 compare(const void *p, const void *q)
310 {
311 - return(strcmp(*(char **)p, *(char **)q));
312 + return(strcoll(*(char **)p, *(char **)q));
313 }
314 +#endif /* BUILDING_VARIANT */
315
316 static int
317 -glob1(Char *pattern, glob_t *pglob, size_t *limit)
318 +glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc)
319 {
320 Char pathbuf[MAXPATHLEN];
321
322 @@ -531,7 +585,7 @@ glob1(Char *pattern, glob_t *pglob, size
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 /*
331 @@ -541,7 +595,7 @@ glob1(Char *pattern, glob_t *pglob, size
332 */
333 static int
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)
337 {
338 struct stat sb;
339 Char *p, *q;
340 @@ -554,13 +608,20 @@ glob2(Char *pathbuf, Char *pathend, Char
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
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 + }
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);
363 @@ -568,7 +629,7 @@ glob2(Char *pathbuf, Char *pathend, Char
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. */
372 @@ -592,7 +653,7 @@ glob2(Char *pathbuf, Char *pathend, Char
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 }
381 @@ -600,7 +661,7 @@ glob2(Char *pathbuf, Char *pathend, Char
382 static int
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)
387 {
388 struct dirent *dp;
389 DIR *dirp;
390 @@ -620,15 +681,22 @@ glob3(Char *pathbuf, Char *pathend, Char
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);
401 - if (pglob->gl_errfunc(buf, errno) ||
402 - pglob->gl_flags & GLOB_ERR)
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__ */
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
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
433 dc = pathend;
434 sc = dp->d_name;
435 while (dc < pathend_last) {
436 - clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs);
437 + clen = mbrtowc_l(&wc, sc, MB_LEN_MAX, &mbs, loc);
438 if (clen == (size_t)-1 || clen == (size_t)-2) {
439 wc = *sc;
440 clen = 1;
441 @@ -663,12 +739,12 @@ glob3(Char *pathbuf, Char *pathend, Char
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 }
456 @@ -681,6 +757,7 @@ glob3(Char *pathbuf, Char *pathend, Char
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.
464 @@ -695,20 +772,18 @@ glob3(Char *pathbuf, Char *pathend, Char
465 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
466 * gl_pathv points to (gl_offs + gl_pathc + 1) items.
467 */
468 -static int
469 -globextend(const Char *path, glob_t *pglob, size_t *limit)
470 +__private_extern__ int
471 +globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, locale_t loc)
472 {
473 char **pathv;
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
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 */
496 + limit->l_string += len;
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 }
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 /*
518 * pattern matching function for filenames. Each occurrence of the *
519 * pattern causes a recursion level.
520 */
521 -static int
522 -match(Char *name, Char *pat, Char *patend)
523 +__private_extern__ int
524 +match(Char *name, Char *pat, Char *patend, locale_t loc)
525 {
526 int ok, negate_range;
527 Char c, k;
528 @@ -759,7 +843,7 @@ match(Char *name, Char *pat, Char *paten
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);
537 @@ -775,10 +859,10 @@ match(Char *name, Char *pat, Char *paten
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;
551 @@ -812,16 +896,17 @@ globfree(glob_t *pglob)
552 pglob->gl_pathv = NULL;
553 }
554 }
555 +#endif /* !BUILDING_VARIANT */
556
557 static DIR *
558 -g_opendir(Char *str, glob_t *pglob)
559 +g_opendir(Char *str, glob_t *pglob, locale_t loc)
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
571 @@ -832,11 +917,11 @@ g_opendir(Char *str, glob_t *pglob)
572 }
573
574 static int
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)
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 }
585 @@ -846,11 +931,11 @@ g_lstat(Char *fn, struct stat *sb, glob_
586 }
587
588 static int
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)
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 }
599 @@ -859,7 +944,8 @@ g_stat(Char *fn, struct stat *sb, glob_t
600 return(stat(buf, sb));
601 }
602
603 -static const Char *
604 +#ifndef BUILDING_VARIANT
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)
610 return (NULL);
611 }
612
613 -static int
614 -g_Ctoc(const Char *str, char *buf, size_t len)
615 +__private_extern__ int
616 +g_Ctoc(const Char *str, char *buf, size_t len, locale_t loc)
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')
630 @@ -908,3 +995,4 @@ qprintf(const char *str, Char *s)
631 (void)printf("\n");
632 }
633 #endif
634 +#endif /* !BUILDING_VARIANT */