blob: 2c8ce2683c5d8034988a345d82e05568afe41bba [file] [log] [blame]
/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <errno.h>
#include <zephyr/init.h>
#include <zephyr/fs/fs.h>
#include <zephyr/fs/fs_sys.h>
#include <zephyr/sys/__assert.h>
#include "test_fs.h"
#define BUF_LEN 128
static char buffer[BUF_LEN];
static char *read_pos = buffer;
static char *cur = buffer;
static int file_length;
static struct fs_mount_t *mp[FS_TYPE_EXTERNAL_BASE];
static bool nospace;
static int opendir_result;
static
int temp_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
{
if (zfp == NULL || file_name == NULL) {
return -EINVAL;
}
if (zfp->filep) {
if (strcmp(zfp->filep, file_name) == 0) {
/* file has been opened */
return -EEXIST;
}
}
if (!(flags & FS_O_MASK)) {
return -EINVAL;
}
zfp->filep = (char *)file_name;
return 0;
}
static int temp_close(struct fs_file_t *zfp)
{
if (zfp == NULL) {
return -EINVAL;
}
if (zfp->filep) {
zfp->filep = NULL;
} else {
return -EIO;
}
return 0;
}
static int temp_unlink(struct fs_mount_t *mountp, const char *path)
{
if (mountp == NULL || path == NULL) {
return -EINVAL;
}
if (strcmp(mountp->mnt_point, path) == 0) {
return -EPERM;
}
return 0;
}
static int temp_rename(struct fs_mount_t *mountp, const char *from,
const char *to)
{
if (mountp == NULL || from == NULL || to == NULL) {
return -EINVAL;
}
if (strcmp(to, TEST_FILE_EX) == 0) {
return -EINVAL;
}
return 0;
}
static ssize_t temp_read(struct fs_file_t *zfp, void *ptr, size_t size)
{
unsigned int br;
if (zfp == NULL || ptr == NULL) {
return -EINVAL;
}
br = size;
if (read_pos - buffer + br > file_length) {
br = file_length - (read_pos - buffer);
}
memcpy(ptr, read_pos, br);
read_pos += br;
cur = read_pos;
return br;
}
static ssize_t temp_write(struct fs_file_t *zfp, const void *ptr, size_t size)
{
unsigned int bw;
if (zfp == NULL || ptr == NULL) {
return -EINVAL;
}
if (nospace) {
return -ENOSPC;
}
bw = size;
if (file_length + bw > BUF_LEN) {
bw = BUF_LEN - file_length;
nospace = true;
}
memcpy(buffer + file_length, ptr, bw);
file_length += bw;
cur = buffer + file_length;
return bw;
}
static int temp_seek(struct fs_file_t *zfp, off_t offset, int whence)
{
if (!zfp) {
return -EINVAL;
}
switch (whence) {
case FS_SEEK_SET:
cur = buffer + offset;
break;
case FS_SEEK_CUR:
cur += offset;
break;
case FS_SEEK_END:
cur = buffer + file_length + offset;
break;
default:
return -EINVAL;
}
if ((cur < buffer) || (cur > buffer + file_length)) {
return -EINVAL;
}
return 0;
}
static off_t temp_tell(struct fs_file_t *zfp)
{
if (!zfp) {
return -EINVAL;
}
if (nospace) {
return -ENOSPC;
}
return cur - buffer;
}
static int temp_truncate(struct fs_file_t *zfp, off_t length)
{
if (!zfp) {
return -EINVAL;
}
if (length > BUF_LEN) {
return -EINVAL;
}
file_length = length;
return 0;
}
static int temp_sync(struct fs_file_t *zfp)
{
if (!zfp) {
return -EINVAL;
}
if (nospace) {
return -ENOSPC;
}
return 0;
}
static int temp_mkdir(struct fs_mount_t *mountp, const char *path)
{
if (mountp == NULL || path == NULL) {
return -EINVAL;
}
if (strcmp(mountp->mnt_point, path) == 0) {
return -EPERM;
}
return 0;
}
void mock_opendir_result(int ret)
{
opendir_result = ret;
}
static int temp_opendir(struct fs_dir_t *zdp, const char *path)
{
if (zdp == NULL || path == NULL) {
return -EINVAL;
}
if (opendir_result) {
return opendir_result;
}
zdp->dirp = (char *)path;
return 0;
}
static int i;
static int temp_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry)
{
if (!zdp) {
return -EINVAL;
}
if (!entry) {
return -ENOENT;
}
switch (i) {
case 0:
strcpy(entry->name, ".");
entry->type = FS_DIR_ENTRY_DIR;
i++;
break;
case 1:
strcpy(entry->name, "testdir");
entry->type = FS_DIR_ENTRY_DIR;
i++;
break;
case 2:
strcpy(entry->name, "test.txt");
entry->type = FS_DIR_ENTRY_FILE;
i++;
break;
case 3:
strcpy(entry->name, "..");
entry->type = FS_DIR_ENTRY_DIR;
i++;
break;
default:
strcpy(entry->name, "\0");
i = 0;
break;
}
return 0;
}
static int temp_closedir(struct fs_dir_t *zdp)
{
if (!zdp) {
return -EINVAL;
}
if (!(zdp->dirp)) {
return -EIO;
}
zdp->dirp = NULL;
return 0;
}
static int temp_stat(struct fs_mount_t *mountp,
const char *path, struct fs_dirent *entry)
{
if (mountp == NULL || path == NULL || entry == NULL) {
return -EINVAL;
}
return 0;
}
static int temp_statvfs(struct fs_mount_t *mountp,
const char *path, struct fs_statvfs *stat)
{
if (mountp == NULL || path == NULL || stat == NULL) {
return -EINVAL;
}
memset(stat, 0, sizeof(struct fs_statvfs));
stat->f_bsize = 512;
return 0;
}
static int temp_mount(struct fs_mount_t *mountp)
{
if (mountp == NULL) {
return -EINVAL;
}
size_t len = strlen(mountp->mnt_point);
if (mountp->mnt_point[len - 1] != ':') {
return -EINVAL;
}
mp[mountp->type] = mountp;
return 0;
}
static int temp_unmount(struct fs_mount_t *mountp)
{
if (mountp == NULL) {
return -EINVAL;
}
if (mp[mountp->type] == NULL) {
return -EINVAL;
}
mp[mountp->type] = NULL;
return 0;
}
/* File system interface */
struct fs_file_system_t temp_fs = {
.open = temp_open,
.close = temp_close,
.read = temp_read,
.write = temp_write,
.lseek = temp_seek,
.tell = temp_tell,
.truncate = temp_truncate,
.sync = temp_sync,
.opendir = temp_opendir,
.readdir = temp_readdir,
.closedir = temp_closedir,
.mount = temp_mount,
.unmount = temp_unmount,
.unlink = temp_unlink,
.rename = temp_rename,
.mkdir = temp_mkdir,
.stat = temp_stat,
.statvfs = temp_statvfs,
};