summaryrefslogtreecommitdiff
path: root/arch/sandbox/cpu/os.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2012-12-26 09:53:34 +0000
committerTom Rini <trini@ti.com>2013-03-04 14:19:56 -0500
commit62584db191013f13133be0f6702d0c935a7c85a6 (patch)
treea8a688c79900497e511269216623fd54105efd10 /arch/sandbox/cpu/os.c
parente6d5241534486effa116bf685f7707041492ec7b (diff)
downloadu-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.c101
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;
+}