blob: 540915d8006f0542abd00f2a1a52a15d2080a352 [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include <stdio.h>
#include <string.h>
#include <misc/printk.h>
#include <fs.h>
static void file_tests(void);
static void dir_tests(void);
#define TEST_SUB_DIR "sub1"
#define TEST_FILE "testfile.txt"
/*
* @file
* @brief File system demo
* Demonstrates the ZEPHYR File System APIs
*/
void main(void)
{
printk("File System Demo!\n\n");
file_tests();
dir_tests();
}
static int check_file_dir_exists(const char *path)
{
int res;
struct zfs_dirent entry;
res = fs_stat(path, &entry);
return !res;
}
static int open_file(ZFILE *fp, const char *path)
{
int res;
if (check_file_dir_exists(path)) {
printk("Opening existing file %s\n", path);
} else {
printk("Creating new file %s\n", path);
}
res = fs_open(fp, path);
if (res) {
printk("Failed opening file [%d]\n", res);
return res;
}
printk("Opened file %s\n", path);
return res;
}
static const char test_str[] = "hello world!";
static int write_test(ZFILE *fp, off_t ofs, const char *str)
{
ssize_t brw;
int res;
res = fs_seek(fp, ofs, SEEK_SET);
if (res) {
printk("fs_seek failed [%d]\n", res);
fs_close(fp);
return res;
}
brw = fs_write(fp, (char *)str, strlen(str));
if (brw < 0) {
printk("Failed writing to file [%d]\n", brw);
fs_close(fp);
return brw;
}
if (brw < strlen(str)) {
printk("Unable to complete write. Volume full.\n");
printk("Number of bytes written: [%d]\n", brw);
fs_close(fp);
return -1;
}
printk("Data successfully written!\n");
printk("Data written:\"%s\"\n\n", str);
return res;
}
static int read_test(ZFILE *fp, off_t ofs, size_t sz, char *read_buff)
{
ssize_t brw;
int res;
res = fs_seek(fp, ofs, SEEK_SET);
if (res) {
printk("fs_seek failed [%d]\n", res);
fs_close(fp);
return res;
}
brw = fs_read(fp, read_buff, sz);
if (brw < 0) {
printk("Failed reading file [%d]\n", brw);
fs_close(fp);
return res;
}
printk("Data successfully read!\n");
read_buff[brw] = 0;
printk("Data read:\"%s\"\n\n", read_buff);
return res;
}
static int close_file(ZFILE *fp, const char *path)
{
int res;
res = fs_close(fp);
if (res) {
printk("Error closing file [%d]\n", res);
return res;
}
printk("Closed file %s\n", path);
return res;
}
static int delete_test(const char *path)
{
int res;
/* Delete the file and verify checking its status */
res = fs_unlink(path);
if (res) {
printk("Error deleting file [%d]\n", res);
return res;
}
/* Check if file was deleted */
if (check_file_dir_exists(path)) {
printk("Failed deleting %s\n", path);
return -1;
}
printk("File (%s) deleted successfully!\n", path);
return 0;
}
static void file_tests(void)
{
ZFILE fp;
int res;
char read_buff[80];
res = open_file(&fp, TEST_FILE);
if (res) {
return;
}
res = write_test(&fp, 0, test_str);
if (res) {
return;
}
res = read_test(&fp, 0, strlen(test_str), read_buff);
if (res) {
return;
}
if (strcmp(test_str, read_buff)) {
printk("Error - Data read does not match data written\n");
return;
}
printk("Data read matches data written!\n");
res = close_file(&fp, TEST_FILE);
if (res) {
return;
}
res = delete_test(TEST_FILE);
if (res) {
return;
}
}
static int create_dir(const char *path)
{
int res;
res = fs_mkdir(path);
if (res) {
printk("Error creating dir[%d]\n", res);
return res;
}
printk("Created dir %s!\n", path);
return 0;
}
/* Deletes files and sub directories one level deep */
static int remove_dir(const char *path)
{
int res;
ZDIR dp;
static struct zfs_dirent entry;
char file_path[80];
if (!check_file_dir_exists(path)) {
return 0;
}
res = fs_opendir(&dp, path);
if (res) {
printk("Error opening dir[%d]\n", res);
return res;
}
printk("\nRemoving files and sub directories in %s\n", path);
for (;;) {
res = fs_readdir(&dp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
/* Delete file or sub directory */
sprintf(file_path, "%s/%s", path, entry.name);
printk("Removing %s\n", file_path);
res = fs_unlink(file_path);
if (res) {
printk("Error deleting file/dir [%d]\n", res);
fs_closedir(&dp);
return res;
}
}
fs_closedir(&dp);
/* Remove the sub directory */
res = fs_unlink(path);
if (res) {
printk("Error removing dir [%d]\n", res);
return res;
}
printk("Removed dir %s!\n", path);
return 0;
}
static int list_dir(const char *path)
{
int res;
ZDIR dp;
static struct zfs_dirent entry;
res = fs_opendir(&dp, path);
if (res) {
printk("Error opening dir[%d]\n", res);
return res;
}
printk("\nListing dir %s:\n", path);
for (;;) {
res = fs_readdir(&dp, &entry);
/* entry.name[0] == 0 means end-of-dir */
if (res || entry.name[0] == 0) {
break;
}
if (entry.type == DIR_ENTRY_DIR) {
printk("[DIR ] %s\n", entry.name);
} else {
printk("[FILE] %s (size = %d)\n",
entry.name, entry.size);
}
}
fs_closedir(&dp);
return 0;
}
static void dir_tests(void)
{
ZFILE fp[2];
int res;
/* Remove sub dir if already exists */
res = remove_dir(TEST_SUB_DIR);
if (res) {
return;
}
/* Create a sub directory */
res = create_dir(TEST_SUB_DIR);
if (res) {
return;
}
/* Open or create files */
res = open_file(&fp[0], TEST_FILE);
if (res) {
return;
}
res = open_file(&fp[1], TEST_SUB_DIR "/" TEST_FILE);
if (res) {
return;
}
/* Write to files to check size info */
res = write_test(&fp[0], 0, "1");
if (res) {
return;
}
res = write_test(&fp[1], 0, "12");
if (res) {
return;
}
/* Close the files in the directories */
res = close_file(&fp[0], TEST_FILE);
if (res) {
return;
}
res = close_file(&fp[1], TEST_SUB_DIR "/" TEST_FILE);
if (res) {
return;
}
/* List the files in root and sub dir */
res = list_dir("/");
if (res) {
return;
}
res = list_dir(TEST_SUB_DIR);
if (res) {
return;
}
/* Remove sub dir */
res = remove_dir(TEST_SUB_DIR);
if (res) {
return;
}
}