mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-19 03:15:00 +00:00
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>
This commit is contained in:
parent
e6d5241534
commit
62584db191
2 changed files with 149 additions and 0 deletions
|
@ -19,10 +19,13 @@
|
||||||
* MA 02111-1307 USA
|
* MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -261,3 +264,101 @@ int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
48
include/os.h
48
include/os.h
|
@ -146,4 +146,52 @@ u64 os_get_nsec(void);
|
||||||
*/
|
*/
|
||||||
int os_parse_args(struct sandbox_state *state, int argc, char *argv[]);
|
int os_parse_args(struct sandbox_state *state, int argc, char *argv[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types of directory entry that we support. See also os_dirent_typename in
|
||||||
|
* the C file.
|
||||||
|
*/
|
||||||
|
enum os_dirent_t {
|
||||||
|
OS_FILET_REG, /* Regular file */
|
||||||
|
OS_FILET_LNK, /* Symbolic link */
|
||||||
|
OS_FILET_DIR, /* Directory */
|
||||||
|
OS_FILET_UNKNOWN, /* Something else */
|
||||||
|
|
||||||
|
OS_FILET_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A directory entry node, containing information about a single dirent */
|
||||||
|
struct os_dirent_node {
|
||||||
|
struct os_dirent_node *next; /* Pointer to next node, or NULL */
|
||||||
|
ulong size; /* Size of file in bytes */
|
||||||
|
enum os_dirent_t type; /* Type of entry */
|
||||||
|
char name[0]; /* Name of entry */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a directionry listing
|
||||||
|
*
|
||||||
|
* This allocates and returns a linked list containing the directory listing.
|
||||||
|
*
|
||||||
|
* @param dirname Directory to examine
|
||||||
|
* @param headp Returns pointer to head of linked list, or NULL if none
|
||||||
|
* @return 0 if ok, -ve on error
|
||||||
|
*/
|
||||||
|
int os_dirent_ls(const char *dirname, struct os_dirent_node **headp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of a directory entry type
|
||||||
|
*
|
||||||
|
* @param type Type to cehck
|
||||||
|
* @return string containing the name of that type, or "???" if none/invalid
|
||||||
|
*/
|
||||||
|
const char *os_dirent_get_typename(enum os_dirent_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of a file
|
||||||
|
*
|
||||||
|
* @param fname Filename to check
|
||||||
|
* @return size of file, or -1 if an error ocurred
|
||||||
|
*/
|
||||||
|
ssize_t os_get_filesize(const char *fname);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue