diff options
Diffstat (limited to 'openbsd-compat/glob.c')
-rw-r--r-- | openbsd-compat/glob.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index 85fccf4d1..742b4b954 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: glob.c,v 1.37 2011/09/20 10:18:46 stsp Exp $ */ | 1 | /* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1989, 1993 | 3 | * Copyright (c) 1989, 1993 |
4 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -133,16 +133,22 @@ typedef char Char; | |||
133 | #define GLOB_LIMIT_STAT 128 | 133 | #define GLOB_LIMIT_STAT 128 |
134 | #define GLOB_LIMIT_READDIR 16384 | 134 | #define GLOB_LIMIT_READDIR 16384 |
135 | 135 | ||
136 | /* Limit of recursion during matching attempts. */ | ||
137 | #define GLOB_LIMIT_RECUR 64 | ||
138 | |||
136 | struct glob_lim { | 139 | struct glob_lim { |
137 | size_t glim_malloc; | 140 | size_t glim_malloc; |
138 | size_t glim_stat; | 141 | size_t glim_stat; |
139 | size_t glim_readdir; | 142 | size_t glim_readdir; |
140 | }; | 143 | }; |
141 | 144 | ||
142 | /* Limit of recursion during matching attempts. */ | 145 | struct glob_path_stat { |
143 | #define GLOB_LIMIT_RECUR 64 | 146 | char *gps_path; |
147 | struct stat *gps_stat; | ||
148 | }; | ||
144 | 149 | ||
145 | static int compare(const void *, const void *); | 150 | static int compare(const void *, const void *); |
151 | static int compare_gps(const void *, const void *); | ||
146 | static int g_Ctoc(const Char *, char *, u_int); | 152 | static int g_Ctoc(const Char *, char *, u_int); |
147 | static int g_lstat(Char *, struct stat *, glob_t *); | 153 | static int g_lstat(Char *, struct stat *, glob_t *); |
148 | static DIR *g_opendir(Char *, glob_t *); | 154 | static DIR *g_opendir(Char *, glob_t *); |
@@ -555,9 +561,32 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) | |||
555 | else | 561 | else |
556 | return(GLOB_NOMATCH); | 562 | return(GLOB_NOMATCH); |
557 | } | 563 | } |
558 | if (!(pglob->gl_flags & GLOB_NOSORT)) | 564 | if (!(pglob->gl_flags & GLOB_NOSORT)) { |
559 | qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, | 565 | if ((pglob->gl_flags & GLOB_KEEPSTAT)) { |
560 | pglob->gl_pathc - oldpathc, sizeof(char *), compare); | 566 | /* Keep the paths and stat info synced during sort */ |
567 | struct glob_path_stat *path_stat; | ||
568 | int i; | ||
569 | int n = pglob->gl_pathc - oldpathc; | ||
570 | int o = pglob->gl_offs + oldpathc; | ||
571 | |||
572 | if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) | ||
573 | return GLOB_NOSPACE; | ||
574 | for (i = 0; i < n; i++) { | ||
575 | path_stat[i].gps_path = pglob->gl_pathv[o + i]; | ||
576 | path_stat[i].gps_stat = pglob->gl_statv[o + i]; | ||
577 | } | ||
578 | qsort(path_stat, n, sizeof(*path_stat), compare_gps); | ||
579 | for (i = 0; i < n; i++) { | ||
580 | pglob->gl_pathv[o + i] = path_stat[i].gps_path; | ||
581 | pglob->gl_statv[o + i] = path_stat[i].gps_stat; | ||
582 | } | ||
583 | free(path_stat); | ||
584 | } else { | ||
585 | qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, | ||
586 | pglob->gl_pathc - oldpathc, sizeof(char *), | ||
587 | compare); | ||
588 | } | ||
589 | } | ||
561 | return(0); | 590 | return(0); |
562 | } | 591 | } |
563 | 592 | ||
@@ -568,6 +597,15 @@ compare(const void *p, const void *q) | |||
568 | } | 597 | } |
569 | 598 | ||
570 | static int | 599 | static int |
600 | compare_gps(const void *_p, const void *_q) | ||
601 | { | ||
602 | const struct glob_path_stat *p = (const struct glob_path_stat *)_p; | ||
603 | const struct glob_path_stat *q = (const struct glob_path_stat *)_q; | ||
604 | |||
605 | return(strcmp(p->gps_path, q->gps_path)); | ||
606 | } | ||
607 | |||
608 | static int | ||
571 | glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) | 609 | glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) |
572 | { | 610 | { |
573 | Char pathbuf[MAXPATHLEN]; | 611 | Char pathbuf[MAXPATHLEN]; |