Mercurial > code
changeset 150:d08c18d8a6ef
Welcom directory.[ch]
author | markand <devnull@localhost> |
---|---|
date | Wed, 23 May 2012 21:29:16 +0200 |
parents | 2563b3e71859 |
children | cedd831d02ff |
files | directory.c directory.h |
diffstat | 2 files changed, 205 insertions(+), 0 deletions(-) [+] |
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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/directory.h Wed May 23 21:29:16 2012 +0200 @@ -0,0 +1,61 @@ +/* + * directory.h -- 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. + */ + +#ifndef _DIRECTORY_H_ +#define _DIRECTORY_H_ + +struct directory { + int nents; /* number of entries */ + + struct { + char *name; /* entry name */ + int length; /* length of entry */ + int type; /* type of entry */ + } *ents; +}; + +#if defined(_WIN32) + +# include <windows.h> + +enum { + DIRECTORY_DIR = FILE_ATTRIBUTE_DIRECTORY, + DIRECTORY_FILE = FILE_ATTRIBUTE_NORMAL +}; + +#else + +# include <dirent.h> + +enum { + DIRECTORY_DIR = DT_DIR, + DIRECTORY_FILE = DT_REG +}; + +#endif + +struct directory * +directory_open(const char *); + +const char * +directory_error(void); + +void +directory_free(struct directory *); + +#endif /* _DIRECTORY_H_ */