source: vendor/bash/3.1/lib/glob/glob.c

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 21.3 KB
Line 
1/* glob.c -- file-name wildcard pattern matching for Bash.
2
3 Copyright (C) 1985-2005 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
18
19/* To whomever it may concern: I have never seen the code which most
20 Unix programs use to perform this function. I wrote this from scratch
21 based on specifications for the pattern matching. --RMS. */
22
23#include <config.h>
24
25#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
26 #pragma alloca
27#endif /* _AIX && RISC6000 && !__GNUC__ */
28
29#include "bashtypes.h"
30
31#if defined (HAVE_UNISTD_H)
32# include <unistd.h>
33#endif
34
35#include "bashansi.h"
36#include "posixdir.h"
37#include "posixstat.h"
38#include "shmbutil.h"
39#include "xmalloc.h"
40
41#include "filecntl.h"
42#if !defined (F_OK)
43# define F_OK 0
44#endif
45
46#include "stdc.h"
47#include "memalloc.h"
48#include "quit.h"
49
50#include "glob.h"
51#include "strmatch.h"
52
53#if !defined (HAVE_BCOPY) && !defined (bcopy)
54# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
55#endif /* !HAVE_BCOPY && !bcopy */
56
57#if !defined (NULL)
58# if defined (__STDC__)
59# define NULL ((void *) 0)
60# else
61# define NULL 0x0
62# endif /* __STDC__ */
63#endif /* !NULL */
64
65#if !defined (FREE)
66# define FREE(x) if (x) free (x)
67#endif
68
69/* Don't try to alloca() more than this much memory for `struct globval'
70 in glob_vector() */
71#ifndef ALLOCA_MAX
72# define ALLOCA_MAX 100000
73#endif
74
75extern void throw_to_top_level __P((void));
76extern int test_eaccess __P((char *, int));
77
78extern int extended_glob;
79
80/* Global variable which controls whether or not * matches .*.
81 Non-zero means don't match .*. */
82int noglob_dot_filenames = 1;
83
84/* Global variable which controls whether or not filename globbing
85 is done without regard to case. */
86int glob_ignore_case = 0;
87
88/* Global variable to return to signify an error in globbing. */
89char *glob_error_return;
90
91/* Some forward declarations. */
92static int skipname __P((char *, char *));
93#if HANDLE_MULTIBYTE
94static int mbskipname __P((char *, char *));
95#endif
96#if HANDLE_MULTIBYTE
97static void udequote_pathname __P((char *));
98static void wdequote_pathname __P((char *));
99#else
100# define dequote_pathname udequote_pathname
101#endif
102static void dequote_pathname __P((char *));
103static int glob_testdir __P((char *));
104static char **glob_dir_to_array __P((char *, char **, int));
105
106/* Compile `glob_loop.c' for single-byte characters. */
107#define CHAR unsigned char
108#define INT int
109#define L(CS) CS
110#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
111#include "glob_loop.c"
112
113/* Compile `glob_loop.c' again for multibyte characters. */
114#if HANDLE_MULTIBYTE
115
116#define CHAR wchar_t
117#define INT wint_t
118#define L(CS) L##CS
119#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
120#include "glob_loop.c"
121
122#endif /* HANDLE_MULTIBYTE */
123
124/* And now a function that calls either the single-byte or multibyte version
125 of internal_glob_pattern_p. */
126int
127glob_pattern_p (pattern)
128 const char *pattern;
129{
130#if HANDLE_MULTIBYTE
131 size_t n;
132 wchar_t *wpattern;
133 int r;
134
135 if (MB_CUR_MAX == 1)
136 return (internal_glob_pattern_p ((unsigned char *)pattern));
137
138 /* Convert strings to wide chars, and call the multibyte version. */
139 n = xdupmbstowcs (&wpattern, NULL, pattern);
140 if (n == (size_t)-1)
141 /* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
142 return (internal_glob_pattern_p ((unsigned char *)pattern));
143
144 r = internal_glob_wpattern_p (wpattern);
145 free (wpattern);
146
147 return r;
148#else
149 return (internal_glob_pattern_p (pattern));
150#endif
151}
152
153/* Return 1 if DNAME should be skipped according to PAT. Mostly concerned
154 with matching leading `.'. */
155
156static int
157skipname (pat, dname)
158 char *pat;
159 char *dname;
160{
161 /* If a leading dot need not be explicitly matched, and the pattern
162 doesn't start with a `.', don't match `.' or `..' */
163 if (noglob_dot_filenames == 0 && pat[0] != '.' &&
164 (pat[0] != '\\' || pat[1] != '.') &&
165 (dname[0] == '.' &&
166 (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
167 return 1;
168
169 /* If a dot must be explicity matched, check to see if they do. */
170 else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
171 (pat[0] != '\\' || pat[1] != '.'))
172 return 1;
173
174 return 0;
175}
176
177#if HANDLE_MULTIBYTE
178/* Return 1 if DNAME should be skipped according to PAT. Handles multibyte
179 characters in PAT and DNAME. Mostly concerned with matching leading `.'. */
180
181static int
182mbskipname (pat, dname)
183 char *pat, *dname;
184{
185 int ret;
186 wchar_t *pat_wc, *dn_wc;
187 size_t pat_n, dn_n, n;
188
189 pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
190 dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
191
192 ret = 0;
193 if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
194 {
195 /* If a leading dot need not be explicitly matched, and the
196 pattern doesn't start with a `.', don't match `.' or `..' */
197 if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
198 (pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
199 (dn_wc[0] == L'.' &&
200 (dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
201 ret = 1;
202
203 /* If a leading dot must be explicity matched, check to see if the
204 pattern and dirname both have one. */
205 else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
206 pat_wc[0] != L'.' &&
207 (pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
208 ret = 1;
209 }
210
211 FREE (pat_wc);
212 FREE (dn_wc);
213
214 return ret;
215}
216#endif /* HANDLE_MULTIBYTE */
217
218/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
219static void
220udequote_pathname (pathname)
221 char *pathname;
222{
223 register int i, j;
224
225 for (i = j = 0; pathname && pathname[i]; )
226 {
227 if (pathname[i] == '\\')
228 i++;
229
230 pathname[j++] = pathname[i++];
231
232 if (pathname[i - 1] == 0)
233 break;
234 }
235 pathname[j] = '\0';
236}
237
238#if HANDLE_MULTIBYTE
239/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
240static void
241wdequote_pathname (pathname)
242 char *pathname;
243{
244 mbstate_t ps;
245 size_t len, n;
246 wchar_t *wpathname;
247 int i, j;
248 wchar_t *orig_wpathname;
249
250 len = strlen (pathname);
251 /* Convert the strings into wide characters. */
252 n = xdupmbstowcs (&wpathname, NULL, pathname);
253 if (n == (size_t) -1)
254 /* Something wrong. */
255 return;
256 orig_wpathname = wpathname;
257
258 for (i = j = 0; wpathname && wpathname[i]; )
259 {
260 if (wpathname[i] == L'\\')
261 i++;
262
263 wpathname[j++] = wpathname[i++];
264
265 if (wpathname[i - 1] == L'\0')
266 break;
267 }
268 wpathname[j] = L'\0';
269
270 /* Convert the wide character string into unibyte character set. */
271 memset (&ps, '\0', sizeof(mbstate_t));
272 n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
273 pathname[len] = '\0';
274
275 /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
276 free (orig_wpathname);
277}
278
279static void
280dequote_pathname (pathname)
281 char *pathname;
282{
283 if (MB_CUR_MAX > 1)
284 wdequote_pathname (pathname);
285 else
286 udequote_pathname (pathname);
287}
288#endif /* HANDLE_MULTIBYTE */
289
290/* Test whether NAME exists. */
291
292#if defined (HAVE_LSTAT)
293# define GLOB_TESTNAME(name) (lstat (name, &finfo))
294#else /* !HAVE_LSTAT */
295# if !defined (AFS)
296# define GLOB_TESTNAME(name) (test_eaccess (nextname, F_OK))
297# else /* AFS */
298# define GLOB_TESTNAME(name) (access (nextname, F_OK))
299# endif /* AFS */
300#endif /* !HAVE_LSTAT */
301
302/* Return 0 if DIR is a directory, -1 otherwise. */
303static int
304glob_testdir (dir)
305 char *dir;
306{
307 struct stat finfo;
308
309 if (stat (dir, &finfo) < 0)
310 return (-1);
311
312 if (S_ISDIR (finfo.st_mode) == 0)
313 return (-1);
314
315 return (0);
316}
317
318/* Return a vector of names of files in directory DIR
319 whose names match glob pattern PAT.
320 The names are not in any particular order.
321 Wildcards at the beginning of PAT do not match an initial period.
322
323 The vector is terminated by an element that is a null pointer.
324
325 To free the space allocated, first free the vector's elements,
326 then free the vector.
327
328 Return 0 if cannot get enough memory to hold the pointer
329 and the names.
330
331 Return -1 if cannot access directory DIR.
332 Look in errno for more information. */
333
334char **
335glob_vector (pat, dir, flags)
336 char *pat;
337 char *dir;
338 int flags;
339{
340 struct globval
341 {
342 struct globval *next;
343 char *name;
344 };
345
346 DIR *d;
347 register struct dirent *dp;
348 struct globval *lastlink;
349 register struct globval *nextlink;
350 register char *nextname, *npat;
351 unsigned int count;
352 int lose, skip;
353 register char **name_vector;
354 register unsigned int i;
355 int mflags; /* Flags passed to strmatch (). */
356 int nalloca;
357 struct globval *firstmalloc, *tmplink;
358
359 lastlink = 0;
360 count = lose = skip = 0;
361
362 firstmalloc = 0;
363
364 /* If PAT is empty, skip the loop, but return one (empty) filename. */
365 if (pat == 0 || *pat == '\0')
366 {
367 if (glob_testdir (dir) < 0)
368 return ((char **) &glob_error_return);
369
370 nextlink = (struct globval *)alloca (sizeof (struct globval));
371 if (nextlink == NULL)
372 return ((char **) NULL);
373
374 nextlink->next = (struct globval *)0;
375 nextname = (char *) malloc (1);
376 if (nextname == 0)
377 lose = 1;
378 else
379 {
380 lastlink = nextlink;
381 nextlink->name = nextname;
382 nextname[0] = '\0';
383 count = 1;
384 }
385
386 skip = 1;
387 }
388
389 /* If the filename pattern (PAT) does not contain any globbing characters,
390 we can dispense with reading the directory, and just see if there is
391 a filename `DIR/PAT'. If there is, and we can access it, just make the
392 vector to return and bail immediately. */
393 if (skip == 0 && glob_pattern_p (pat) == 0)
394 {
395 int dirlen;
396 struct stat finfo;
397
398 if (glob_testdir (dir) < 0)
399 return ((char **) &glob_error_return);
400
401 dirlen = strlen (dir);
402 nextname = (char *)malloc (dirlen + strlen (pat) + 2);
403 npat = (char *)malloc (strlen (pat) + 1);
404 if (nextname == 0 || npat == 0)
405 lose = 1;
406 else
407 {
408 strcpy (npat, pat);
409 dequote_pathname (npat);
410
411 strcpy (nextname, dir);
412 nextname[dirlen++] = '/';
413 strcpy (nextname + dirlen, npat);
414
415 if (GLOB_TESTNAME (nextname) >= 0)
416 {
417 free (nextname);
418 nextlink = (struct globval *)alloca (sizeof (struct globval));
419 if (nextlink)
420 {
421 nextlink->next = (struct globval *)0;
422 lastlink = nextlink;
423 nextlink->name = npat;
424 count = 1;
425 }
426 else
427 lose = 1;
428 }
429 else
430 {
431 free (nextname);
432 free (npat);
433 }
434 }
435
436 skip = 1;
437 }
438
439 if (skip == 0)
440 {
441 /* Open the directory, punting immediately if we cannot. If opendir
442 is not robust (i.e., it opens non-directories successfully), test
443 that DIR is a directory and punt if it's not. */
444#if defined (OPENDIR_NOT_ROBUST)
445 if (glob_testdir (dir) < 0)
446 return ((char **) &glob_error_return);
447#endif
448
449 d = opendir (dir);
450 if (d == NULL)
451 return ((char **) &glob_error_return);
452
453 /* Compute the flags that will be passed to strmatch(). We don't
454 need to do this every time through the loop. */
455 mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
456
457#ifdef FNM_CASEFOLD
458 if (glob_ignore_case)
459 mflags |= FNM_CASEFOLD;
460#endif
461
462 if (extended_glob)
463 mflags |= FNM_EXTMATCH;
464
465 /* Scan the directory, finding all names that match.
466 For each name that matches, allocate a struct globval
467 on the stack and store the name in it.
468 Chain those structs together; lastlink is the front of the chain. */
469 while (1)
470 {
471 /* Make globbing interruptible in the shell. */
472 if (interrupt_state)
473 {
474 lose = 1;
475 break;
476 }
477
478 dp = readdir (d);
479 if (dp == NULL)
480 break;
481
482 /* If this directory entry is not to be used, try again. */
483 if (REAL_DIR_ENTRY (dp) == 0)
484 continue;
485
486#if 0
487 if (dp->d_name == 0 || *dp->d_name == 0)
488 continue;
489#endif
490
491#if HANDLE_MULTIBYTE
492 if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
493 continue;
494 else
495#endif
496 if (skipname (pat, dp->d_name))
497 continue;
498
499 if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
500 {
501 if (nalloca < ALLOCA_MAX)
502 {
503 nextlink = (struct globval *) alloca (sizeof (struct globval));
504 nalloca += sizeof (struct globval);
505 }
506 else
507 {
508 nextlink = (struct globval *) malloc (sizeof (struct globval));
509 if (firstmalloc == 0)
510 firstmalloc = nextlink;
511 }
512 nextname = (char *) malloc (D_NAMLEN (dp) + 1);
513 if (nextlink == 0 || nextname == 0)
514 {
515 lose = 1;
516 break;
517 }
518 nextlink->next = lastlink;
519 lastlink = nextlink;
520 nextlink->name = nextname;
521 bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
522 ++count;
523 }
524 }
525
526 (void) closedir (d);
527 }
528
529 if (lose == 0)
530 {
531 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
532 lose |= name_vector == NULL;
533 }
534
535 /* Have we run out of memory? */
536 if (lose)
537 {
538 tmplink = 0;
539
540 /* Here free the strings we have got. */
541 while (lastlink)
542 {
543 if (firstmalloc)
544 {
545 if (lastlink == firstmalloc)
546 firstmalloc = 0;
547 tmplink = lastlink;
548 }
549 free (lastlink->name);
550 lastlink = lastlink->next;
551 FREE (tmplink);
552 }
553
554 QUIT;
555
556 return ((char **)NULL);
557 }
558
559 /* Copy the name pointers from the linked list into the vector. */
560 for (tmplink = lastlink, i = 0; i < count; ++i)
561 {
562 name_vector[i] = tmplink->name;
563 tmplink = tmplink->next;
564 }
565
566 name_vector[count] = NULL;
567
568 /* If we allocated some of the struct globvals, free them now. */
569 if (firstmalloc)
570 {
571 tmplink = 0;
572 while (lastlink)
573 {
574 tmplink = lastlink;
575 if (lastlink == firstmalloc)
576 lastlink = firstmalloc = 0;
577 else
578 lastlink = lastlink->next;
579 free (tmplink);
580 }
581 }
582
583 return (name_vector);
584}
585
586/* Return a new array which is the concatenation of each string in ARRAY
587 to DIR. This function expects you to pass in an allocated ARRAY, and
588 it takes care of free()ing that array. Thus, you might think of this
589 function as side-effecting ARRAY. This should handle GX_MARKDIRS. */
590static char **
591glob_dir_to_array (dir, array, flags)
592 char *dir, **array;
593 int flags;
594{
595 register unsigned int i, l;
596 int add_slash;
597 char **result, *new;
598 struct stat sb;
599
600 l = strlen (dir);
601 if (l == 0)
602 {
603 if (flags & GX_MARKDIRS)
604 for (i = 0; array[i]; i++)
605 {
606 if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
607 {
608 l = strlen (array[i]);
609 new = (char *)realloc (array[i], l + 2);
610 if (new == 0)
611 return NULL;
612 new[l] = '/';
613 new[l+1] = '\0';
614 array[i] = new;
615 }
616 }
617 return (array);
618 }
619
620 add_slash = dir[l - 1] != '/';
621
622 i = 0;
623 while (array[i] != NULL)
624 ++i;
625
626 result = (char **) malloc ((i + 1) * sizeof (char *));
627 if (result == NULL)
628 return (NULL);
629
630 for (i = 0; array[i] != NULL; i++)
631 {
632 /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
633 result[i] = (char *) malloc (l + strlen (array[i]) + 3);
634
635 if (result[i] == NULL)
636 return (NULL);
637
638 strcpy (result[i], dir);
639 if (add_slash)
640 result[i][l] = '/';
641 strcpy (result[i] + l + add_slash, array[i]);
642 if (flags & GX_MARKDIRS)
643 {
644 if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
645 {
646 size_t rlen;
647 rlen = strlen (result[i]);
648 result[i][rlen] = '/';
649 result[i][rlen+1] = '\0';
650 }
651 }
652 }
653 result[i] = NULL;
654
655 /* Free the input array. */
656 for (i = 0; array[i] != NULL; i++)
657 free (array[i]);
658 free ((char *) array);
659
660 return (result);
661}
662
663/* Do globbing on PATHNAME. Return an array of pathnames that match,
664 marking the end of the array with a null-pointer as an element.
665 If no pathnames match, then the array is empty (first element is null).
666 If there isn't enough memory, then return NULL.
667 If a file system error occurs, return -1; `errno' has the error code. */
668char **
669glob_filename (pathname, flags)
670 char *pathname;
671 int flags;
672{
673 char **result;
674 unsigned int result_size;
675 char *directory_name, *filename;
676 unsigned int directory_len;
677 int free_dirname; /* flag */
678
679 result = (char **) malloc (sizeof (char *));
680 result_size = 1;
681 if (result == NULL)
682 return (NULL);
683
684 result[0] = NULL;
685
686 directory_name = NULL;
687
688 /* Find the filename. */
689 filename = strrchr (pathname, '/');
690 if (filename == NULL)
691 {
692 filename = pathname;
693 directory_name = "";
694 directory_len = 0;
695 free_dirname = 0;
696 }
697 else
698 {
699 directory_len = (filename - pathname) + 1;
700 directory_name = (char *) malloc (directory_len + 1);
701
702 if (directory_name == 0) /* allocation failed? */
703 return (NULL);
704
705 bcopy (pathname, directory_name, directory_len);
706 directory_name[directory_len] = '\0';
707 ++filename;
708 free_dirname = 1;
709 }
710
711 /* If directory_name contains globbing characters, then we
712 have to expand the previous levels. Just recurse. */
713 if (glob_pattern_p (directory_name))
714 {
715 char **directories;
716 register unsigned int i;
717
718 if (directory_name[directory_len - 1] == '/')
719 directory_name[directory_len - 1] = '\0';
720
721 directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
722
723 if (free_dirname)
724 {
725 free (directory_name);
726 directory_name = NULL;
727 }
728
729 if (directories == NULL)
730 goto memory_error;
731 else if (directories == (char **)&glob_error_return)
732 {
733 free ((char *) result);
734 return ((char **) &glob_error_return);
735 }
736 else if (*directories == NULL)
737 {
738 free ((char *) directories);
739 free ((char *) result);
740 return ((char **) &glob_error_return);
741 }
742
743 /* We have successfully globbed the preceding directory name.
744 For each name in DIRECTORIES, call glob_vector on it and
745 FILENAME. Concatenate the results together. */
746 for (i = 0; directories[i] != NULL; ++i)
747 {
748 char **temp_results;
749
750 /* Scan directory even on a NULL pathname. That way, `*h/'
751 returns only directories ending in `h', instead of all
752 files ending in `h' with a `/' appended. */
753 temp_results = glob_vector (filename, directories[i], flags & ~GX_MARKDIRS);
754
755 /* Handle error cases. */
756 if (temp_results == NULL)
757 goto memory_error;
758 else if (temp_results == (char **)&glob_error_return)
759 /* This filename is probably not a directory. Ignore it. */
760 ;
761 else
762 {
763 char **array;
764 register unsigned int l;
765
766 array = glob_dir_to_array (directories[i], temp_results, flags);
767 l = 0;
768 while (array[l] != NULL)
769 ++l;
770
771 result =
772 (char **)realloc (result, (result_size + l) * sizeof (char *));
773
774 if (result == NULL)
775 goto memory_error;
776
777 for (l = 0; array[l] != NULL; ++l)
778 result[result_size++ - 1] = array[l];
779
780 result[result_size - 1] = NULL;
781
782 /* Note that the elements of ARRAY are not freed. */
783 free ((char *) array);
784 }
785 }
786 /* Free the directories. */
787 for (i = 0; directories[i]; i++)
788 free (directories[i]);
789
790 free ((char *) directories);
791
792 return (result);
793 }
794
795 /* If there is only a directory name, return it. */
796 if (*filename == '\0')
797 {
798 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
799 if (result == NULL)
800 return (NULL);
801 /* Handle GX_MARKDIRS here. */
802 result[0] = (char *) malloc (directory_len + 1);
803 if (result[0] == NULL)
804 goto memory_error;
805 bcopy (directory_name, result[0], directory_len + 1);
806 if (free_dirname)
807 free (directory_name);
808 result[1] = NULL;
809 return (result);
810 }
811 else
812 {
813 char **temp_results;
814
815 /* There are no unquoted globbing characters in DIRECTORY_NAME.
816 Dequote it before we try to open the directory since there may
817 be quoted globbing characters which should be treated verbatim. */
818 if (directory_len > 0)
819 dequote_pathname (directory_name);
820
821 /* We allocated a small array called RESULT, which we won't be using.
822 Free that memory now. */
823 free (result);
824
825 /* Just return what glob_vector () returns appended to the
826 directory name. */
827 temp_results = glob_vector (filename,
828 (directory_len == 0 ? "." : directory_name),
829 flags & ~GX_MARKDIRS);
830
831 if (temp_results == NULL || temp_results == (char **)&glob_error_return)
832 {
833 if (free_dirname)
834 free (directory_name);
835 return (temp_results);
836 }
837
838 result = glob_dir_to_array (directory_name, temp_results, flags);
839 if (free_dirname)
840 free (directory_name);
841 return (result);
842 }
843
844 /* We get to memory_error if the program has run out of memory, or
845 if this is the shell, and we have been interrupted. */
846 memory_error:
847 if (result != NULL)
848 {
849 register unsigned int i;
850 for (i = 0; result[i] != NULL; ++i)
851 free (result[i]);
852 free ((char *) result);
853 }
854
855 if (free_dirname && directory_name)
856 free (directory_name);
857
858 QUIT;
859
860 return (NULL);
861}
862
863#if defined (TEST)
864
865main (argc, argv)
866 int argc;
867 char **argv;
868{
869 unsigned int i;
870
871 for (i = 1; i < argc; ++i)
872 {
873 char **value = glob_filename (argv[i], 0);
874 if (value == NULL)
875 puts ("Out of memory.");
876 else if (value == &glob_error_return)
877 perror (argv[i]);
878 else
879 for (i = 0; value[i] != NULL; i++)
880 puts (value[i]);
881 }
882
883 exit (0);
884}
885#endif /* TEST. */
Note: See TracBrowser for help on using the repository browser.