diff options
author | Simon Glass <sjg@chromium.org> | 2012-12-26 09:53:34 +0000 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-03-04 14:19:56 -0500 |
commit | 62584db191013f13133be0f6702d0c935a7c85a6 (patch) | |
tree | a8a688c79900497e511269216623fd54105efd10 /arch/sandbox/cpu/os.c | |
parent | e6d5241534486effa116bf685f7707041492ec7b (diff) | |
download | u-boot-imx-62584db191013f13133be0f6702d0c935a7c85a6.zip u-boot-imx-62584db191013f13133be0f6702d0c935a7c85a6.tar.gz u-boot-imx-62584db191013f13133be0f6702d0c935a7c85a6.tar.bz2 |
sandbox: Add a way of obtaining directory listings
This implementation uses opendir()/readdir() to access the directory
information and then puts it in a linked list for the caller's use.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'arch/sandbox/cpu/os.c')
-rw-r--r-- | arch/sandbox/cpu/os.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 3e37c93..d075407 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -19,10 +19,13 @@ * MA 02111-1307 USA */ +#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <getopt.h> +#include <stdio.h> #include <stdlib.h> +#include <string.h> #include <termios.h> #include <time.h> #include <unistd.h> @@ -261,3 +264,101 @@ int os_parse_args(struct sandbox_state *state, int argc, char *argv[]) return 0; } + +void os_dirent_free(struct os_dirent_node *node) +{ + struct os_dirent_node *next; + + while (node) { + next = node->next; + free(node); + node = next; + } +} + +int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) +{ + struct dirent entry, *result; + struct os_dirent_node *head, *node, *next; + struct stat buf; + DIR *dir; + int ret; + char *fname; + int len; + + *headp = NULL; + dir = opendir(dirname); + if (!dir) + return -1; + + /* Create a buffer for the maximum filename length */ + len = sizeof(entry.d_name) + strlen(dirname) + 2; + fname = malloc(len); + if (!fname) { + ret = -ENOMEM; + goto done; + } + + for (node = head = NULL;; node = next) { + ret = readdir_r(dir, &entry, &result); + if (ret || !result) + break; + next = malloc(sizeof(*node) + strlen(entry.d_name) + 1); + if (!next) { + os_dirent_free(head); + ret = -ENOMEM; + goto done; + } + strcpy(next->name, entry.d_name); + switch (entry.d_type) { + case DT_REG: + next->type = OS_FILET_REG; + break; + case DT_DIR: + next->type = OS_FILET_DIR; + break; + case DT_LNK: + next->type = OS_FILET_LNK; + break; + } + next->size = 0; + snprintf(fname, len, "%s/%s", dirname, next->name); + if (!stat(fname, &buf)) + next->size = buf.st_size; + if (node) + node->next = next; + if (!head) + head = node; + } + *headp = head; + +done: + closedir(dir); + return ret; +} + +const char *os_dirent_typename[OS_FILET_COUNT] = { + " ", + "SYM", + "DIR", + "???", +}; + +const char *os_dirent_get_typename(enum os_dirent_t type) +{ + if (type >= 0 && type < OS_FILET_COUNT) + return os_dirent_typename[type]; + + return os_dirent_typename[OS_FILET_UNKNOWN]; +} + +ssize_t os_get_filesize(const char *fname) +{ + struct stat buf; + int ret; + + ret = stat(fname, &buf); + if (ret) + return ret; + return buf.st_size; +} |