Source code for the Trusted Boot Module.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
tbm-mcu/source/mufs/file.c

164 lines
2.7 KiB

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <flash.h>
#include <macros.h>
#include <mufs.h>
#include "dir.h"
#include "path.h"
#include "tree.h"
struct mufs_file {
struct mufs *fs;
struct mufs_tree *tree;
int mode;
uint32_t va;
};
int mufs_create(struct mufs *fs, const char *path)
{
return mufs_mkpath(fs, path, NULL, MUFS_FILE);
}
struct mufs_file *mufs_open(struct mufs *fs, const char *path, int mode)
{
struct mufs_stat stat;
struct mufs_file *file;
if (!(file = malloc(sizeof(*file))))
return NULL;
file->fs = fs;
if (resolve_path(fs, path, &file->tree, &stat) < 0) {
if (!(mode & MUFS_WRITE))
goto err_free_file;
if (mufs_create(fs, path) < 0)
goto err_free_file;
if (resolve_path(fs, path, &file->tree, &stat) < 0)
goto err_free_file;
}
if (stat.type != MUFS_FILE)
goto err_del_tree;
file->mode = mode;
file->va = 0;
return file;
err_del_tree:
mufs_del_tree(file->tree);
err_free_file:
free(file);
return NULL;
}
void mufs_close(struct mufs_file *file)
{
if (!file)
return;
mufs_del_tree(file->tree);
free(file);
}
long mufs_seek(struct mufs_file *file, long offset, int whence)
{
if (!file)
return -1;
switch (whence) {
case SEEK_SET: break;
case SEEK_CUR: offset += file->va; break;
case SEEK_END: offset += file->tree->file_size; break;
default: return -1;
}
if (offset > (long)file->tree->file_size || offset >= (long)UINT32_MAX)
return -1;
file->va = offset;
return offset;
}
size_t mufs_read(struct mufs_file *file, void *data, size_t len)
{
size_t ret;
if (!file || !data || !len)
return 0;
if (!(file->mode & MUFS_READ))
return 0;
if (file->va >= file->tree->file_size)
return 0;
if (!(ret = mufs_tree_read(file->tree, data, file->va, len)))
return 0;
ret = min(ret, file->tree->file_size - file->va);
file->va += ret;
return ret;
}
size_t mufs_write(struct mufs_file *file, const void *data, size_t len)
{
size_t ret;
if (!file || !data || !len)
return 0;
if (!(file->mode & MUFS_WRITE))
return 0;
if (file->mode & MUFS_APPEND)
file->va = file->tree->file_size;
if (!(ret = mufs_tree_write(file->tree, (void *)data, file->va, len)))
return 0;
file->va += ret;
if (file->tree->file_size <= file->va) {
file->tree->file_size = file->va;
if (mufs_sync_tree(file->tree) < 0)
return 0;
}
return ret;
}
int mufs_unlink(struct mufs *fs, const char *path)
{
struct mufs_stat stat;
struct mufs_tree *tree;
if (resolve_path(fs, path, &tree, &stat) < 0)
return -1;
if (stat.type != MUFS_FILE)
goto err_del_tree;
if (mufs_shrink_tree(tree, 0) < 0)
goto err_del_tree;
if (mufs_rmpath(fs, path) < 0)
goto err_del_tree;
mufs_del_tree(tree);
return 0;
err_del_tree:
mufs_del_tree(tree);
return -1;
}