/* * Copyright (c) 2016, ETH Zurich. * All rights reserved. * * This file is distributed under the terms in the attached LICENSE file. * If you do not find this file, copies can be found by writing to: * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. */ #include #include #include #define FAIL_FN() \ do { \ debug_printf("***** %s:%s() called. Something is probably wrong! Maybe " \ "you forgot to call fs_register_dirops().\n", __FILE__,__FUNCTION__); \ return LIB_ERR_NOT_IMPLEMENTED; \ } while (0) static errval_t fs_mkdir_fail(const char *path){ FAIL_FN(); } static errval_t fs_rmdir_fail(const char *path){ FAIL_FN(); } static errval_t fs_rm_fail(const char *path){ FAIL_FN(); } static errval_t fs_opendir_fail(const char *path, fs_dirhandle_t *h){ FAIL_FN(); } static errval_t fs_readdir_fail(fs_dirhandle_t h, char **name) { FAIL_FN(); } static errval_t fs_closedir_fail(fs_dirhandle_t h) { FAIL_FN(); } static errval_t fs_fstat_fail(fs_dirhandle_t h, struct fs_fileinfo *b) { FAIL_FN(); } static struct { fs_mkdir_fn_t mkdir; fs_rmdir_fn_t rmdir; fs_rm_fn_t rm; fs_opendir_fn_t opendir; fs_readdir_fn_t readdir; fs_closedir_fn_t closedir; fs_fstat_fn_t fstat; } dir_ops = { .mkdir = fs_mkdir_fail, .rm = fs_rm_fail, .rmdir = fs_rmdir_fail, .opendir = fs_opendir_fail, .readdir = fs_readdir_fail, .closedir = fs_closedir_fail, .fstat = fs_fstat_fail }; /** * @brief sets the operation handlers for the directory functions * * @param ops struct containing function pointers */ void fs_register_dirops(fs_mkdir_fn_t mkdir_fn, fs_rmdir_fn_t rmdir_fn, fs_rm_fn_t rm_fn, fs_opendir_fn_t opendir_fn, fs_readdir_fn_t readdir_fn, fs_closedir_fn_t closedir_fn, fs_fstat_fn_t fstat_fn) { dir_ops.mkdir = (mkdir_fn ? mkdir_fn : fs_mkdir_fail); dir_ops.rmdir = (rmdir_fn ? rmdir_fn : fs_rmdir_fail); dir_ops.opendir = (opendir_fn ? opendir_fn : fs_opendir_fail); dir_ops.readdir = (readdir_fn ? readdir_fn : fs_readdir_fail); dir_ops.closedir = (closedir_fn ? closedir_fn : fs_closedir_fail); dir_ops.fstat = (fstat_fn ? fstat_fn : fs_fstat_fail); dir_ops.rm = (rm_fn ? rm_fn : fs_rm_fail); } /** * @brief opens a directory on the * * @param path the path to be created * @param ret_handle returned handle to the opendir state * * @returns SYS_ERR_OK on successful creation * FS_ERR_EXISTS if there is already a directory or file * FS_ERR_NOTFOUND if there is no such path to the parent */ errval_t opendir(const char *path, fs_dirhandle_t *ret_handle) { return dir_ops.opendir(path, ret_handle); } /** * @brief opens a directory on the * * @param handle the handle to close * * @returns SYS_ERR_OK on successful closing of the directory * FS_ERR_INVALID_FH if the filehandle was invalid */ errval_t closedir(fs_dirhandle_t handle) { return dir_ops.closedir(handle); } /** * @brief reads the next directory entry * * @param handle the handle to the directory * @param name returned (malloced) name oft he file * * @returns SYS_ERR_OK on successful reading the next entry * FS_ERR_INVALID_FH if the directory handle was invalid * FS_ERR_NOTFOUND there is no next file in the directory */ errval_t readdir(fs_dirhandle_t handle, char **name) { return dir_ops.readdir(handle, name); } /** * @brief creates a new directory on the file system * * @param path the path to be created * * @returns SYS_ERR_OK on successful creation * FS_ERR_EXISTS if there is already a directory or file * FS_ERR_NOTFOUND if there is no such path to the parent */ errval_t mkdir(const char *path) { return dir_ops.mkdir(path); } /** * @brief removes a directory from the file system * * @param path the path to be removed * * @returns SYS_ERR_OK on successful removal * FS_ERR_NOTEMPTY if the directory is not emtpy * FS_ERR_NOTDIR if the path is not a directory * FS_ERR_NOTFOUND if there is no such path */ errval_t rmdir(const char *path) { return dir_ops.rmdir(path); } /** * @brief removes a file from the file system * * @param path the path to be removed * * @returns SYS_ERR_OK on successful removal * FS_ERR_NOTDIR if the path is not a directory * FS_ERR_NOTFOUND if there is no such path */ errval_t rm(const char *path) { return dir_ops.rm(path); } /** * @brief Obtains file status information * * @param handle file handle * @param buf returned data of the filehandle information * * @returns SYS_ERR_OK on successful removal * FS_ERR_INVALID_FH if the directory is not emtpy */ errval_t fstat(fs_dirhandle_t handle, struct fs_fileinfo *buf) { return dir_ops.fstat(handle, buf); } /** * @brief Obtains file status information * * @param handle file handle * @param buf returned data of the filehandle information * * @returns SYS_ERR_OK on successful removal * FS_ERR_NOTFOUND if there is no such path */ errval_t stat(const char *path, struct fs_fileinfo *buf) { FILE *f = fopen(path, "r"); if (f == NULL) { return FS_ERR_NOTFOUND; } errval_t err = fstat(f, buf); fclose(f); return err; }