Mercurial > code
diff directory.c @ 150:d08c18d8a6ef
Welcom directory.[ch]
author | markand <devnull@localhost> |
---|---|
date | Wed, 23 May 2012 21:29:16 +0200 |
parents | |
children | 54976019a5a8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/directory.c Wed May 23 21:29:16 2012 +0200 @@ -0,0 +1,144 @@ +/* + * directory.c -- portable way to open directories + * + * Copyright (c) 2011, 2012 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "directory.h" + +#if defined(_WIN32) /* WINDOWS */ + +struct directory * +directory_open(const char *path) +{ + WIN32_FIND_DATA fdata; + HANDLE h; + struct directory *res; + char respath[FILENAME_MAX + 1]; + + if (!(res = calloc(1, sizeof (struct directory)))) + return NULL; + + snprintf(respath, sizeof (respath), "%s/*", path); + + if ((h = FindFirstFile(respath, &fdata)) == INVALID_HANDLE_VALUE) { + free(res); + return NULL; + } + + do { + res->ents = realloc(res->ents, + sizeof (*res->ents) * (res->nents + 1)); + + /* Fail to reallocate */ + if (!res->ents) { + free(res); + res = NULL; + break; + } + + res->ents[res->nents].name = strdup(fdata.cFileName); + res->ents[res->nents].type = fdata.dwFileAttributes; + res->ents[res->nents++].length = strlen(fdata.cFileName); + } while (FindNextFile(h, &fdata) != 0); + + return res; +} + +const char * +directory_error(void) +{ + static char msg[1024]; + DWORD num; + + num = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + num, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + msg, + sizeof (msg), + NULL + ); + + return msg; +} + +#else /* UNIX */ + +# include <errno.h> + +struct directory * +directory_open(const char *path) +{ + DIR *dp; + struct dirent *ent; + struct directory *res; + + if (!(res = calloc(1, sizeof (struct directory)))) + return NULL; + + if (!(dp = opendir(path))) { + free(res); + return NULL; + } + + while ((ent = readdir(dp))) { + res->ents = realloc(res->ents, + sizeof (*res->ents) * (res->nents + 1)); + + /* Fail to reallocate */ + if (!res->ents) { + free(res); + res = NULL; + break; + } + + res->ents[res->nents].name = strdup(ent->d_name); + res->ents[res->nents].type = ent->d_type; + res->ents[res->nents++].length = ent->d_namlen; + } + + (void)closedir(dp); + + return res; +} + +const char * +directory_error(void) +{ + return strerror(errno); +} + +#endif + +void +directory_free(struct directory *dir) +{ + int i; + + for (i = 0; i < dir->nents; ++i) + free(dir->ents[i].name); + + free(dir->ents); + free(dir); +} \ No newline at end of file