Project

General

Profile

Bug #1097 » glob.c-ill.diff

Gary Mills, 2012-11-01 02:58 PM

View differences:

glob.c-ill Wed Oct 31 09:06:10 2012
1
/*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License (the "License").
6
 * You may not use this file except in compliance with the License.
7
 *
8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9
 * or http://www.opensolaris.org/os/licensing.
10
 * See the License for the specific language governing permissions
11
 * and limitations under the License.
12
 *
13
 * When distributing Covered Code, include this CDDL HEADER in each
14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15
 * If applicable, add the following below this CDDL HEADER, with the
16
 * fields enclosed by brackets "[]" replaced with your own identifying
17
 * information: Portions Copyright [yyyy] [name of copyright owner]
18
 *
19
 * CDDL HEADER END
20
 */
21

  
22
/*
23
 * Copyright (c) 2012 Gary Mills
24
 */
25

  
1 26
/*	$OpenBSD: glob.c,v 1.39 2012/01/20 07:09:42 tedu Exp $ */
2 27
/*
3 28
 * Copyright (c) 1989, 1993
......
148 173
static Char	*g_strchr(const Char *, int);
149 174
static int	 g_strncmp(const Char *, const char *, size_t);
150 175
static int	 g_stat(Char *, struct stat *, glob_t *);
151
static int	 glob0(const Char *, glob_t *, struct glob_lim *);
152
static int	 glob1(Char *, Char *, glob_t *, struct glob_lim *);
176
static int	 glob0(const Char *, glob_t *, struct glob_lim *,
177
		       int (*)(const char *, int));
178
static int	 glob1(Char *, Char *, glob_t *, struct glob_lim *,
179
		       int (*)(const char *, int));
153 180
static int	 glob2(Char *, Char *, Char *, Char *, Char *, Char *,
154
		    glob_t *, struct glob_lim *);
181
		       glob_t *, struct glob_lim *,
182
		       int (*)(const char *, int));
155 183
static int	 glob3(Char *, Char *, Char *, Char *, Char *,
156
		    Char *, Char *, glob_t *, struct glob_lim *);
184
		       Char *, Char *, glob_t *, struct glob_lim *,
185
		       int (*)(const char *, int));
157 186
static int	 globextend(const Char *, glob_t *, struct glob_lim *,
158 187
		    struct stat *);
159 188
static const Char *
160 189
		 globtilde(const Char *, Char *, size_t, glob_t *);
161
static int	 globexp1(const Char *, glob_t *, struct glob_lim *);
190
static int	 globexp1(const Char *, glob_t *, struct glob_lim *,
191
			  int (*)(const char *, int));
162 192
static int	 globexp2(const Char *, const Char *, glob_t *,
163
		    struct glob_lim *);
193
			  struct glob_lim *, int (*)(const char *, int));
164 194
static int	 match(Char *, Char *, Char *, int);
165 195
#ifdef DEBUG
166 196
static void	 qprintf(const char *, Char *);
......
182 212
	if (!(flags & GLOB_APPEND)) {
183 213
		pglob->gl_pathc = 0;
184 214
		pglob->gl_pathv = NULL;
185
		pglob->gl_statv = NULL;
215
		if ((flags & GLOB_KEEPSTAT) != 0)
216
		  pglob->gl_statv = NULL;
186 217
		if (!(flags & GLOB_DOOFFS))
187 218
			pglob->gl_offs = 0;
188 219
	}
189 220
	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
190
	pglob->gl_errfunc = errfunc;
191 221
	pglob->gl_matchc = 0;
192 222

  
193 223
	if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 ||
......
215 245
	*bufnext = EOS;
216 246

  
217 247
	if (flags & GLOB_BRACE)
218
		return globexp1(patbuf, pglob, &limit);
248
	  return globexp1(patbuf, pglob, &limit, errfunc);
219 249
	else
220
		return glob0(patbuf, pglob, &limit);
250
	  return glob0(patbuf, pglob, &limit, errfunc);
221 251
}
222 252

  
223 253
/*
......
226 256
 * characters
227 257
 */
228 258
static int
229
globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
259
globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp,
260
	 int (*errfunc)(const char *, int))
230 261
{
231 262
	const Char* ptr = pattern;
232 263

  
233 264
	/* Protect a single {}, for find(1), like csh */
234 265
	if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
235
		return glob0(pattern, pglob, limitp);
266
	  return glob0(pattern, pglob, limitp, errfunc);
236 267

  
237 268
	if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL)
238
		return globexp2(ptr, pattern, pglob, limitp);
269
	  return globexp2(ptr, pattern, pglob, limitp, errfunc);
239 270

  
240
	return glob0(pattern, pglob, limitp);
271
	return glob0(pattern, pglob, limitp, errfunc);
241 272
}
242 273

  
243 274

  
......
248 279
 */
249 280
static int
250 281
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
251
    struct glob_lim *limitp)
282
	 struct glob_lim *limitp, int (*errfunc)(const char *, int))
