lib: posix: Add Posix Style File System API support
Add IEEE 1003.1 Posix Style file system API support. These API's will internally use corresponding Zephyr File System API's. Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
This commit is contained in:
parent
0b76b12837
commit
eb0aaca64d
9 changed files with 550 additions and 19 deletions
|
@ -45,6 +45,8 @@
|
|||
#define mqueue_desc zap_mqueue_desc
|
||||
#define mqd_t zap_mqd_t
|
||||
#define mq_attr zap_mq_attr
|
||||
#define dirent zap_dirent
|
||||
#define DIR zap_DIR
|
||||
|
||||
/* Condition variables */
|
||||
|
||||
|
@ -163,6 +165,20 @@
|
|||
#define mq_timedreceive(...) zap_mq_timedreceive(__VA_ARGS__)
|
||||
#define mq_timedsend(...) zap_mq_timedsend(__VA_ARGS__)
|
||||
|
||||
/* File system */
|
||||
#define open zap_open
|
||||
#define close zap_close
|
||||
#define write zap_write
|
||||
#define read zap_read
|
||||
#define lseek zap_lseek
|
||||
#define opendir zap_opendir
|
||||
#define closedir zap_closedir
|
||||
#define readdir zap_readdir
|
||||
#define rename zap_rename
|
||||
#define unlink zap_unlink
|
||||
#define stat zap_stat
|
||||
#define mkdir zap_mkdir
|
||||
|
||||
#endif /* CONFIG_PTHREAD_IPC */
|
||||
|
||||
#endif /* CONFIG_ARCH_POSIX */
|
||||
|
|
18
include/fs.h
18
include/fs.h
|
@ -7,7 +7,25 @@
|
|||
#ifndef _FS_H_
|
||||
#define _FS_H_
|
||||
|
||||
#ifdef CONFIG_ARCH_POSIX
|
||||
#ifndef __ssize_t_defined
|
||||
typedef __SIZE_TYPE__ ssize_t;
|
||||
#define __ssize_t_defined
|
||||
#endif
|
||||
|
||||
#ifndef __off_t_defined
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
typedef long int off_t;
|
||||
#else
|
||||
typedef long long int off_t;
|
||||
#endif
|
||||
#define __off_t_defined
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <misc/dlist.h>
|
||||
#include <fs/fs_interface.h>
|
||||
|
||||
|
|
57
include/posix/sys/stat.h
Normal file
57
include/posix/sys/stat.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __POSIX_STAT_H__
|
||||
#define __POSIX_STAT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_IPC
|
||||
#include <kernel.h>
|
||||
|
||||
#ifdef CONFIG_POSIX_FS
|
||||
#define S_IRWXU 00700
|
||||
#define S_IRUSR 00400
|
||||
#define S_IWUSR 00200
|
||||
#define S_IXUSR 00100
|
||||
|
||||
#define S_IRWXG 00070
|
||||
#define S_IRGRP 00040
|
||||
#define S_IWGRP 00020
|
||||
#define S_IXGRP 00010
|
||||
|
||||
#define S_IRWXO 00007
|
||||
#define S_IROTH 00004
|
||||
#define S_IWOTH 00002
|
||||
#define S_IXOTH 00001
|
||||
|
||||
/* File open modes */
|
||||
#define O_ACCMODE 0003
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#define O_RDWR 02
|
||||
|
||||
#define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
#define SEEK_CUR 1 /* Seek from current position. */
|
||||
#define SEEK_END 2 /* Seek from end of file. */
|
||||
|
||||
struct stat {
|
||||
unsigned long st_size;
|
||||
unsigned long st_blksize;
|
||||
unsigned long st_blocks;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_POSIX_FS */
|
||||
|
||||
#endif /* CONFIG_PTHREAD_IPC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __POSIX_STAT_H__ */
|
|
@ -11,7 +11,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARCH_POSIX
|
||||
#include_next <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_IPC
|
||||
#include <kernel.h>
|
||||
|
|
|
@ -11,11 +11,46 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
|
||||
#ifdef CONFIG_POSIX_FS
|
||||
#include <fs.h>
|
||||
|
||||
#undef PATH_MAX
|
||||
#define PATH_MAX 256
|
||||
|
||||
typedef struct fs_dir_t DIR;
|
||||
typedef unsigned int mode_t;
|
||||
|
||||
struct dirent {
|
||||
unsigned int d_ino;
|
||||
char d_name[PATH_MAX + 1];
|
||||
};
|
||||
|
||||
/* File related operations */
|
||||
extern int open(const char *name, int flags);
|
||||
extern int close(int file);
|
||||
extern ssize_t write(int file, char *buffer, unsigned int count);
|
||||
extern ssize_t read(int file, char *buffer, unsigned int count);
|
||||
extern int lseek(int file, int offset, int whence);
|
||||
|
||||
/* Directory related operations */
|
||||
extern DIR *opendir(const char *dirname);
|
||||
extern int closedir(DIR *dirp);
|
||||
extern struct dirent *readdir(DIR *dirp);
|
||||
|
||||
/* File System related operations */
|
||||
extern int rename(const char *old, const char *newp);
|
||||
extern int unlink(const char *path);
|
||||
extern int stat(const char *path, struct stat *buf);
|
||||
extern int mkdir(const char *path, mode_t mode);
|
||||
#endif
|
||||
|
||||
unsigned sleep(unsigned int seconds);
|
||||
int usleep(useconds_t useconds);
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __POSIX_UNISTD_H__ */
|
||||
|
|
|
@ -75,6 +75,7 @@ void __stdin_hook_install(unsigned char (*hook)(void))
|
|||
_stdin_hook = hook;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_POSIX_FS
|
||||
int _read(int fd, char *buf, int nbytes)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -104,6 +105,28 @@ int _write(int fd, char *buf, int nbytes)
|
|||
}
|
||||
FUNC_ALIAS(_write, write, int);
|
||||
|
||||
int _open(const char *name, int mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FUNC_ALIAS(_open, open, int);
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FUNC_ALIAS(_close, close, int);
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
FUNC_ALIAS(_lseek, lseek, int);
|
||||
#else
|
||||
extern ssize_t write(int file, char *buffer, unsigned int count);
|
||||
#define _write write
|
||||
#endif
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
return 1;
|
||||
|
@ -137,24 +160,6 @@ void _exit(int status)
|
|||
}
|
||||
}
|
||||
|
||||
int _open(const char *name, int mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FUNC_ALIAS(_open, open, int);
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
FUNC_ALIAS(_close, close, int);
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
FUNC_ALIAS(_lseek, lseek, int);
|
||||
|
||||
void *_sbrk(int count)
|
||||
{
|
||||
void *ptr = heap_base + heap_sz;
|
||||
|
|
|
@ -16,6 +16,7 @@ zephyr_library_sources(timer.c)
|
|||
zephyr_library_sources(pthread_rwlock.c)
|
||||
zephyr_library_sources(semaphore.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_POSIX_MQUEUE mqueue.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_POSIX_FS fs.c)
|
||||
|
||||
zephyr_library_link_libraries(PTHREAD)
|
||||
target_link_libraries(PTHREAD INTERFACE zephyr_interface)
|
||||
|
|
|
@ -70,4 +70,23 @@ config MQUEUE_NAMELEN_MAX
|
|||
Mention length of message queue name in number of characters.
|
||||
|
||||
endif
|
||||
|
||||
if FILE_SYSTEM
|
||||
config POSIX_FS
|
||||
bool
|
||||
prompt "Enable POSIX file system API support"
|
||||
default n
|
||||
help
|
||||
This enabled POSIX style file system related APIs.
|
||||
|
||||
if POSIX_FS
|
||||
config POSIX_MAX_OPEN_FILES
|
||||
int
|
||||
prompt "Maximum number of open file descriptors"
|
||||
default 16
|
||||
help
|
||||
Mention maximum number of open file descriptors.
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
378
lib/posix/fs.c
Normal file
378
lib/posix/fs.c
Normal file
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <posix/pthread.h>
|
||||
#include <posix/unistd.h>
|
||||
|
||||
|
||||
union file_desc {
|
||||
struct fs_file_t file;
|
||||
struct fs_dir_t dir;
|
||||
};
|
||||
|
||||
struct posix_fs_desc {
|
||||
union file_desc desc;
|
||||
bool is_dir;
|
||||
bool used;
|
||||
};
|
||||
|
||||
static struct posix_fs_desc desc_array[CONFIG_POSIX_MAX_OPEN_FILES];
|
||||
|
||||
static struct fs_dirent fdirent;
|
||||
static struct dirent pdirent;
|
||||
|
||||
static int posix_fs_alloc_fd(union file_desc **ptr, bool is_dir)
|
||||
{
|
||||
int fd;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
for (fd = 0; fd < CONFIG_POSIX_MAX_OPEN_FILES; fd++) {
|
||||
if (desc_array[fd].used == false) {
|
||||
*ptr = &desc_array[fd].desc;
|
||||
desc_array[fd].used = true;
|
||||
desc_array[fd].is_dir = is_dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
irq_unlock(key);
|
||||
|
||||
if (fd >= CONFIG_POSIX_MAX_OPEN_FILES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int posix_fs_get_ptr(int fd, union file_desc **ptr, bool is_dir)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int key;
|
||||
|
||||
if (fd < 0 || fd >= CONFIG_POSIX_MAX_OPEN_FILES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = irq_lock();
|
||||
|
||||
if ((desc_array[fd].used == true) &&
|
||||
(desc_array[fd].is_dir == is_dir)) {
|
||||
*ptr = &desc_array[fd].desc;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
irq_unlock(key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline void posix_fs_free_ptr(struct posix_fs_desc *ptr)
|
||||
{
|
||||
struct posix_fs_desc *desc = ptr;
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
desc->used = false;
|
||||
desc->is_dir = false;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
static inline void posix_fs_free_fd(int fd)
|
||||
{
|
||||
posix_fs_free_ptr(&desc_array[fd]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a file.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int open(const char *name, int flags)
|
||||
{
|
||||
int rc, fd;
|
||||
struct fs_file_t *ptr = NULL;
|
||||
|
||||
ARG_UNUSED(flags);
|
||||
|
||||
fd = posix_fs_alloc_fd((union file_desc **)&ptr, false);
|
||||
if ((fd < 0) || (ptr == NULL)) {
|
||||
errno = ENFILE;
|
||||
return -1;
|
||||
}
|
||||
memset(ptr, 0, sizeof(struct fs_file_t));
|
||||
|
||||
rc = fs_open(ptr, name);
|
||||
if (rc < 0) {
|
||||
posix_fs_free_fd(fd);
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close a file descriptor.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int close(int fd)
|
||||
{
|
||||
int rc;
|
||||
struct fs_file_t *ptr = NULL;
|
||||
|
||||
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_close(ptr);
|
||||
|
||||
/* Free file ptr memory */
|
||||
posix_fs_free_fd(fd);
|
||||
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write to a file.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
ssize_t write(int fd, char *buffer, unsigned int count)
|
||||
{
|
||||
ssize_t rc;
|
||||
struct fs_file_t *ptr = NULL;
|
||||
|
||||
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_write(ptr, buffer, count);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read from a file.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
ssize_t read(int fd, char *buffer, unsigned int count)
|
||||
{
|
||||
ssize_t rc;
|
||||
struct fs_file_t *ptr = NULL;
|
||||
|
||||
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_read(ptr, buffer, count);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move read/write file offset.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int lseek(int fd, int offset, int whence)
|
||||
{
|
||||
int rc;
|
||||
struct fs_file_t *ptr = NULL;
|
||||
|
||||
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_seek(ptr, offset, whence);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a directory stream.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
DIR *opendir(const char *dirname)
|
||||
{
|
||||
int rc, fd;
|
||||
struct fs_dir_t *ptr = NULL;
|
||||
|
||||
fd = posix_fs_alloc_fd((union file_desc **)&ptr, true);
|
||||
if ((fd < 0) || (ptr == NULL)) {
|
||||
errno = EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
memset(ptr, 0, sizeof(struct fs_dir_t));
|
||||
|
||||
rc = fs_opendir(ptr, dirname);
|
||||
if (rc < 0) {
|
||||
posix_fs_free_fd(fd);
|
||||
errno = -rc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close a directory stream.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int closedir(DIR *dirp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (dirp == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_closedir(dirp);
|
||||
|
||||
/* Free file ptr memory */
|
||||
posix_fs_free_ptr((struct posix_fs_desc *)dirp);
|
||||
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a directory.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
struct dirent *readdir(DIR *dirp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (dirp == NULL) {
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = fs_readdir(dirp, &fdirent);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = strlen(fdirent.name);
|
||||
memcpy(pdirent.d_name, fdirent.name,
|
||||
rc <= PATH_MAX ? rc : PATH_MAX);
|
||||
return &pdirent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rename a file.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int rename(const char *old, const char *new)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = fs_rename(old, new);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a directory entry.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int unlink(const char *path)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = fs_unlink(path);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get file status.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int stat(const char *path, struct stat *buf)
|
||||
{
|
||||
int rc;
|
||||
struct fs_statvfs stat;
|
||||
|
||||
if (buf == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fs_statvfs(path, &stat);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf->st_size = stat.f_bsize * stat.f_blocks;
|
||||
buf->st_blksize = stat.f_bsize;
|
||||
buf->st_blocks = stat.f_blocks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Make a directory.
|
||||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
int mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ARG_UNUSED(mode);
|
||||
|
||||
rc = fs_mkdir(path);
|
||||
if (rc < 0) {
|
||||
errno = -rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue