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:
Simon Glass 2012-12-26 09:53:34 +00:00 committed by Tom Rini
parent e6d5241534
commit 62584db191
2 changed files with 149 additions and 0 deletions

View File

@ -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;
}

View File

@ -146,4 +146,52 @@ u64 os_get_nsec(void);
*/
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