[klibc] [PATCH 1/3] klibc: Add scandir() and alphasort() support.
maximilian attems
max at stro.at
Tue Aug 2 14:07:19 PDT 2011
On Fri, 29 Jul 2011, Mike Waychison wrote:
> Add support for scandir() and alphasort() as defined in POSIX.1-2008.
>
> Signed-off-by: Mike Waychison <mikew at google.com>
> ---
> usr/include/dirent.h | 7 +++++
> usr/klibc/Kbuild | 2 +
> usr/klibc/scandir.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 84 insertions(+), 1 deletions(-)
> create mode 100644 usr/klibc/scandir.c
>
> diff --git a/usr/include/dirent.h b/usr/include/dirent.h
> index e324474..3b1ff59 100644
> --- a/usr/include/dirent.h
> +++ b/usr/include/dirent.h
> @@ -30,4 +30,11 @@ static __inline__ int dirfd(DIR * __d)
> return __d->__fd;
> }
>
> +__extern int scandir(const char *dirp, struct dirent ***namelist,
> + int (*filter)(const struct dirent *),
> + int (*compar)(const struct dirent **,
> + const struct dirent **));
> +
> +int alphasort(const struct dirent **a, const struct dirent **b);
> +
> #endif /* _DIRENT_H */
please no names in the header files, it breaks macros.
ah and alphasort needs __extern too.
> diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
> index af40367..40e61da 100644
> --- a/usr/klibc/Kbuild
> +++ b/usr/klibc/Kbuild
> @@ -42,7 +42,7 @@ klib-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \
> seteuid.o setegid.o \
> getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
> clearenv.o nullenv.o \
> - getopt.o getopt_long.o readdir.o remove.o \
> + getopt.o getopt_long.o readdir.o scandir.o remove.o \
> syslog.o closelog.o pty.o getpt.o posix_openpt.o isatty.o reboot.o \
> time.o utime.o llseek.o nice.o getpriority.o \
> qsort.o bsearch.o \
please put alphasort in separate file.
> diff --git a/usr/klibc/scandir.c b/usr/klibc/scandir.c
> new file mode 100644
> index 0000000..1f58b15
> --- /dev/null
> +++ b/usr/klibc/scandir.c
> @@ -0,0 +1,76 @@
> +/*
> + * scandir.c: scandir/alphasort
> + */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +
> +#include <dirent.h>
> +
> +int scandir(const char *dirp, struct dirent ***namelist,
> + int (*filter)(const struct dirent *),
> + int (*compar)(const struct dirent **, const struct dirent **))
> +{
> + struct dirent **nl = NULL, **next_nl;
> + struct dirent *dirent;
> + size_t count = 0;
> + size_t allocated = 0;
> + DIR *dir;
> +
> + dir = opendir(dirp);
> + if (!dir)
> + return -1;
> +
> + while (1) {
> + dirent = readdir(dir);
> + if (!dirent)
> + break;
> + if (!filter || filter(dirent)) {
> + struct dirent *copy;
> + copy = malloc(sizeof(*copy));
> + if (!copy)
> + goto cleanup_fail;
> + memcpy(copy, dirent, sizeof(*copy));
> +
> + /* Extend the array if needed */
> + if (count == allocated) {
> + if (allocated == 0)
> + allocated = 15; /* ~1 page worth */
> + else
> + allocated *= 2;
> + next_nl = realloc(nl, allocated);
> + if (!next_nl) {
> + free(copy);
> + goto cleanup_fail;
> + }
> + nl = next_nl;
> + }
> +
> + nl[count++] = copy;
> + }
> + }
> +
> + qsort(nl, count, sizeof(struct dirent *),
> + (int (*)(const void *, const void *))compar);
> +
> + closedir(dir);
> +
> + *namelist = nl;
> + return count;
> +
> +cleanup_fail:
> + while (count) {
> + dirent = nl[--count];
> + free(dirent);
> + }
> + free(nl);
> + closedir(dir);
> + errno = ENOMEM;
> + return -1;
> +}
> +
> +int alphasort(const struct dirent **a, const struct dirent **b)
> +{
> + return strcmp((*a)->d_name, (*b)->d_name);
> +}
other then that looks good, thanks to hpa for quick review.
--
maks
P.S. need to fix the sys/capability.h too.
More information about the klibc
mailing list