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

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

Applied bash31-016

  • Property svn:eol-style set to native
File size: 21.4 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 nalloca = 0;
364
365 /* If PAT is empty, skip the loop, but return one (empty) filename. */
366 if (pat == 0 || *pat == '\0')
367 {
368 if (glob_testdir (dir) < 0)
369 return ((char **) &glob_error_return);
370
371 nextlink = (struct globval *)alloca (sizeof (struct globval));
372 if (nextlink == NULL)
373 return ((char **) NULL);
374
375 nextlink->next = (struct globval *)0;
376 nextname = (char *) malloc (1);
377 if (nextname == 0)
378 lose = 1;
379 else
380 {
381 lastlink = nextlink;
382 nextlink->name = nextname;
383 nextname[0] = '\0';
384 count = 1;
385 }
386
387 skip = 1;
388 }
389
390 /* If the filename pattern (PAT) does not contain any globbing characters,
391 we can dispense with reading the directory, and just see if there is
392 a filename `DIR/PAT'. If there is, and we can access it, just make the
393 vector to return and bail immediately. */
394 if (skip == 0 && glob_pattern_p (pat) == 0)
395 {
396 int dirlen;
397 struct stat finfo;
398
399 if (glob_testdir (dir) < 0)
400 return ((char **) &glob_error_return);
401
402 dirlen = strlen (dir);
403 nextname = (char *)malloc (dirlen + strlen (pat) + 2);
404 npat = (char *)malloc (strlen (pat) + 1);
405 if (nextname == 0 || npat == 0)
406 lose = 1;
407 else
408 {
409 strcpy (npat, pat);
410 dequote_pathname (npat);
411
412 strcpy (nextname, dir);
413 nextname[dirlen++] = '/';
414 strcpy (nextname + dirlen, npat);
415
416 if (GLOB_TESTNAME (nextname) >= 0)
417 {
418 free (nextname);
419 nextlink = (struct globval *)alloca (sizeof (struct globval));
420 if (nextlink)
421 {
422 nextlink->next = (struct globval *)0;
423 lastlink = nextlink;
424 nextlink->name = npat;
425 count = 1;
426 }
427 else
428 lose = 1;
429 }
430 else
431 {
432 free (nextname);
433 free (npat);
434 }
435 }
436
437 skip = 1;
438 }
439
440 if (skip == 0)
441 {
442 /* Open the directory, punting immediately if we cannot. If opendir
443 is not robust (i.e., it opens non-directories successfully), test
444 that DIR is a directory and punt if it's not. */
445#if defined (OPENDIR_NOT_ROBUST)
446 if (glob_testdir (dir) < 0)
447 return ((char **) &glob_error_return);
448#endif
449
450 d = opendir (dir);
451 if (d == NULL)
452 return ((char **) &glob_error_return);
453
454 /* Compute the flags that will be passed to strmatch(). We don't
455 need to do this every time through the loop. */
456 mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
457
458#ifdef FNM_CASEFOLD
459 if (glob_ignore_case)
460 mflags |= FNM_CASEFOLD;
461#endif
462
463 if (extended_glob)
464 mflags |= FNM_EXTMATCH;
465
466 /* Scan the directory, finding all names that match.
467 For each name that matches, allocate a struct globval
468 on the stack and store the name in it.
469 Chain those structs together; lastlink is the front of the chain. */
470 while (1)
471 {
472 /* Make globbing interruptible in the shell. */
473 if (interrupt_state)
474 {
475 lose = 1;
476 break;
477 }
478
479 dp = readdir (d);
480 if (dp == NULL)
481 break;
482
483 /* If this directory entry is not to be used, try again. */
484 if (REAL_DIR_ENTRY (dp) == 0)
485 continue;
486
487#if 0
488 if (dp->d_name == 0 || *dp->d_name == 0)
489 continue;
490#endif
491
492#if HANDLE_MULTIBYTE
493 if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
494 continue;
495 else
496#endif
497 if (skipname (pat, dp->d_name))
498 continue;
499
500 if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
501 {
502 if (nalloca < ALLOCA_MAX)
503 {
504 nextlink = (struct globval *) alloca (sizeof (struct globval));
505 nalloca += sizeof (struct globval);
506 }
507 else
508 {
509 nextlink = (struct globval *) malloc (sizeof (struct globval));
510 if (firstmalloc == 0)
511 firstmalloc = nextlink;
512 }
513 nextname = (char *) malloc (D_NAMLEN (dp) + 1);
514 if (nextlink == 0 || nextname == 0)
515 {
516 lose = 1;
517 break;
518 }
519 nextlink->next = lastlink;
520 lastlink = nextlink;
521 nextlink->name = nextname;
522 bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
523 ++count;
524 }
525 }
526
527 (void) closedir (d);
528 }
529
530 if (lose == 0)
531 {
532 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
533 lose |= name_vector == NULL;
534 }
535
536 /* Have we run out of memory? */
537 if (lose)
538 {
539 tmplink = 0;
540
541 /* Here free the strings we have got. */
542 while (lastlink)
543 {
544 if (firstmalloc)
545 {
546 if (lastlink == firstmalloc)
547 firstmalloc = 0;
548 tmplink = lastlink;
549 }
550 else
551 tmplink = 0;
552 free (lastlink->name);
553 lastlink = lastlink->next;
554 FREE (tmplink);
555 }
556
557 QUIT;
558
559 return ((char **)NULL);
560 }
561
562 /* Copy the name pointers from the linked list into the vector. */
563 for (tmplink = lastlink, i = 0; i < count; ++i)
564 {
565 name_vector[i] = tmplink->name;
566 tmplink = tmplink->next;
567 }
568
569 name_vector[count] = NULL;
570
571 /* If we allocated some of the struct globvals, free them now. */
572 if (firstmalloc)
573 {
574 tmplink = 0;
575 while (lastlink)
576 {
577 tmplink = lastlink;
578 if (lastlink == firstmalloc)
579 lastlink = firstmalloc = 0;
580 else
581 lastlink = lastlink->next;
582 free (tmplink);
583 }
584 }
585
586 return (name_vector);
587}
588
589/* Return a new array which is the concatenation of each string in ARRAY
590 to DIR. This function expects you to pass in an allocated ARRAY, and
591 it takes care of free()ing that array. Thus, you might think of this
592 function as side-effecting ARRAY. This should handle GX_MARKDIRS. */
593static char **
594glob_dir_to_array (dir, array, flags)
595 char *dir, **array;
596 int flags;
597{
598 register unsigned int i, l;
599 int add_slash;
600 char **result, *new;
601 struct stat sb;
602
603 l = strlen (dir);
604 if (l == 0)
605 {
606 if (flags & GX_MARKDIRS)
607 for (i = 0; array[i]; i++)
608 {
609 if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
610 {
611 l = strlen (array[i]);
612 new = (char *)realloc (array[i], l + 2);
613 if (new == 0)
614 return NULL;
615 new[l] = '/';
616 new[l+1] = '\0';
617 array[i] = new;
618 }
619 }
620 return (array);
621 }
622
623 add_slash = dir[l - 1] != '/';
624
625 i = 0;
626 while (array[i] != NULL)
627 ++i;
628
629 result = (char **) malloc ((i + 1) * sizeof (char *));
630 if (result == NULL)
631 return (NULL);
632
633 for (i = 0; array[i] != NULL; i++)
634 {
635 /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
636 result[i] = (char *) malloc (l + strlen (array[i]) + 3);
637
638 if (result[i] == NULL)
639 return (NULL);
640
641 strcpy (result[i], dir);
642 if (add_slash)
643 result[i][l] = '/';
644 strcpy (result[i] + l + add_slash, array[i]);
645 if (flags & GX_MARKDIRS)
646 {
647 if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
648 {
649 size_t rlen;
650 rlen = strlen (result[i]);
651 result[i][rlen] = '/';
652 result[i][rlen+1] = '\0';
653 }
654 }
655 }
656 result[i] = NULL;
657
658 /* Free the input array. */
659 for (i = 0; array[i] != NULL; i++)
660 free (array[i]);
661 free ((char *) array);
662
663 return (result);
664}
665
666/* Do globbing on PATHNAME. Return an array of pathnames that match,
667 marking the end of the array with a null-pointer as an element.
668 If no pathnames match, then the array is empty (first element is null).
669 If there isn't enough memory, then return NULL.
670 If a file system error occurs, return -1; `errno' has the error code. */
671char **
672glob_filename (pathname, flags)
673 char *pathname;
674 int flags;
675{
676 char **result;
677 unsigned int result_size;
678 char *directory_name, *filename;
679 unsigned int directory_len;
680 int free_dirname; /* flag */
681
682 result = (char **) malloc (sizeof (char *));
683 result_size = 1;
684 if (result == NULL)
685 return (NULL);
686
687 result[0] = NULL;
688
689 directory_name = NULL;
690
691 /* Find the filename. */
692 filename = strrchr (pathname, '/');
693 if (filename == NULL)
694 {
695 filename = pathname;
696 directory_name = "";
697 directory_len = 0;
698 free_dirname = 0;
699 }
700 else
701 {
702 directory_len = (filename - pathname) + 1;
703 directory_name = (char *) malloc (directory_len + 1);
704
705 if (directory_name == 0) /* allocation failed? */
706 return (NULL);
707
708 bcopy (pathname, directory_name, directory_len);
709 directory_name[directory_len] = '\0';
710 ++filename;
711 free_dirname = 1;
712 }
713
714 /* If directory_name contains globbing characters, then we
715 have to expand the previous levels. Just recurse. */
716 if (glob_pattern_p (directory_name))
717 {
718 char **directories;
719 register unsigned int i;
720
721 if (directory_name[directory_len - 1] == '/')
722 directory_name[directory_len - 1] = '\0';
723
724 directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
725
726 if (free_dirname)
727 {
728 free (directory_name);
729 directory_name = NULL;
730 }
731
732 if (directories == NULL)
733 goto memory_error;
734 else if (directories == (char **)&glob_error_return)
735 {
736 free ((char *) result);
737 return ((char **) &glob_error_return);
738 }
739 else if (*directories == NULL)
740 {
741 free ((char *) directories);
742 free ((char *) result);
743 return ((char **) &glob_error_return);
744 }
745
746 /* We have successfully globbed the preceding directory name.
747 For each name in DIRECTORIES, call glob_vector on it and
748 FILENAME. Concatenate the results together. */
749 for (i = 0; directories[i] != NULL; ++i)
750 {
751 char **temp_results;
752
753 /* Scan directory even on a NULL pathname. That way, `*h/'
754 returns only directories ending in `h', instead of all
755 files ending in `h' with a `/' appended. */
756 temp_results = glob_vector (filename, directories[i], flags & ~GX_MARKDIRS);
757
758 /* Handle error cases. */
759 if (temp_results == NULL)
760 goto memory_error;
761 else if (temp_results == (char **)&glob_error_return)
762 /* This filename is probably not a directory. Ignore it. */
763 ;
764 else
765 {
766 char **array;
767 register unsigned int l;
768
769 array = glob_dir_to_array (directories[i], temp_results, flags);
770 l = 0;
771 while (array[l] != NULL)
772 ++l;
773
774 result =
775 (char **)realloc (result, (result_size + l) * sizeof (char *));
776
777 if (result == NULL)
778 goto memory_error;
779
780 for (l = 0; array[l] != NULL; ++l)
781 result[result_size++ - 1] = array[l];
782
783 result[result_size - 1] = NULL;
784
785 /* Note that the elements of ARRAY are not freed. */
786 free ((char *) array);
787 }
788 }
789 /* Free the directories. */
790 for (i = 0; directories[i]; i++)
791 free (directories[i]);
792
793 free ((char *) directories);
794
795 return (result);
796 }
797
798 /* If there is only a directory name, return it. */
799 if (*filename == '\0')
800 {
801 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
802 if (result == NULL)
803 return (NULL);
804 /* Handle GX_MARKDIRS here. */
805 result[0] = (char *) malloc (directory_len + 1);
806 if (result[0] == NULL)
807 goto memory_error;
808 bcopy (directory_name, result[0], directory_len + 1);
809 if (free_dirname)
810 free (directory_name);
811 result[1] = NULL;
812 return (result);
813 }
814 else
815 {
816 char **temp_results;
817
818 /* There are no unquoted globbing characters in DIRECTORY_NAME.
819 Dequote it before we try to open the directory since there may
820 be quoted globbing characters which should be treated verbatim. */
821 if (directory_len > 0)
822 dequote_pathname (directory_name);
823
824 /* We allocated a small array called RESULT, which we won't be using.
825 Free that memory now. */
826 free (result);
827
828 /* Just return what glob_vector () returns appended to the
829 directory name. */
830 temp_results = glob_vector (filename,
831 (directory_len == 0 ? "." : directory_name),
832 flags & ~GX_MARKDIRS);
833
834 if (temp_results == NULL || temp_results == (char **)&glob_error_return)
835 {
836 if (free_dirname)
837 free (directory_name);
838 return (temp_results);
839 }
840
841 result = glob_dir_to_array (directory_name, temp_results, flags);
842 if (free_dirname)
843 free (directory_name);
844 return (result);
845 }
846
847 /* We get to memory_error if the program has run out of memory, or
848 if this is the shell, and we have been interrupted. */
849 memory_error:
850 if (result != NULL)
851 {
852 register unsigned int i;
853 for (i = 0; result[i] != NULL; ++i)
854 free (result[i]);
855 free ((char *) result);
856 }
857
858 if (free_dirname && directory_name)
859 free (directory_name);
860
861 QUIT;
862
863 return (NULL);
864}
865
866#if defined (TEST)
867
868main (argc, argv)
869 int argc;
870 char **argv;
871{
872 unsigned int i;
873
874 for (i = 1; i < argc; ++i)
875 {
876 char **value = glob_filename (argv[i], 0);
877 if (value == NULL)
878 puts ("Out of memory.");
879 else if (value == &glob_error_return)
880 perror (argv[i]);
881 else
882 for (i = 0; value[i] != NULL; i++)
883 puts (value[i]);
884 }
885
886 exit (0);
887}
888#endif /* TEST. */
Note: See TracBrowser for help on using the repository browser.