]>
Commit | Line | Data |
---|---|---|
3d9156a7 A |
1 | --- glob.c.orig 2004-11-25 11:38:01.000000000 -0800 |
2 | +++ glob.c 2005-02-24 16:02:34.000000000 -0800 | |
3 | @@ -40,6 +40,8 @@ | |
4 | #include <sys/cdefs.h> | |
5 | __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.22 2004/07/29 03:48:52 tjr Exp $"); | |
6 | ||
7 | +#include "xlocale_private.h" | |
8 | + | |
9 | /* | |
10 | * glob(3) -- a superset of the one defined in POSIX 1003.2. | |
11 | * | |
12 | @@ -144,24 +146,24 @@ | |
13 | ||
14 | ||
15 | static int compare(const void *, const void *); | |
16 | -static int g_Ctoc(const Char *, char *, u_int); | |
17 | -static int g_lstat(Char *, struct stat *, glob_t *); | |
18 | -static DIR *g_opendir(Char *, glob_t *); | |
19 | +static int g_Ctoc(const Char *, char *, u_int, locale_t); | |
20 | +static int g_lstat(Char *, struct stat *, glob_t *, locale_t); | |
21 | +static DIR *g_opendir(Char *, glob_t *, locale_t); | |
22 | static Char *g_strchr(Char *, wchar_t); | |
23 | #ifdef notdef | |
24 | static Char *g_strcat(Char *, const Char *); | |
25 | #endif | |
26 | -static int g_stat(Char *, struct stat *, glob_t *); | |
27 | -static int glob0(const Char *, glob_t *, int *); | |
28 | -static int glob1(Char *, glob_t *, int *); | |
29 | -static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *); | |
30 | -static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *); | |
31 | -static int globextend(const Char *, glob_t *, int *); | |
32 | +static int g_stat(Char *, struct stat *, glob_t *, locale_t); | |
33 | +static int glob0(const Char *, glob_t *, int *, locale_t); | |
34 | +static int glob1(Char *, glob_t *, int *, locale_t); | |
35 | +static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); | |
36 | +static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *, locale_t); | |
37 | +static int globextend(const Char *, glob_t *, int *, locale_t); | |
38 | static const Char * | |
39 | globtilde(const Char *, Char *, size_t, glob_t *); | |
40 | -static int globexp1(const Char *, glob_t *, int *); | |
41 | -static int globexp2(const Char *, const Char *, glob_t *, int *, int *); | |
42 | -static int match(Char *, Char *, Char *); | |
43 | +static int globexp1(const Char *, glob_t *, int *, locale_t); | |
44 | +static int globexp2(const Char *, const Char *, glob_t *, int *, int *, locale_t); | |
45 | +static int match(Char *, Char *, Char *, locale_t); | |
46 | #ifdef DEBUG | |
47 | static void qprintf(const char *, Char *); | |
48 | #endif | |
49 | @@ -178,6 +180,8 @@ | |
50 | mbstate_t mbs; | |
51 | wchar_t wc; | |
52 | size_t clen; | |
53 | + locale_t loc = __current_locale(); | |
54 | + int mb_cur_max = MB_CUR_MAX_L(loc); | |
55 | ||
56 | patnext = (u_char *) pattern; | |
57 | if (!(flags & GLOB_APPEND)) { | |
58 | @@ -200,8 +204,8 @@ | |
59 | bufend = bufnext + MAXPATHLEN - 1; | |
60 | if (flags & GLOB_NOESCAPE) { | |
61 | memset(&mbs, 0, sizeof(mbs)); | |
62 | - while (bufend - bufnext >= MB_CUR_MAX) { | |
63 | - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); | |
64 | + while (bufend - bufnext >= mb_cur_max) { | |
65 | + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc); | |
66 | if (clen == (size_t)-1 || clen == (size_t)-2) | |
67 | return (GLOB_NOMATCH); | |
68 | else if (clen == 0) | |
69 | @@ -212,7 +216,7 @@ | |
70 | } else { | |
71 | /* Protect the quoted characters. */ | |
72 | memset(&mbs, 0, sizeof(mbs)); | |
73 | - while (bufend - bufnext >= MB_CUR_MAX) { | |
74 | + while (bufend - bufnext >= mb_cur_max) { | |
75 | if (*patnext == QUOTE) { | |
76 | if (*++patnext == EOS) { | |
77 | *bufnext++ = QUOTE | M_PROTECT; | |
78 | @@ -221,7 +225,7 @@ | |
79 | prot = M_PROTECT; | |
80 | } else | |
81 | prot = 0; | |
82 | - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); | |
83 | + clen = mbrtowc_l(&wc, (const char *)patnext, MB_LEN_MAX, &mbs, loc); | |
84 | if (clen == (size_t)-1 || clen == (size_t)-2) | |
85 | return (GLOB_NOMATCH); | |
86 | else if (clen == 0) | |
87 | @@ -233,9 +237,9 @@ | |
88 | *bufnext = EOS; | |
89 | ||
90 | if (flags & GLOB_BRACE) | |
91 | - return globexp1(patbuf, pglob, &limit); | |
92 | + return globexp1(patbuf, pglob, &limit, loc); | |
93 | else | |
94 | - return glob0(patbuf, pglob, &limit); | |
95 | + return glob0(patbuf, pglob, &limit, loc); | |
96 | } | |
97 | ||
98 | /* | |
99 | @@ -244,23 +248,24 @@ | |
100 | * characters | |
101 | */ | |
102 | static int | |
103 | -globexp1(pattern, pglob, limit) | |
104 | +globexp1(pattern, pglob, limit, loc) | |
105 | const Char *pattern; | |
106 | glob_t *pglob; | |
107 | int *limit; | |
108 | + locale_t loc; | |
109 | { | |
110 | const Char* ptr = pattern; | |
111 | int rv; | |
112 | ||
113 | /* Protect a single {}, for find(1), like csh */ | |
114 | if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) | |
115 | - return glob0(pattern, pglob, limit); | |
116 | + return glob0(pattern, pglob, limit, loc); | |
117 | ||
118 | while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) | |
119 | - if (!globexp2(ptr, pattern, pglob, &rv, limit)) | |
120 | + if (!globexp2(ptr, pattern, pglob, &rv, limit, loc)) | |
121 | return rv; | |
122 | ||
123 | - return glob0(pattern, pglob, limit); | |
124 | + return glob0(pattern, pglob, limit, loc); | |
125 | } | |
126 | ||
127 | ||
128 | @@ -270,10 +275,11 @@ | |
129 | * If it fails then it tries to glob the rest of the pattern and returns. | |
130 | */ | |
131 | static int | |
132 | -globexp2(ptr, pattern, pglob, rv, limit) | |
133 | +globexp2(ptr, pattern, pglob, rv, limit, loc) | |
134 | const Char *ptr, *pattern; | |
135 | glob_t *pglob; | |
136 | int *rv, *limit; | |
137 | + locale_t loc; | |
138 | { | |
139 | int i; | |
140 | Char *lm, *ls; | |
141 | @@ -310,7 +316,7 @@ | |
142 | ||
143 | /* Non matching braces; just glob the pattern */ | |
144 | if (i != 0 || *pe == EOS) { | |
145 | - *rv = glob0(patbuf, pglob, limit); | |
146 | + *rv = glob0(patbuf, pglob, limit, loc); | |
147 | return 0; | |
148 | } | |
149 | ||
150 | @@ -357,7 +363,7 @@ | |
151 | #ifdef DEBUG | |
152 | qprintf("globexp2:", patbuf); | |
153 | #endif | |
154 | - *rv = globexp1(patbuf, pglob, limit); | |
155 | + *rv = globexp1(patbuf, pglob, limit, loc); | |
156 | ||
157 | /* move after the comma, to the next string */ | |
158 | pl = pm + 1; | |
159 | @@ -447,10 +453,11 @@ | |
160 | * if things went well, nonzero if errors occurred. | |
161 | */ | |
162 | static int | |
163 | -glob0(pattern, pglob, limit) | |
164 | +glob0(pattern, pglob, limit, loc) | |
165 | const Char *pattern; | |
166 | glob_t *pglob; | |
167 | int *limit; | |
168 | + locale_t loc; | |
169 | { | |
170 | const Char *qpatnext; | |
171 | int c, err, oldpathc; | |
172 | @@ -512,7 +519,7 @@ | |
173 | qprintf("glob0:", patbuf); | |
174 | #endif | |
175 | ||
176 | - if ((err = glob1(patbuf, pglob, limit)) != 0) | |
177 | + if ((err = glob1(patbuf, pglob, limit, loc)) != 0) | |
178 | return(err); | |
179 | ||
180 | /* | |
181 | @@ -525,7 +532,7 @@ | |
182 | if (((pglob->gl_flags & GLOB_NOCHECK) || | |
183 | ((pglob->gl_flags & GLOB_NOMAGIC) && | |
184 | !(pglob->gl_flags & GLOB_MAGCHAR)))) | |
185 | - return(globextend(pattern, pglob, limit)); | |
186 | + return(globextend(pattern, pglob, limit, loc)); | |
187 | else | |
188 | return(GLOB_NOMATCH); | |
189 | } | |
190 | @@ -543,10 +550,11 @@ | |
191 | } | |
192 | ||
193 | static int | |
194 | -glob1(pattern, pglob, limit) | |
195 | +glob1(pattern, pglob, limit, loc) | |
196 | Char *pattern; | |
197 | glob_t *pglob; | |
198 | int *limit; | |
199 | + locale_t loc; | |
200 | { | |
201 | Char pathbuf[MAXPATHLEN]; | |
202 | ||
203 | @@ -554,7 +562,7 @@ | |
204 | if (*pattern == EOS) | |
205 | return(0); | |
206 | return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, | |
207 | - pattern, pglob, limit)); | |
208 | + pattern, pglob, limit, loc)); | |
209 | } | |
210 | ||
211 | /* | |
212 | @@ -563,10 +571,11 @@ | |
213 | * meta characters. | |
214 | */ | |
215 | static int | |
216 | -glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit) | |
217 | +glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit, loc) | |
218 | Char *pathbuf, *pathend, *pathend_last, *pattern; | |
219 | glob_t *pglob; | |
220 | int *limit; | |
221 | + locale_t loc; | |
222 | { | |
223 | struct stat sb; | |
224 | Char *p, *q; | |
225 | @@ -579,13 +588,13 @@ | |
226 | for (anymeta = 0;;) { | |
227 | if (*pattern == EOS) { /* End of pattern? */ | |
228 | *pathend = EOS; | |
229 | - if (g_lstat(pathbuf, &sb, pglob)) | |
230 | + if (g_lstat(pathbuf, &sb, pglob, loc)) | |
231 | return(0); | |
232 | ||
233 | if (((pglob->gl_flags & GLOB_MARK) && | |
234 | pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) | |
235 | || (S_ISLNK(sb.st_mode) && | |
236 | - (g_stat(pathbuf, &sb, pglob) == 0) && | |
237 | + (g_stat(pathbuf, &sb, pglob, loc) == 0) && | |
238 | S_ISDIR(sb.st_mode)))) { | |
239 | if (pathend + 1 > pathend_last) | |
240 | return (GLOB_ABORTED); | |
241 | @@ -593,7 +602,7 @@ | |
242 | *pathend = EOS; | |
243 | } | |
244 | ++pglob->gl_matchc; | |
245 | - return(globextend(pathbuf, pglob, limit)); | |
246 | + return(globextend(pathbuf, pglob, limit, loc)); | |
247 | } | |
248 | ||
249 | /* Find end of next segment, copy tentatively to pathend. */ | |
250 | @@ -617,16 +626,17 @@ | |
251 | } | |
252 | } else /* Need expansion, recurse. */ | |
253 | return(glob3(pathbuf, pathend, pathend_last, pattern, p, | |
254 | - pglob, limit)); | |
255 | + pglob, limit, loc)); | |
256 | } | |
257 | /* NOTREACHED */ | |
258 | } | |
259 | ||
260 | static int | |
261 | -glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit) | |
262 | +glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit, loc) | |
263 | Char *pathbuf, *pathend, *pathend_last, *pattern, *restpattern; | |
264 | glob_t *pglob; | |
265 | int *limit; | |
266 | + locale_t loc; | |
267 | { | |
268 | struct dirent *dp; | |
269 | DIR *dirp; | |
270 | @@ -646,10 +656,10 @@ | |
271 | *pathend = EOS; | |
272 | errno = 0; | |
273 | ||
274 | - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { | |
275 | + if ((dirp = g_opendir(pathbuf, pglob, loc)) == NULL) { | |
276 | /* TODO: don't call for ENOENT or ENOTDIR? */ | |
277 | if (pglob->gl_errfunc) { | |
278 | - if (g_Ctoc(pathbuf, buf, sizeof(buf))) | |
279 | + if (g_Ctoc(pathbuf, buf, sizeof(buf), loc)) | |
280 | return (GLOB_ABORTED); | |
281 | if (pglob->gl_errfunc(buf, errno) || | |
282 | pglob->gl_flags & GLOB_ERR) | |
283 | @@ -679,7 +689,7 @@ | |
284 | dc = pathend; | |
285 | sc = (u_char *) dp->d_name; | |
286 | while (dc < pathend_last) { | |
287 | - clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); | |
288 | + clen = mbrtowc_l(&wc, (const char *)sc, MB_LEN_MAX, &mbs, loc); | |
289 | if (clen == (size_t)-1 || clen == (size_t)-2) { | |
290 | wc = *sc; | |
291 | clen = 1; | |
292 | @@ -689,12 +699,12 @@ | |
293 | break; | |
294 | sc += clen; | |
295 | } | |
296 | - if (!match(pathend, pattern, restpattern)) { | |
297 | + if (!match(pathend, pattern, restpattern, loc)) { | |
298 | *pathend = EOS; | |
299 | continue; | |
300 | } | |
301 | err = glob2(pathbuf, --dc, pathend_last, restpattern, | |
302 | - pglob, limit); | |
303 | + pglob, limit, loc); | |
304 | if (err) | |
305 | break; | |
306 | } | |
307 | @@ -722,10 +732,11 @@ | |
308 | * gl_pathv points to (gl_offs + gl_pathc + 1) items. | |
309 | */ | |
310 | static int | |
311 | -globextend(path, pglob, limit) | |
312 | +globextend(path, pglob, limit, loc) | |
313 | const Char *path; | |
314 | glob_t *pglob; | |
315 | int *limit; | |
316 | + locale_t loc; | |
317 | { | |
318 | char **pathv; | |
319 | int i; | |
320 | @@ -760,9 +771,9 @@ | |
321 | ||
322 | for (p = path; *p++;) | |
323 | continue; | |
324 | - len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ | |
325 | + len = MB_CUR_MAX_L(loc) * (size_t)(p - path); /* XXX overallocation */ | |
326 | if ((copy = malloc(len)) != NULL) { | |
327 | - if (g_Ctoc(path, copy, len)) { | |
328 | + if (g_Ctoc(path, copy, len, loc)) { | |
329 | free(copy); | |
330 | return (GLOB_NOSPACE); | |
331 | } | |
332 | @@ -777,8 +788,9 @@ | |
333 | * pattern causes a recursion level. | |
334 | */ | |
335 | static int | |
336 | -match(name, pat, patend) | |
337 | +match(name, pat, patend, loc) | |
338 | Char *name, *pat, *patend; | |
339 | + locale_t loc; | |
340 | { | |
341 | int ok, negate_range; | |
342 | Char c, k; | |
343 | @@ -790,7 +802,7 @@ | |
344 | if (pat == patend) | |
345 | return(1); | |
346 | do | |
347 | - if (match(name, pat, patend)) | |
348 | + if (match(name, pat, patend, loc)) | |
349 | return(1); | |
350 | while (*name++ != EOS); | |
351 | return(0); | |
352 | @@ -806,10 +818,10 @@ | |
353 | ++pat; | |
354 | while (((c = *pat++) & M_MASK) != M_END) | |
355 | if ((*pat & M_MASK) == M_RNG) { | |
356 | - if (__collate_load_error ? | |
357 | + if (loc->__collate_load_error ? | |
358 | CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : | |
359 | - __collate_range_cmp(CHAR(c), CHAR(k)) <= 0 | |
360 | - && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0 | |
361 | + __collate_range_cmp(CHAR(c), CHAR(k), loc) <= 0 | |
362 | + && __collate_range_cmp(CHAR(k), CHAR(pat[1]), loc) <= 0 | |
363 | ) | |
364 | ok = 1; | |
365 | pat += 2; | |
366 | @@ -846,16 +858,17 @@ | |
367 | } | |
368 | ||
369 | static DIR * | |
370 | -g_opendir(str, pglob) | |
371 | +g_opendir(str, pglob, loc) | |
372 | Char *str; | |
373 | glob_t *pglob; | |
374 | + locale_t loc; | |
375 | { | |
376 | char buf[MAXPATHLEN]; | |
377 | ||
378 | if (!*str) | |
379 | strcpy(buf, "."); | |
380 | else { | |
381 | - if (g_Ctoc(str, buf, sizeof(buf))) | |
382 | + if (g_Ctoc(str, buf, sizeof(buf), loc)) | |
383 | return (NULL); | |
384 | } | |
385 | ||
386 | @@ -866,14 +879,15 @@ | |
387 | } | |
388 | ||
389 | static int | |
390 | -g_lstat(fn, sb, pglob) | |
391 | +g_lstat(fn, sb, pglob, loc) | |
392 | Char *fn; | |
393 | struct stat *sb; | |
394 | glob_t *pglob; | |
395 | + locale_t loc; | |
396 | { | |
397 | char buf[MAXPATHLEN]; | |
398 | ||
399 | - if (g_Ctoc(fn, buf, sizeof(buf))) { | |
400 | + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { | |
401 | errno = ENAMETOOLONG; | |
402 | return (-1); | |
403 | } | |
404 | @@ -883,14 +897,15 @@ | |
405 | } | |
406 | ||
407 | static int | |
408 | -g_stat(fn, sb, pglob) | |
409 | +g_stat(fn, sb, pglob, loc) | |
410 | Char *fn; | |
411 | struct stat *sb; | |
412 | glob_t *pglob; | |
413 | + locale_t loc; | |
414 | { | |
415 | char buf[MAXPATHLEN]; | |
416 | ||
417 | - if (g_Ctoc(fn, buf, sizeof(buf))) { | |
418 | + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { | |
419 | errno = ENAMETOOLONG; | |
420 | return (-1); | |
421 | } | |
422 | @@ -912,17 +927,19 @@ | |
423 | } | |
424 | ||
425 | static int | |
426 | -g_Ctoc(str, buf, len) | |
427 | +g_Ctoc(str, buf, len, loc) | |
428 | const Char *str; | |
429 | char *buf; | |
430 | u_int len; | |
431 | + locale_t loc; | |
432 | { | |
433 | mbstate_t mbs; | |
434 | size_t clen; | |
435 | + int mb_cur_max = MB_CUR_MAX_L(loc); | |
436 | ||
437 | memset(&mbs, 0, sizeof(mbs)); | |
438 | - while (len >= MB_CUR_MAX) { | |
439 | - clen = wcrtomb(buf, *str, &mbs); | |
440 | + while (len >= mb_cur_max) { | |
441 | + clen = wcrtomb_l(buf, *str, &mbs, loc); | |
442 | if (clen == (size_t)-1) | |
443 | return (1); | |
444 | if (*str == L'\0') |