From patchwork Wed Dec 26 19:53:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 208206 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 0C4492C007A for ; Thu, 27 Dec 2012 06:54:53 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A27584A0A8; Wed, 26 Dec 2012 20:54:51 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fR8UFLWelGFk; Wed, 26 Dec 2012 20:54:51 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 81E684A0A9; Wed, 26 Dec 2012 20:54:33 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D73824A09D for ; Wed, 26 Dec 2012 20:54:21 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lcwY+eX7UNR9 for ; Wed, 26 Dec 2012 20:54:20 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-qa0-f74.google.com (mail-qa0-f74.google.com [209.85.216.74]) by theia.denx.de (Postfix) with ESMTPS id 597494A056 for ; Wed, 26 Dec 2012 20:54:14 +0100 (CET) Received: by mail-qa0-f74.google.com with SMTP id r4so963154qaq.5 for ; Wed, 26 Dec 2012 11:54:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=F0oeCuQYdYGG01sM2dUpI9acwssizmNhwLzvkrUHnjE=; b=h+j28spdljIHn0eOhDIylPxG2+sgFw8JBbnTf0URkC5ZzB0jpodkSUEOBZNoLgQMYy Wxu1m6pDdLeECaKBT/Jozxth5Lx3xguZpRfDbDchWIIVWXMPI/GlbBeU2Z3o5lRAd4kv OIdjd6qMjgUosDGbUPLMOh6TR+QGhj7ufZLtvPmsFvVLsuVBzDwlOs1aF9N1ffNf5BO2 rPiWvjQcqT7Poyzkwpkcglnal5Y9/q8mthGWMtgvvEDujozVUFaNu9ltG34qYzIZtpTS Ln69AljmHQXqAM+XVxKJe+ibJjaj3N4vIl1lw4khRNAnJh3bU9HEBox1kSdRSbY9Z4L8 j/JQ== X-Received: by 10.236.179.72 with SMTP id g48mr12125506yhm.37.1356551653828; Wed, 26 Dec 2012 11:54:13 -0800 (PST) Received: from wpzn3.hot.corp.google.com (216-239-44-65.google.com [216.239.44.65]) by gmr-mx.google.com with ESMTPS id s58si2358995yhi.6.2012.12.26.11.54.13 (version=TLSv1/SSLv3 cipher=AES128-SHA); Wed, 26 Dec 2012 11:54:13 -0800 (PST) Received: from kaka.mtv.corp.google.com (kaka.mtv.corp.google.com [172.22.73.79]) by wpzn3.hot.corp.google.com (Postfix) with ESMTP id 92430100048; Wed, 26 Dec 2012 11:54:13 -0800 (PST) Received: by kaka.mtv.corp.google.com (Postfix, from userid 121222) id 53646160C13; Wed, 26 Dec 2012 11:54:13 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Date: Wed, 26 Dec 2012 11:53:34 -0800 Message-Id: <1356551618-8280-8-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.7.3 In-Reply-To: <1356551618-8280-1-git-send-email-sjg@chromium.org> References: <1356551618-8280-1-git-send-email-sjg@chromium.org> X-Gm-Message-State: ALoCoQllTnH4B5OsFv1L2vUG/or5EPumDD8vbrkoFGiUhSpcxatkmUS6T5CQzkm6KZoGCvAl/QJ8cr4PLe4z6jU5wJUTYUwV0nU3bbT5UYHlrPOGV0qWcKg27QkvvpNkB5IZDgr33w2b3yV4nosPUKfOiIYtn1X/kBh4YSH7czgKPA8cSPQifVbBwG0KEXJsldinMiC8z5dI Cc: Tom Rini Subject: [U-Boot] [PATCH 07/11] sandbox: Add a way of obtaining directory listings X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 Reviewed-by: Tom Rini --- arch/sandbox/cpu/os.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ include/os.h | 48 +++++++++++++++++++++++ 2 files changed, 149 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 #include #include #include +#include #include +#include #include #include #include @@ -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; +} diff --git a/include/os.h b/include/os.h index c452d1b..038aba9 100644 --- a/include/os.h +++ b/include/os.h @@ -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