1 /* Copyright (C) 1992-1998,2000,2002,2003,2009,2011
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library 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 GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 #include <bits/libc-lock.h>
27 # define SCANDIRAT scandirat
28 # define READDIR __readdir
29 # define DIRENT_TYPE struct dirent
32 #ifndef SKIP_SCANDIR_CANCEL
34 __scandir_cancel_handler (void *arg
)
36 struct scandir_cancel_struct
*cp
= arg
;
40 for (i
= 0; i
< cp
->cnt
; ++i
)
43 (void) __closedir (cp
->dp
);
49 SCANDIRAT (dfd
, dir
, namelist
, select
, cmp
)
52 DIRENT_TYPE
***namelist
;
53 int (*select
) (const DIRENT_TYPE
*);
54 int (*cmp
) (const DIRENT_TYPE
**, const DIRENT_TYPE
**);
56 DIR *dp
= __opendirat (dfd
, dir
);
57 DIRENT_TYPE
**v
= NULL
;
59 struct scandir_cancel_struct c
;
72 __libc_cleanup_push (__scandir_cancel_handler
, &c
);
74 while ((d
= READDIR (dp
)) != NULL
)
76 int use_it
= select
== NULL
;
81 /* The select function might have changed errno. It was
82 zero before and it need to be again to make the latter
92 /* Ignore errors from select or readdir */
95 if (__builtin_expect (c
.cnt
== vsize
, 0))
102 new = (DIRENT_TYPE
**) realloc (v
, vsize
* sizeof (*v
));
109 dsize
= &d
->d_name
[_D_ALLOC_NAMLEN (d
)] - (char *) d
;
110 vnew
= (DIRENT_TYPE
*) malloc (dsize
);
114 v
[c
.cnt
++] = (DIRENT_TYPE
*) memcpy (vnew
, d
, dsize
);
118 if (__builtin_expect (errno
, 0) != 0)
129 /* Sort the list if we have a comparison function to sort with. */
131 qsort (v
, c
.cnt
, sizeof (*v
),
132 (int (*) (const void *, const void *)) cmp
);
137 __libc_cleanup_pop (0);
139 (void) __closedir (dp
);
144 libc_hidden_def (SCANDIRAT
)