252 283
{
253 284
	int     i, rv;
254 285
	Char   *lm, *ls;
......
284 315

  
285 316
	/* Non matching braces; just glob the pattern */
286 317
	if (i != 0 || *pe == EOS)
287
		return glob0(patbuf, pglob, limitp);
318
	  return glob0(patbuf, pglob, limitp, errfunc);
288 319

  
289 320
	for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
290 321
		switch (*pm) {
......
330 361
#ifdef DEBUG
331 362
				qprintf("globexp2:", patbuf);
332 363
#endif
333
				rv = globexp1(patbuf, pglob, limitp);
364
				rv = globexp1(patbuf, pglob, limitp, errfunc);
334 365
				if (rv && rv != GLOB_NOMATCH)
335 366
					return rv;
336 367

  
......
458 489
 * to find no matches.
459 490
 */
460 491
static int
461
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
492
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp,
493
      int (*errfunc)(const char *, int))
462 494
{
463 495
	const Char *qpatnext;
464 496
	int c, err, oldpathc;
......
534 566
	qprintf("glob0:", patbuf);
535 567
#endif
536 568

  
537
	if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0)
569
	if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp, errfunc))
570
	    != 0)
538 571
		return(err);
539 572

  
540 573
	/*
......
596 629
}
597 630

  
598 631
static int
599
glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
632
glob1(Char *pattern, Char *pattern_last, glob_t *pglob,
633
      struct glob_lim *limitp, int (*errfunc)(const char *, int))
600 634
{
601 635
	Char pathbuf[MAXPATHLEN];
602 636

  
......
605 639
		return(0);
606 640
	return(glob2(pathbuf, pathbuf+MAXPATHLEN-1,
607 641
	    pathbuf, pathbuf+MAXPATHLEN-1,
608
	    pattern, pattern_last, pglob, limitp));
642
		     pattern, pattern_last, pglob, limitp, errfunc));
609 643
}
610 644

  
611 645
/*
......
615 649
 */
616 650
static int
617 651
glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
618
    Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
652
    Char *pattern, Char *pattern_last, glob_t *pglob,
653
      struct glob_lim *limitp, int (*errfunc)(const char *, int))
619 654
{
620 655
	struct stat sb;
621 656
	Char *p, *q;
......
676 711
			/* Need expansion, recurse. */
677 712
			return(glob3(pathbuf, pathbuf_last, pathend,
678 713
			    pathend_last, pattern, p, pattern_last,
679
			    pglob, limitp));
714
				     pglob, limitp, errfunc));
680 715
	}
681 716
	/* NOTREACHED */
682 717
}
......
684 719
static int
685 720
glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
686 721
    Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob,
687
    struct glob_lim *limitp)
722
      struct glob_lim *limitp, int (*errfunc)(const char *, int))
688 723
{
689 724
	struct dirent *dp;
690 725
	DIR *dirp;
691 726
	int err;
692 727
	char buf[MAXPATHLEN];
728
	struct dirent *(*readdirfunc)(DIR *);
693 729

  
694
	/*
695
	 * The readdirfunc declaration can't be prototyped, because it is
696
	 * assigned, below, to two functions which are prototyped in glob.h
697
	 * and dirent.h as taking pointers to differently typed opaque
698
	 * structures.
699
	 */
700
	struct dirent *(*readdirfunc)(void *);
701

  
702 730
	if (pathend > pathend_last)
703 731
		return (1);
704 732
	*pathend = EOS;
......
706 734

  
707 735
	if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
708 736
		/* TODO: don't call for ENOENT or ENOTDIR? */
709
		if (pglob->gl_errfunc) {
737
		if (errfunc) {
710 738
			if (g_Ctoc(pathbuf, buf, sizeof(buf)))
711 739
				return(GLOB_ABORTED);
712
			if (pglob->gl_errfunc(buf, errno) ||
740
			if (errfunc(buf, errno) ||
713 741
			    pglob->gl_flags & GLOB_ERR)
714 742
				return(GLOB_ABORTED);
715 743
		}
......
722 750
	if (pglob->gl_flags & GLOB_ALTDIRFUNC)
723 751
		readdirfunc = pglob->gl_readdir;
724 752
	else
725
		readdirfunc = (struct dirent *(*)(void *))readdir;
753
		readdirfunc = readdir;
726 754
	while ((dp = (*readdirfunc)(dirp))) {
727 755
		u_char *sc;
728 756
		Char *dc;
......
754 782
			continue;
755 783
		}
756 784
		err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,
757
		    restpattern, restpattern_last, pglob, limitp);
785
			    restpattern, restpattern_last, pglob, limitp,
786
			    errfunc);
758 787
		if (err)
759 788
			break;
760 789
	}
......
810 839
			free(pglob->gl_pathv);
811 840
			pglob->gl_pathv = NULL;
812 841
		}
813
		if (pglob->gl_statv) {
842
		if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
843
		    pglob->gl_statv) {
814 844
			free(pglob->gl_statv);
815 845
			pglob->gl_statv = NULL;
816 846
		}
......
959 989
		free(pglob->gl_pathv);
960 990
		pglob->gl_pathv = NULL;
961 991
	}
962
	if (pglob->gl_statv != NULL) {
992
	if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 &&
993
	  pglob->gl_statv != NULL) {
963 994
		for (i = 0; i < pglob->gl_pathc; i++) {
964 995
			if (pglob->gl_statv[i] != NULL)
965 996
				free(pglob->gl_statv[i]);
(1-1/11)