[dfs] add poll/select
1. Add poll/select APIs; 2. Add wait queue implementation; 3. Remove DFS_STATUS_* code and use errno; 4. Add pipe API; 5. Use a standalone fops in DFS;
This commit is contained in:
parent
5c7b16d00b
commit
0f5a68a55e
@ -59,12 +59,13 @@ if RT_USING_DFS
|
|||||||
|
|
||||||
config RT_DFS_ELM_MAX_LFN
|
config RT_DFS_ELM_MAX_LFN
|
||||||
int "Maximal size of file name length"
|
int "Maximal size of file name length"
|
||||||
default 256
|
range 12 255
|
||||||
|
default 255
|
||||||
|
|
||||||
config RT_DFS_ELM_DRIVES
|
config RT_DFS_ELM_DRIVES
|
||||||
int "Number of volumes (logical drives) to be used."
|
int "Number of volumes (logical drives) to be used."
|
||||||
default 2
|
default 2
|
||||||
|
|
||||||
config RT_DFS_ELM_MAX_SECTOR_SIZE
|
config RT_DFS_ELM_MAX_SECTOR_SIZE
|
||||||
int "Maximum sector size to be handled."
|
int "Maximum sector size to be handled."
|
||||||
default 512
|
default 512
|
||||||
@ -86,12 +87,14 @@ if RT_USING_DFS
|
|||||||
|
|
||||||
config RT_USING_DFS_NET
|
config RT_USING_DFS_NET
|
||||||
bool "Enable BSD socket operated by file system API"
|
bool "Enable BSD socket operated by file system API"
|
||||||
|
depends on RT_USING_LWIP
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
|
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
|
||||||
|
|
||||||
config RT_USING_DFS_NFS
|
config RT_USING_DFS_NFS
|
||||||
bool "Using NFS v3 client file system"
|
bool "Using NFS v3 client file system"
|
||||||
|
depends on RT_USING_LWIP
|
||||||
default n
|
default n
|
||||||
|
|
||||||
if RT_USING_DFS_NFS
|
if RT_USING_DFS_NFS
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
from building import *
|
from building import *
|
||||||
|
|
||||||
# The set of source files associated with this SConscript file.
|
# The set of source files associated with this SConscript file.
|
||||||
src = Glob('src/*.c')
|
src = Split('''
|
||||||
|
src/dfs.c
|
||||||
|
src/dfs_file.c
|
||||||
|
src/dfs_fs.c
|
||||||
|
src/dfs_posix.c
|
||||||
|
''')
|
||||||
cwd = GetCurrentDir()
|
cwd = GetCurrentDir()
|
||||||
CPPPATH = [cwd + "/include"]
|
CPPPATH = [cwd + "/include"]
|
||||||
|
|
||||||
|
if GetDepend('RT_USING_DFS_NET'):
|
||||||
|
src += ['src/poll.c', 'src/select.c']
|
||||||
|
|
||||||
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
|
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
if GetDepend('RT_USING_DFS'):
|
if GetDepend('RT_USING_DFS'):
|
||||||
# search in the file system implementation
|
# search in the file system implementation
|
||||||
list = os.listdir(cwd)
|
list = os.listdir(cwd)
|
||||||
|
|
||||||
for item in list:
|
for item in list:
|
||||||
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
|
||||||
group = group + SConscript(os.path.join(item, 'SConscript'))
|
group = group + SConscript(os.path.join(item, 'SConscript'))
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* File : console.c
|
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2004-2011, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2015.03.27 Bernard Add author information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
struct console_device
|
|
||||||
{
|
|
||||||
struct rt_device parent;
|
|
||||||
|
|
||||||
rt_device_t device; /* the actual device */
|
|
||||||
};
|
|
||||||
struct console_device _console;
|
|
||||||
|
|
||||||
/* common device interface */
|
|
||||||
static rt_err_t console_init(rt_device_t dev)
|
|
||||||
{
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t console_open(rt_device_t dev, rt_uint16_t oflag)
|
|
||||||
{
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t console_close(rt_device_t dev)
|
|
||||||
{
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_size_t console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
|
||||||
{
|
|
||||||
struct console_device* device;
|
|
||||||
|
|
||||||
device = (struct console_device*)dev;
|
|
||||||
RT_ASSERT(device != RT_NULL);
|
|
||||||
|
|
||||||
return rt_device_read(device->device, pos, buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_size_t console_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
|
||||||
{
|
|
||||||
struct console_device* device;
|
|
||||||
|
|
||||||
device = (struct console_device*)dev;
|
|
||||||
RT_ASSERT(device != RT_NULL);
|
|
||||||
|
|
||||||
return rt_device_write(device->device, pos, buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t console_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
|
||||||
{
|
|
||||||
return rt_device_control(_console.device, cmd, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_console_init(const char* device_name)
|
|
||||||
{
|
|
||||||
rt_device_t device;
|
|
||||||
/* register to device framework */
|
|
||||||
|
|
||||||
device = rt_device_find("console");
|
|
||||||
if (device) return; /* not register a same name device */
|
|
||||||
|
|
||||||
device = rt_device_find(device_name);
|
|
||||||
if (device != RT_NULL)
|
|
||||||
{
|
|
||||||
struct console_device* console;
|
|
||||||
/* get console device */
|
|
||||||
console = &_console;
|
|
||||||
rt_memset(console, 0, sizeof(_console));
|
|
||||||
|
|
||||||
/* device initialization */
|
|
||||||
console->parent.type = RT_Device_Class_Char;
|
|
||||||
/* set device interface */
|
|
||||||
console->parent.init = console_init;
|
|
||||||
console->parent.open = console_open;
|
|
||||||
console->parent.close = console_close;
|
|
||||||
console->parent.read = console_read;
|
|
||||||
console->parent.write = console_write;
|
|
||||||
console->parent.control = console_control;
|
|
||||||
console->parent.user_data = RT_NULL;
|
|
||||||
|
|
||||||
console->device = device;
|
|
||||||
|
|
||||||
rt_device_register(&console->parent, "console", RT_DEVICE_FLAG_RDWR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,8 +22,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
|
||||||
#include "devfs.h"
|
#include "devfs.h"
|
||||||
|
|
||||||
@ -36,7 +39,7 @@ struct device_dirent
|
|||||||
|
|
||||||
int dfs_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
int dfs_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
{
|
{
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
int dfs_device_fs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
||||||
@ -53,12 +56,12 @@ int dfs_device_fs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
|||||||
/* close device handler */
|
/* close device handler */
|
||||||
result = rt_device_control(dev_id, cmd, args);
|
result = rt_device_control(dev_id, cmd, args);
|
||||||
if (result == RT_EOK)
|
if (result == RT_EOK)
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_read(struct dfs_fd *file, void *buf, rt_size_t count)
|
int dfs_device_fs_read(struct dfs_fd *file, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
rt_device_t dev_id;
|
rt_device_t dev_id;
|
||||||
@ -76,7 +79,7 @@ int dfs_device_fs_read(struct dfs_fd *file, void *buf, rt_size_t count)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_write(struct dfs_fd *file, const void *buf, rt_size_t count)
|
int dfs_device_fs_write(struct dfs_fd *file, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
rt_device_t dev_id;
|
rt_device_t dev_id;
|
||||||
@ -110,7 +113,7 @@ int dfs_device_fs_close(struct dfs_fd *file)
|
|||||||
|
|
||||||
/* release dirent */
|
/* release dirent */
|
||||||
rt_free(root_dirent);
|
rt_free(root_dirent);
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get device handler */
|
/* get device handler */
|
||||||
@ -123,10 +126,10 @@ int dfs_device_fs_close(struct dfs_fd *file)
|
|||||||
{
|
{
|
||||||
file->data = RT_NULL;
|
file->data = RT_NULL;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_open(struct dfs_fd *file)
|
int dfs_device_fs_open(struct dfs_fd *file)
|
||||||
@ -134,12 +137,12 @@ int dfs_device_fs_open(struct dfs_fd *file)
|
|||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
rt_device_t device;
|
rt_device_t device;
|
||||||
|
|
||||||
if (file->flags & DFS_O_CREAT)
|
if (file->flags & O_CREAT)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* open root directory */
|
/* open root directory */
|
||||||
if ((file->path[0] == '/') && (file->path[1] == '\0') &&
|
if ((file->path[0] == '/') && (file->path[1] == '\0') &&
|
||||||
(file->flags & DFS_O_DIRECTORY))
|
(file->flags & O_DIRECTORY))
|
||||||
{
|
{
|
||||||
struct rt_object *object;
|
struct rt_object *object;
|
||||||
struct rt_list_node *node;
|
struct rt_list_node *node;
|
||||||
@ -180,23 +183,42 @@ int dfs_device_fs_open(struct dfs_fd *file)
|
|||||||
/* set data */
|
/* set data */
|
||||||
file->data = root_dirent;
|
file->data = root_dirent;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = rt_device_find(&file->path[1]);
|
device = rt_device_find(&file->path[1]);
|
||||||
if (device == RT_NULL)
|
if (device == RT_NULL)
|
||||||
return -DFS_STATUS_ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* to open device */
|
if (device->fops)
|
||||||
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
|
||||||
if (result == RT_EOK || result == -RT_ENOSYS)
|
|
||||||
{
|
{
|
||||||
file->data = device;
|
/* use device fops */
|
||||||
return DFS_STATUS_OK;
|
file->fops = device->fops;
|
||||||
|
file->data = (void*)device;
|
||||||
|
|
||||||
|
/* use fops */
|
||||||
|
if (file->fops->open)
|
||||||
|
{
|
||||||
|
result = file->fops->open(file);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
||||||
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
|
{
|
||||||
|
file->data = device;
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file->data = RT_NULL;
|
||||||
/* open device failed. */
|
/* open device failed. */
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
@ -206,15 +228,15 @@ int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat
|
|||||||
{
|
{
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
|
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
st->st_mode &= ~DFS_S_IFREG;
|
st->st_mode &= ~S_IFREG;
|
||||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
|
||||||
st->st_size = 0;
|
st->st_size = 0;
|
||||||
st->st_mtime = 0;
|
st->st_mtime = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -225,27 +247,29 @@ int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat
|
|||||||
{
|
{
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
|
|
||||||
st->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
st->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
if (dev_id->type == RT_Device_Class_Char)
|
if (dev_id->type == RT_Device_Class_Char)
|
||||||
st->st_mode |= DFS_S_IFCHR;
|
st->st_mode |= S_IFCHR;
|
||||||
else if (dev_id->type == RT_Device_Class_Block)
|
else if (dev_id->type == RT_Device_Class_Block)
|
||||||
st->st_mode |= DFS_S_IFBLK;
|
st->st_mode |= S_IFBLK;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Pipe)
|
||||||
|
st->st_mode |= S_IFIFO;
|
||||||
else
|
else
|
||||||
st->st_mode |= DFS_S_IFREG;
|
st->st_mode |= S_IFREG;
|
||||||
|
|
||||||
st->st_size = 0;
|
st->st_size = 0;
|
||||||
st->st_mtime = 0;
|
st->st_mtime = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_device_fs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
|
int dfs_device_fs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
|
||||||
{
|
{
|
||||||
rt_uint32_t index;
|
rt_uint32_t index;
|
||||||
rt_object_t object;
|
rt_object_t object;
|
||||||
@ -258,7 +282,7 @@ int dfs_device_fs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t
|
|||||||
/* make integer count */
|
/* make integer count */
|
||||||
count = (count / sizeof(struct dirent));
|
count = (count / sizeof(struct dirent));
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
||||||
index ++)
|
index ++)
|
||||||
@ -266,7 +290,7 @@ int dfs_device_fs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t
|
|||||||
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
||||||
|
|
||||||
d = dirp + index;
|
d = dirp + index;
|
||||||
d->d_type = DFS_DT_REG;
|
d->d_type = DT_REG;
|
||||||
d->d_namlen = RT_NAME_MAX;
|
d->d_namlen = RT_NAME_MAX;
|
||||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
||||||
@ -277,23 +301,37 @@ int dfs_device_fs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t
|
|||||||
return index * sizeof(struct dirent);
|
return index * sizeof(struct dirent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation _device_fs =
|
static int dfs_device_fs_poll(struct dfs_fd *fd, struct rt_pollreq *req)
|
||||||
{
|
{
|
||||||
"devfs",
|
int mask = 0;
|
||||||
DFS_FS_FLAG_DEFAULT,
|
|
||||||
dfs_device_fs_mount,
|
|
||||||
RT_NULL,
|
|
||||||
RT_NULL,
|
|
||||||
RT_NULL,
|
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_file_ops _device_fops =
|
||||||
|
{
|
||||||
dfs_device_fs_open,
|
dfs_device_fs_open,
|
||||||
dfs_device_fs_close,
|
dfs_device_fs_close,
|
||||||
dfs_device_fs_ioctl,
|
dfs_device_fs_ioctl,
|
||||||
dfs_device_fs_read,
|
dfs_device_fs_read,
|
||||||
dfs_device_fs_write,
|
dfs_device_fs_write,
|
||||||
RT_NULL,
|
RT_NULL, /* flush */
|
||||||
RT_NULL,
|
RT_NULL, /* lseek */
|
||||||
dfs_device_fs_getdents,
|
dfs_device_fs_getdents,
|
||||||
|
dfs_device_fs_poll,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _device_fs =
|
||||||
|
{
|
||||||
|
"devfs",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_device_fops,
|
||||||
|
|
||||||
|
dfs_device_fs_mount,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
|
||||||
RT_NULL,
|
RT_NULL,
|
||||||
dfs_device_fs_stat,
|
dfs_device_fs_stat,
|
||||||
RT_NULL,
|
RT_NULL,
|
||||||
@ -306,5 +344,3 @@ int devfs_init(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_FS_EXPORT(devfs_init);
|
|
||||||
|
|
||||||
|
@ -27,6 +27,5 @@
|
|||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
int devfs_init(void);
|
int devfs_init(void);
|
||||||
void rt_console_init(const char* device_name);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,13 +41,13 @@
|
|||||||
#define HAVE_DIR_STRUCTURE
|
#define HAVE_DIR_STRUCTURE
|
||||||
|
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
#include <dfs_def.h>
|
#include <dfs_file.h>
|
||||||
|
|
||||||
static rt_device_t disk[_VOLUMES] = {0};
|
static rt_device_t disk[_VOLUMES] = {0};
|
||||||
|
|
||||||
static int elm_result_to_dfs(FRESULT result)
|
static int elm_result_to_dfs(FRESULT result)
|
||||||
{
|
{
|
||||||
int status = DFS_STATUS_OK;
|
int status = RT_EOK;
|
||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
@ -57,31 +57,31 @@ static int elm_result_to_dfs(FRESULT result)
|
|||||||
case FR_NO_FILE:
|
case FR_NO_FILE:
|
||||||
case FR_NO_PATH:
|
case FR_NO_PATH:
|
||||||
case FR_NO_FILESYSTEM:
|
case FR_NO_FILESYSTEM:
|
||||||
status = -DFS_STATUS_ENOENT;
|
status = -ENOENT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FR_INVALID_NAME:
|
case FR_INVALID_NAME:
|
||||||
status = -DFS_STATUS_EINVAL;
|
status = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FR_EXIST:
|
case FR_EXIST:
|
||||||
case FR_INVALID_OBJECT:
|
case FR_INVALID_OBJECT:
|
||||||
status = -DFS_STATUS_EEXIST;
|
status = -EEXIST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FR_DISK_ERR:
|
case FR_DISK_ERR:
|
||||||
case FR_NOT_READY:
|
case FR_NOT_READY:
|
||||||
case FR_INT_ERR:
|
case FR_INT_ERR:
|
||||||
status = -DFS_STATUS_EIO;
|
status = -EIO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FR_WRITE_PROTECTED:
|
case FR_WRITE_PROTECTED:
|
||||||
case FR_DENIED:
|
case FR_DENIED:
|
||||||
status = -DFS_STATUS_EROFS;
|
status = -EROFS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FR_MKFS_ABORTED:
|
case FR_MKFS_ABORTED:
|
||||||
status = -DFS_STATUS_EINVAL;
|
status = -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -120,7 +120,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
|
|||||||
/* get an empty position */
|
/* get an empty position */
|
||||||
index = get_disk(RT_NULL);
|
index = get_disk(RT_NULL);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
logic_nbr[0] = '0' + index;
|
logic_nbr[0] = '0' + index;
|
||||||
|
|
||||||
/* save device */
|
/* save device */
|
||||||
@ -131,7 +131,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
|
|||||||
if (geometry.bytes_per_sector > _MAX_SS)
|
if (geometry.bytes_per_sector > _MAX_SS)
|
||||||
{
|
{
|
||||||
rt_kprintf("The sector size of device is greater than the sector size of FAT.\n");
|
rt_kprintf("The sector size of device is greater than the sector size of FAT.\n");
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
|
|||||||
if (fat == RT_NULL)
|
if (fat == RT_NULL)
|
||||||
{
|
{
|
||||||
disk[index] = RT_NULL;
|
disk[index] = RT_NULL;
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mount fatfs, always 0 logic driver */
|
/* mount fatfs, always 0 logic driver */
|
||||||
@ -156,7 +156,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
|
|||||||
f_mount(RT_NULL, (const TCHAR*)logic_nbr, 1);
|
f_mount(RT_NULL, (const TCHAR*)logic_nbr, 1);
|
||||||
disk[index] = RT_NULL;
|
disk[index] = RT_NULL;
|
||||||
rt_free(fat);
|
rt_free(fat);
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the root directory to test whether the fatfs is valid */
|
/* open the root directory to test whether the fatfs is valid */
|
||||||
@ -190,7 +190,7 @@ int dfs_elm_unmount(struct dfs_filesystem *fs)
|
|||||||
/* find the device index and then umount it */
|
/* find the device index and then umount it */
|
||||||
index = get_disk(fs->dev_id);
|
index = get_disk(fs->dev_id);
|
||||||
if (index == -1) /* not found */
|
if (index == -1) /* not found */
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
result = f_mount(RT_NULL, "", (BYTE)index);
|
result = f_mount(RT_NULL, "", (BYTE)index);
|
||||||
if (result != FR_OK)
|
if (result != FR_OK)
|
||||||
@ -200,7 +200,7 @@ int dfs_elm_unmount(struct dfs_filesystem *fs)
|
|||||||
disk[index] = RT_NULL;
|
disk[index] = RT_NULL;
|
||||||
rt_free(fat);
|
rt_free(fat);
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_mkfs(rt_device_t dev_id)
|
int dfs_elm_mkfs(rt_device_t dev_id)
|
||||||
@ -212,15 +212,17 @@ int dfs_elm_mkfs(rt_device_t dev_id)
|
|||||||
int flag;
|
int flag;
|
||||||
FRESULT result;
|
FRESULT result;
|
||||||
int index;
|
int index;
|
||||||
char logic_nbr[2] = {'0',':'};
|
|
||||||
|
|
||||||
work = rt_malloc(_MAX_SS);
|
work = rt_malloc(_MAX_SS);
|
||||||
if(RT_NULL == work) {
|
if(RT_NULL == work) {
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_id == RT_NULL)
|
if (dev_id == RT_NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
{
|
||||||
|
rt_free(work); /* release memory */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the device is already mounted, then just do mkfs to the drv,
|
/* if the device is already mounted, then just do mkfs to the drv,
|
||||||
* while if it is not mounted yet, then find an empty drive to do mkfs
|
* while if it is not mounted yet, then find an empty drive to do mkfs
|
||||||
@ -236,13 +238,17 @@ int dfs_elm_mkfs(rt_device_t dev_id)
|
|||||||
{
|
{
|
||||||
/* no space to store an temp driver */
|
/* no space to store an temp driver */
|
||||||
rt_kprintf("sorry, there is no space to do mkfs! \n");
|
rt_kprintf("sorry, there is no space to do mkfs! \n");
|
||||||
return -DFS_STATUS_ENOSPC;
|
rt_free(work); /* release memory */
|
||||||
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fat = rt_malloc(sizeof(FATFS));
|
fat = rt_malloc(sizeof(FATFS));
|
||||||
if (fat == RT_NULL)
|
if (fat == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
{
|
||||||
|
rt_free(work); /* release memory */
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
flag = FSM_STATUS_USE_TEMP_DRIVER;
|
flag = FSM_STATUS_USE_TEMP_DRIVER;
|
||||||
|
|
||||||
@ -256,26 +262,23 @@ int dfs_elm_mkfs(rt_device_t dev_id)
|
|||||||
* on the disk, you will get a failure. so we need f_mount here,
|
* on the disk, you will get a failure. so we need f_mount here,
|
||||||
* just fill the FatFS[index] in elm fatfs to make mkfs work.
|
* just fill the FatFS[index] in elm fatfs to make mkfs work.
|
||||||
*/
|
*/
|
||||||
logic_nbr[0] = '0' + index;
|
f_mount(fat, "", (BYTE)index);
|
||||||
f_mount(fat, logic_nbr, (BYTE)index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
logic_nbr[0] = '0' + index;
|
|
||||||
|
|
||||||
/* [IN] Logical drive number */
|
/* [IN] Logical drive number */
|
||||||
/* [IN] Format options */
|
/* [IN] Format options */
|
||||||
/* [IN] Size of the allocation unit */
|
/* [IN] Size of the allocation unit */
|
||||||
/* [-] Working buffer */
|
/* [-] Working buffer */
|
||||||
/* [IN] Size of working buffer */
|
/* [IN] Size of working buffer */
|
||||||
result = f_mkfs(logic_nbr, FM_ANY, 0, work, _MAX_SS);
|
result = f_mkfs("", FM_ANY, 0, work, _MAX_SS);
|
||||||
rt_free(work);
|
rt_free(work); work = RT_NULL;
|
||||||
|
|
||||||
/* check flag status, we need clear the temp driver stored in disk[] */
|
/* check flag status, we need clear the temp driver stored in disk[] */
|
||||||
if (flag == FSM_STATUS_USE_TEMP_DRIVER)
|
if (flag == FSM_STATUS_USE_TEMP_DRIVER)
|
||||||
{
|
{
|
||||||
rt_free(fat);
|
rt_free(fat);
|
||||||
f_mount(RT_NULL, logic_nbr,(BYTE)index);
|
f_mount(RT_NULL, "",(BYTE)index);
|
||||||
disk[index] = RT_NULL;
|
disk[index] = RT_NULL;
|
||||||
/* close device */
|
/* close device */
|
||||||
rt_device_close(dev_id);
|
rt_device_close(dev_id);
|
||||||
@ -287,7 +290,7 @@ int dfs_elm_mkfs(rt_device_t dev_id)
|
|||||||
return elm_result_to_dfs(result);
|
return elm_result_to_dfs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
@ -331,26 +334,30 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
|
|
||||||
#if (_VOLUMES > 1)
|
#if (_VOLUMES > 1)
|
||||||
int vol;
|
int vol;
|
||||||
|
struct dfs_filesystem *fs = (struct dfs_filesystem *)file->data;
|
||||||
extern int elm_get_vol(FATFS * fat);
|
extern int elm_get_vol(FATFS * fat);
|
||||||
|
|
||||||
|
if (fs == NULL)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
/* add path for ELM FatFS driver support */
|
/* add path for ELM FatFS driver support */
|
||||||
vol = elm_get_vol((FATFS *)file->fs->data);
|
vol = elm_get_vol((FATFS *)fs->data);
|
||||||
if (vol < 0)
|
if (vol < 0)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
drivers_fn = rt_malloc(256);
|
drivers_fn = rt_malloc(256);
|
||||||
if (drivers_fn == RT_NULL)
|
if (drivers_fn == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
|
rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
|
||||||
#else
|
#else
|
||||||
drivers_fn = file->path;
|
drivers_fn = file->path;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (file->flags & DFS_O_DIRECTORY)
|
if (file->flags & O_DIRECTORY)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
if (file->flags & DFS_O_CREAT)
|
if (file->flags & O_CREAT)
|
||||||
{
|
{
|
||||||
result = f_mkdir(drivers_fn);
|
result = f_mkdir(drivers_fn);
|
||||||
if (result != FR_OK)
|
if (result != FR_OK)
|
||||||
@ -369,7 +376,7 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
#if _VOLUMES > 1
|
#if _VOLUMES > 1
|
||||||
rt_free(drivers_fn);
|
rt_free(drivers_fn);
|
||||||
#endif
|
#endif
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = f_opendir(dir, drivers_fn);
|
result = f_opendir(dir, drivers_fn);
|
||||||
@ -383,24 +390,24 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
file->data = dir;
|
file->data = dir;
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mode = FA_READ;
|
mode = FA_READ;
|
||||||
|
|
||||||
if (file->flags & DFS_O_WRONLY)
|
if (file->flags & O_WRONLY)
|
||||||
mode |= FA_WRITE;
|
mode |= FA_WRITE;
|
||||||
if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR)
|
if ((file->flags & O_ACCMODE) & O_RDWR)
|
||||||
mode |= FA_WRITE;
|
mode |= FA_WRITE;
|
||||||
/* Opens the file, if it is existing. If not, a new file is created. */
|
/* Opens the file, if it is existing. If not, a new file is created. */
|
||||||
if (file->flags & DFS_O_CREAT)
|
if (file->flags & O_CREAT)
|
||||||
mode |= FA_OPEN_ALWAYS;
|
mode |= FA_OPEN_ALWAYS;
|
||||||
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
||||||
if (file->flags & DFS_O_TRUNC)
|
if (file->flags & O_TRUNC)
|
||||||
mode |= FA_CREATE_ALWAYS;
|
mode |= FA_CREATE_ALWAYS;
|
||||||
/* Creates a new file. The function fails if the file is already existing. */
|
/* Creates a new file. The function fails if the file is already existing. */
|
||||||
if (file->flags & DFS_O_EXCL)
|
if (file->flags & O_EXCL)
|
||||||
mode |= FA_CREATE_NEW;
|
mode |= FA_CREATE_NEW;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* allocate a fd */
|
||||||
@ -410,7 +417,7 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
#if _VOLUMES > 1
|
#if _VOLUMES > 1
|
||||||
rt_free(drivers_fn);
|
rt_free(drivers_fn);
|
||||||
#endif
|
#endif
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = f_open(fd, drivers_fn, mode);
|
result = f_open(fd, drivers_fn, mode);
|
||||||
@ -423,7 +430,7 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
file->size = f_size(fd);
|
file->size = f_size(fd);
|
||||||
file->data = fd;
|
file->data = fd;
|
||||||
|
|
||||||
if (file->flags & DFS_O_APPEND)
|
if (file->flags & O_APPEND)
|
||||||
{
|
{
|
||||||
/* seek to the end of file */
|
/* seek to the end of file */
|
||||||
f_lseek(fd, f_size(fd));
|
f_lseek(fd, f_size(fd));
|
||||||
@ -438,7 +445,7 @@ int dfs_elm_open(struct dfs_fd *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_close(struct dfs_fd *file)
|
int dfs_elm_close(struct dfs_fd *file)
|
||||||
@ -475,10 +482,10 @@ int dfs_elm_close(struct dfs_fd *file)
|
|||||||
|
|
||||||
int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)
|
int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len)
|
int dfs_elm_read(struct dfs_fd *file, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
FIL *fd;
|
FIL *fd;
|
||||||
FRESULT result;
|
FRESULT result;
|
||||||
@ -486,7 +493,7 @@ int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len)
|
|||||||
|
|
||||||
if (file->type == FT_DIRECTORY)
|
if (file->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EISDIR;
|
return -EISDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = (FIL *)(file->data);
|
fd = (FIL *)(file->data);
|
||||||
@ -501,7 +508,7 @@ int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len)
|
|||||||
return elm_result_to_dfs(result);
|
return elm_result_to_dfs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_write(struct dfs_fd *file, const void *buf, rt_size_t len)
|
int dfs_elm_write(struct dfs_fd *file, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
FIL *fd;
|
FIL *fd;
|
||||||
FRESULT result;
|
FRESULT result;
|
||||||
@ -509,7 +516,7 @@ int dfs_elm_write(struct dfs_fd *file, const void *buf, rt_size_t len)
|
|||||||
|
|
||||||
if (file->type == FT_DIRECTORY)
|
if (file->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EISDIR;
|
return -EISDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = (FIL *)(file->data);
|
fd = (FIL *)(file->data);
|
||||||
@ -576,7 +583,7 @@ int dfs_elm_lseek(struct dfs_fd *file, rt_off_t offset)
|
|||||||
return elm_result_to_dfs(result);
|
return elm_result_to_dfs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
|
int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
@ -590,7 +597,7 @@ int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count
|
|||||||
/* make integer count */
|
/* make integer count */
|
||||||
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
while (1)
|
while (1)
|
||||||
@ -609,11 +616,11 @@ int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count
|
|||||||
fn = fno.fname;
|
fn = fno.fname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
d->d_type = DFS_DT_UNKNOWN;
|
d->d_type = DT_UNKNOWN;
|
||||||
if (fno.fattrib & AM_DIR)
|
if (fno.fattrib & AM_DIR)
|
||||||
d->d_type = DFS_DT_DIR;
|
d->d_type = DT_DIR;
|
||||||
else
|
else
|
||||||
d->d_type = DFS_DT_REG;
|
d->d_type = DT_REG;
|
||||||
|
|
||||||
d->d_namlen = (rt_uint8_t)rt_strlen(fn);
|
d->d_namlen = (rt_uint8_t)rt_strlen(fn);
|
||||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
@ -644,10 +651,10 @@ int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
|
|||||||
/* add path for ELM FatFS driver support */
|
/* add path for ELM FatFS driver support */
|
||||||
vol = elm_get_vol((FATFS *)fs->data);
|
vol = elm_get_vol((FATFS *)fs->data);
|
||||||
if (vol < 0)
|
if (vol < 0)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
drivers_fn = rt_malloc(256);
|
drivers_fn = rt_malloc(256);
|
||||||
if (drivers_fn == RT_NULL)
|
if (drivers_fn == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
||||||
#else
|
#else
|
||||||
@ -675,11 +682,11 @@ int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *n
|
|||||||
/* add path for ELM FatFS driver support */
|
/* add path for ELM FatFS driver support */
|
||||||
vol = elm_get_vol((FATFS *)fs->data);
|
vol = elm_get_vol((FATFS *)fs->data);
|
||||||
if (vol < 0)
|
if (vol < 0)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
drivers_oldfn = rt_malloc(256);
|
drivers_oldfn = rt_malloc(256);
|
||||||
if (drivers_oldfn == RT_NULL)
|
if (drivers_oldfn == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
drivers_newfn = newpath;
|
drivers_newfn = newpath;
|
||||||
|
|
||||||
rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
|
rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
|
||||||
@ -710,10 +717,10 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
|||||||
/* add path for ELM FatFS driver support */
|
/* add path for ELM FatFS driver support */
|
||||||
vol = elm_get_vol((FATFS *)fs->data);
|
vol = elm_get_vol((FATFS *)fs->data);
|
||||||
if (vol < 0)
|
if (vol < 0)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
drivers_fn = rt_malloc(256);
|
drivers_fn = rt_malloc(256);
|
||||||
if (drivers_fn == RT_NULL)
|
if (drivers_fn == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
|
||||||
#else
|
#else
|
||||||
@ -730,15 +737,15 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
|||||||
/* convert to dfs stat structure */
|
/* convert to dfs stat structure */
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
|
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
if (file_info.fattrib & AM_DIR)
|
if (file_info.fattrib & AM_DIR)
|
||||||
{
|
{
|
||||||
st->st_mode &= ~DFS_S_IFREG;
|
st->st_mode &= ~S_IFREG;
|
||||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
}
|
}
|
||||||
if (file_info.fattrib & AM_RDO)
|
if (file_info.fattrib & AM_RDO)
|
||||||
st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
|
st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
|
|
||||||
st->st_size = file_info.fsize;
|
st->st_size = file_info.fsize;
|
||||||
|
|
||||||
@ -777,15 +784,8 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
|||||||
return elm_result_to_dfs(result);
|
return elm_result_to_dfs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation dfs_elm =
|
static const struct dfs_file_ops dfs_elm_fops =
|
||||||
{
|
{
|
||||||
"elm",
|
|
||||||
DFS_FS_FLAG_DEFAULT,
|
|
||||||
dfs_elm_mount,
|
|
||||||
dfs_elm_unmount,
|
|
||||||
dfs_elm_mkfs,
|
|
||||||
dfs_elm_statfs,
|
|
||||||
|
|
||||||
dfs_elm_open,
|
dfs_elm_open,
|
||||||
dfs_elm_close,
|
dfs_elm_close,
|
||||||
dfs_elm_ioctl,
|
dfs_elm_ioctl,
|
||||||
@ -794,6 +794,20 @@ static const struct dfs_filesystem_operation dfs_elm =
|
|||||||
dfs_elm_flush,
|
dfs_elm_flush,
|
||||||
dfs_elm_lseek,
|
dfs_elm_lseek,
|
||||||
dfs_elm_getdents,
|
dfs_elm_getdents,
|
||||||
|
RT_NULL, /* poll interface */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops dfs_elm =
|
||||||
|
{
|
||||||
|
"elm",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&dfs_elm_fops,
|
||||||
|
|
||||||
|
dfs_elm_mount,
|
||||||
|
dfs_elm_unmount,
|
||||||
|
dfs_elm_mkfs,
|
||||||
|
dfs_elm_statfs,
|
||||||
|
|
||||||
dfs_elm_unlink,
|
dfs_elm_unlink,
|
||||||
dfs_elm_stat,
|
dfs_elm_stat,
|
||||||
dfs_elm_rename,
|
dfs_elm_rename,
|
||||||
|
@ -26,27 +26,35 @@
|
|||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include "dfs_net.h"
|
#include "dfs_net.h"
|
||||||
|
|
||||||
int dfs_net_getsocket(int fd)
|
int dfs_net_getsocket(int fd)
|
||||||
{
|
{
|
||||||
|
int sock;
|
||||||
struct dfs_fd *_dfs_fd;
|
struct dfs_fd *_dfs_fd;
|
||||||
|
|
||||||
_dfs_fd = fd_get(fd);
|
_dfs_fd = fd_get(fd);
|
||||||
if (_dfs_fd == RT_NULL) return -1;
|
if (_dfs_fd == NULL) return -1;
|
||||||
|
|
||||||
if (_dfs_fd->type != FT_SOCKET) return -1;
|
if (_dfs_fd->type != FT_SOCKET) sock = -1;
|
||||||
|
else sock = (int)_dfs_fd->data;
|
||||||
return (int)_dfs_fd->data;
|
|
||||||
|
fd_put(_dfs_fd); /* put this dfs fd */
|
||||||
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
|
static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_net_read(struct dfs_fd* file, void *buf, rt_size_t count)
|
static int dfs_net_read(struct dfs_fd* file, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
@ -56,7 +64,7 @@ int dfs_net_read(struct dfs_fd* file, void *buf, rt_size_t count)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_net_write(struct dfs_fd *file, const void *buf, rt_size_t count)
|
static int dfs_net_write(struct dfs_fd *file, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
@ -66,7 +74,7 @@ int dfs_net_write(struct dfs_fd *file, const void *buf, rt_size_t count)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_net_close(struct dfs_fd* file)
|
static int dfs_net_close(struct dfs_fd* file)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
int result;
|
int result;
|
||||||
@ -74,55 +82,60 @@ int dfs_net_close(struct dfs_fd* file)
|
|||||||
sock = (int)file->data;
|
sock = (int)file->data;
|
||||||
result = lwip_close(sock);
|
result = lwip_close(sock);
|
||||||
|
|
||||||
if (result == 0) return DFS_STATUS_OK;
|
if (result == 0) return RT_EOK;
|
||||||
|
|
||||||
return -result;
|
return -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation _net_fs_ops =
|
static int dfs_net_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
||||||
{
|
{
|
||||||
"net",
|
int sfd;
|
||||||
DFS_FS_FLAG_DEFAULT,
|
int mask = 0;
|
||||||
RT_NULL, /* mount */
|
struct lwip_sock *sock;
|
||||||
RT_NULL, /* unmont */
|
|
||||||
RT_NULL, /* mkfs */
|
|
||||||
RT_NULL, /* statfs */
|
|
||||||
|
|
||||||
RT_NULL, /* open */
|
sfd = (int)file->data;
|
||||||
|
|
||||||
|
sock = lwip_tryget_socket(sfd);
|
||||||
|
if (sock != NULL)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
rt_poll_add(&sock->wait_head, req);
|
||||||
|
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
if (sock->rcvevent)
|
||||||
|
{
|
||||||
|
mask |= POLLIN;
|
||||||
|
}
|
||||||
|
if (sock->sendevent)
|
||||||
|
{
|
||||||
|
mask |= POLLOUT;
|
||||||
|
}
|
||||||
|
if (sock->errevent)
|
||||||
|
{
|
||||||
|
mask |= POLLERR;
|
||||||
|
}
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct dfs_file_ops _net_fops =
|
||||||
|
{
|
||||||
|
NULL, /* open */
|
||||||
dfs_net_close,
|
dfs_net_close,
|
||||||
dfs_net_ioctl,
|
dfs_net_ioctl,
|
||||||
dfs_net_read,
|
dfs_net_read,
|
||||||
dfs_net_write,
|
dfs_net_write,
|
||||||
RT_NULL,
|
NULL,
|
||||||
RT_NULL, /* lseek */
|
NULL, /* lseek */
|
||||||
RT_NULL, /* getdents */
|
NULL, /* getdents */
|
||||||
RT_NULL, /* unlink */
|
dfs_net_poll,
|
||||||
RT_NULL, /* stat */
|
|
||||||
RT_NULL, /* rename */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dfs_filesystem _net_fs =
|
const struct dfs_file_ops *dfs_net_get_fops(void)
|
||||||
{
|
{
|
||||||
0, /* dev_id */
|
return &_net_fops;
|
||||||
RT_NULL, /* path */
|
|
||||||
&_net_fs_ops,
|
|
||||||
RT_NULL /* data */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dfs_filesystem* dfs_net_get_fs(void)
|
|
||||||
{
|
|
||||||
return &_net_fs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
NOTE: Beause we don't need to mount lwIP file system, the filesystem_ops is not
|
|
||||||
registered to the system.
|
|
||||||
|
|
||||||
int dfs_net_system_init(void)
|
|
||||||
{
|
|
||||||
dfs_register(&_net_fs_ops);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
INIT_FS_EXPORT(dfs_net_system_init);
|
|
||||||
*/
|
|
||||||
|
@ -32,13 +32,12 @@ extern "C" {
|
|||||||
|
|
||||||
#include <lwip/sockets.h>
|
#include <lwip/sockets.h>
|
||||||
|
|
||||||
struct dfs_filesystem* dfs_net_get_fs(void);
|
const struct dfs_file_ops* dfs_net_get_fops(void);
|
||||||
int dfs_net_getsocket(int fd);
|
int dfs_net_getsocket(int fd);
|
||||||
|
|
||||||
int dfs_net_system_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* File : lwip_select.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2015-05-05 Bernard First version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWIP
|
|
||||||
|
|
||||||
#include "dfs_net.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|
||||||
struct timeval *timeout)
|
|
||||||
{
|
|
||||||
int index, result;
|
|
||||||
int sock, maxfd;
|
|
||||||
|
|
||||||
fd_set sock_readset;
|
|
||||||
fd_set sock_writeset;
|
|
||||||
fd_set sock_exceptset;
|
|
||||||
|
|
||||||
FD_ZERO(&sock_readset);
|
|
||||||
FD_ZERO(&sock_writeset);
|
|
||||||
FD_ZERO(&sock_exceptset);
|
|
||||||
|
|
||||||
maxfd = 0;
|
|
||||||
for (index = 0; index < maxfdp1; index ++)
|
|
||||||
{
|
|
||||||
/* convert fd to sock */
|
|
||||||
sock = dfs_net_getsocket(index);
|
|
||||||
if (sock == -1) continue;
|
|
||||||
|
|
||||||
if (sock > maxfd) maxfd = sock;
|
|
||||||
|
|
||||||
/* if FD is set, set the socket set */
|
|
||||||
if (readset && FD_ISSET(index, readset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, &sock_readset);
|
|
||||||
}
|
|
||||||
if (writeset && FD_ISSET(index, writeset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, &sock_writeset);
|
|
||||||
}
|
|
||||||
if (exceptset && FD_ISSET(index, exceptset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, &sock_exceptset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no socket found, return bad file descriptor */
|
|
||||||
if (maxfd == 0) return -EBADF;
|
|
||||||
maxfd += 1;
|
|
||||||
|
|
||||||
result = lwip_select(maxfd, &sock_readset, &sock_writeset, &sock_exceptset, timeout);
|
|
||||||
|
|
||||||
if (readset) FD_ZERO(readset);
|
|
||||||
if (writeset) FD_ZERO(writeset);
|
|
||||||
if (exceptset) FD_ZERO(exceptset);
|
|
||||||
|
|
||||||
if (result != -1)
|
|
||||||
{
|
|
||||||
for (index = 0; index < maxfd; index ++)
|
|
||||||
{
|
|
||||||
/* check each socket */
|
|
||||||
if ((FD_ISSET(index, &sock_readset)) ||
|
|
||||||
(FD_ISSET(index, &sock_writeset)) ||
|
|
||||||
(FD_ISSET(index, &sock_exceptset)))
|
|
||||||
{
|
|
||||||
int fd_index;
|
|
||||||
|
|
||||||
/* Because we can not get the corresponding fd, we have to search it one by one */
|
|
||||||
for (fd_index = 0; fd_index < maxfdp1; fd_index ++)
|
|
||||||
{
|
|
||||||
sock = dfs_lwip_getsocket(fd_index);
|
|
||||||
if (sock == index) /* found it */
|
|
||||||
{
|
|
||||||
if (readset && FD_ISSET(index, &sock_readset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, readset);
|
|
||||||
}
|
|
||||||
if (writeset && FD_ISSET(index, &sock_writeset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, writeset);
|
|
||||||
}
|
|
||||||
if (exceptset && FD_ISSET(index, &sock_exceptset))
|
|
||||||
{
|
|
||||||
FD_SET(sock, exceptset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of search */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
RTM_EXPORT(select);
|
|
||||||
|
|
||||||
#endif
|
|
@ -23,13 +23,92 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_def.h>
|
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include "dfs_net.h"
|
#include "dfs_net.h"
|
||||||
|
|
||||||
|
static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
struct lwip_sock *sock;
|
||||||
|
uint32_t event = 0;
|
||||||
|
SYS_ARCH_DECL_PROTECT(lev);
|
||||||
|
|
||||||
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
|
/* Get socket */
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
|
s = conn->socket;
|
||||||
|
if (s < 0)
|
||||||
|
{
|
||||||
|
/* Data comes in right away after an accept, even though
|
||||||
|
* the server task might not have created a new socket yet.
|
||||||
|
* Just count down (or up) if that's the case and we
|
||||||
|
* will use the data later. Note that only receive events
|
||||||
|
* can happen before the new socket is set up. */
|
||||||
|
SYS_ARCH_PROTECT(lev);
|
||||||
|
if (conn->socket < 0)
|
||||||
|
{
|
||||||
|
if (evt == NETCONN_EVT_RCVPLUS)
|
||||||
|
{
|
||||||
|
conn->socket--;
|
||||||
|
}
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s = conn->socket;
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = lwip_tryget_socket(s);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_ARCH_PROTECT(lev);
|
||||||
|
/* Set event as required */
|
||||||
|
switch (evt)
|
||||||
|
{
|
||||||
|
case NETCONN_EVT_RCVPLUS:
|
||||||
|
sock->rcvevent++;
|
||||||
|
break;
|
||||||
|
case NETCONN_EVT_RCVMINUS:
|
||||||
|
sock->rcvevent--;
|
||||||
|
break;
|
||||||
|
case NETCONN_EVT_SENDPLUS:
|
||||||
|
sock->sendevent = 1;
|
||||||
|
break;
|
||||||
|
case NETCONN_EVT_SENDMINUS:
|
||||||
|
sock->sendevent = 0;
|
||||||
|
break;
|
||||||
|
case NETCONN_EVT_ERROR:
|
||||||
|
sock->errevent = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LWIP_ASSERT("unknown event", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->lastdata || sock->rcvevent > 0) event |= POLLIN;
|
||||||
|
if (sock->sendevent) event |= POLLOUT;
|
||||||
|
if (sock->errevent) event |= POLLERR;
|
||||||
|
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
rt_wqueue_wakeup(&sock->wait_head, (void*)event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
int new_client = -1;
|
int new_client = -1;
|
||||||
@ -41,15 +120,15 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
|||||||
/* this is a new socket, create it in file system fd */
|
/* this is a new socket, create it in file system fd */
|
||||||
int fd;
|
int fd;
|
||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
struct lwip_sock *lwsock;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* allocate a fd */
|
||||||
fd = fd_new();
|
fd = fd_new();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
lwip_close(sock);
|
lwip_close(sock);
|
||||||
|
|
||||||
rt_kprintf("no fd yet!\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
@ -58,9 +137,12 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
|||||||
d->type = FT_SOCKET;
|
d->type = FT_SOCKET;
|
||||||
d->path = RT_NULL;
|
d->path = RT_NULL;
|
||||||
|
|
||||||
d->fs = dfs_net_get_fs();
|
d->fops = dfs_net_get_fops();
|
||||||
|
/* initialize wait head */
|
||||||
|
lwsock = lwip_tryget_socket(new_client);
|
||||||
|
rt_list_init(&(lwsock->wait_head));
|
||||||
|
|
||||||
d->flags = DFS_O_RDWR; /* set flags as read and write */
|
d->flags = O_RDWR; /* set flags as read and write */
|
||||||
d->size = 0;
|
d->size = 0;
|
||||||
d->pos = 0;
|
d->pos = 0;
|
||||||
|
|
||||||
@ -93,7 +175,7 @@ int shutdown(int s, int how)
|
|||||||
d = fd_get(s);
|
d = fd_get(s);
|
||||||
if (d == RT_NULL)
|
if (d == RT_NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -200,12 +282,13 @@ int socket(int domain, int type, int protocol)
|
|||||||
int fd;
|
int fd;
|
||||||
int sock;
|
int sock;
|
||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
struct lwip_sock *lwsock;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* allocate a fd */
|
||||||
fd = fd_new();
|
fd = fd_new();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -213,20 +296,24 @@ int socket(int domain, int type, int protocol)
|
|||||||
|
|
||||||
/* create socket in lwip and then put it to the dfs_fd */
|
/* create socket in lwip and then put it to the dfs_fd */
|
||||||
sock = lwip_socket(domain, type, protocol);
|
sock = lwip_socket(domain, type, protocol);
|
||||||
if (sock > 0)
|
if (sock >= 0)
|
||||||
{
|
{
|
||||||
/* this is a socket fd */
|
/* this is a socket fd */
|
||||||
d->type = FT_SOCKET;
|
d->type = FT_SOCKET;
|
||||||
d->path = RT_NULL;
|
d->path = NULL;
|
||||||
|
|
||||||
d->fs = dfs_net_get_fs();
|
d->fops = dfs_net_get_fops();
|
||||||
|
|
||||||
d->flags = DFS_O_RDWR; /* set flags as read and write */
|
d->flags = O_RDWR; /* set flags as read and write */
|
||||||
d->size = 0;
|
d->size = 0;
|
||||||
d->pos = 0;
|
d->pos = 0;
|
||||||
|
|
||||||
/* set socket to the data of dfs_fd */
|
/* set socket to the data of dfs_fd */
|
||||||
d->data = (void *) sock;
|
d->data = (void *) sock;
|
||||||
|
|
||||||
|
lwsock = lwip_tryget_socket(sock);
|
||||||
|
rt_list_init(&(lwsock->wait_head));
|
||||||
|
lwsock->conn->callback = event_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release the ref-count of fd */
|
/* release the ref-count of fd */
|
||||||
@ -235,3 +322,20 @@ int socket(int domain, int type, int protocol)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(socket);
|
RTM_EXPORT(socket);
|
||||||
|
|
||||||
|
int closesocket(int s)
|
||||||
|
{
|
||||||
|
int sock = dfs_net_getsocket(s);
|
||||||
|
|
||||||
|
return lwip_close(sock);
|
||||||
|
}
|
||||||
|
RTM_EXPORT(closesocket);
|
||||||
|
|
||||||
|
int ioctlsocket(int s, long cmd, void *arg)
|
||||||
|
{
|
||||||
|
int sock = dfs_net_getsocket(s);
|
||||||
|
|
||||||
|
return lwip_ioctl(sock, cmd, arg);
|
||||||
|
}
|
||||||
|
RTM_EXPORT(ioctlsocket);
|
||||||
|
|
||||||
|
@ -25,22 +25,6 @@
|
|||||||
#ifndef SELECT_H__
|
#ifndef SELECT_H__
|
||||||
#define SELECT_H__
|
#define SELECT_H__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include <dfs_select.h>
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* select API */
|
|
||||||
#ifdef RT_USING_LWIP
|
|
||||||
/* we use lwIP's structure definitions. */
|
|
||||||
#include <lwip/sockets.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|
||||||
struct timeval *timeout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,7 +31,12 @@ extern "C" {
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <lwip/sockets.h>
|
#include <lwip/sockets.h>
|
||||||
|
#include <lwip/api.h>
|
||||||
|
#include <lwip/init.h>
|
||||||
|
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#if LWIP_VERSION < 0x2000000
|
||||||
typedef uint16_t sa_family_t;
|
typedef uint16_t sa_family_t;
|
||||||
typedef uint16_t in_port_t;
|
typedef uint16_t in_port_t;
|
||||||
|
|
||||||
@ -40,6 +45,44 @@ struct sockaddr_storage
|
|||||||
sa_family_t ss_family; /* Address family */
|
sa_family_t ss_family; /* Address family */
|
||||||
char ss_data[14]; /* 14-bytes of address data */
|
char ss_data[14]; /* 14-bytes of address data */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_VERSION < 0x2000000
|
||||||
|
#define SELWAIT_T int
|
||||||
|
#else
|
||||||
|
#ifndef SELWAIT_T
|
||||||
|
#define SELWAIT_T u8_t
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-define lwip socket
|
||||||
|
*
|
||||||
|
* NOTE: please make sure the definitions same in lwip::net_socket.c
|
||||||
|
*/
|
||||||
|
struct lwip_sock {
|
||||||
|
/** sockets currently are built on netconns, each socket has one netconn */
|
||||||
|
struct netconn *conn;
|
||||||
|
/** data that was left from the previous read */
|
||||||
|
void *lastdata;
|
||||||
|
/** offset in the data that was left from the previous read */
|
||||||
|
u16_t lastoffset;
|
||||||
|
/** number of times data was received, set by event_callback(),
|
||||||
|
tested by the receive and select functions */
|
||||||
|
s16_t rcvevent;
|
||||||
|
/** number of times data was ACKed (free send buffer), set by event_callback(),
|
||||||
|
tested by select */
|
||||||
|
u16_t sendevent;
|
||||||
|
/** error happened for this socket, set by event_callback(), tested by select */
|
||||||
|
u16_t errevent;
|
||||||
|
/** last error that occurred on this socket */
|
||||||
|
int err;
|
||||||
|
/** counter of how many threads are waiting for this socket using select */
|
||||||
|
SELWAIT_T select_waiting;
|
||||||
|
|
||||||
|
rt_wqueue_t wait_head;
|
||||||
|
};
|
||||||
|
struct lwip_sock *lwip_tryget_socket(int s);
|
||||||
|
|
||||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||||
int bind(int s, const struct sockaddr *name, socklen_t namelen);
|
int bind(int s, const struct sockaddr *name, socklen_t namelen);
|
||||||
@ -57,6 +100,8 @@ int send(int s, const void *dataptr, size_t size, int flags);
|
|||||||
int sendto(int s, const void *dataptr, size_t size, int flags,
|
int sendto(int s, const void *dataptr, size_t size, int flags,
|
||||||
const struct sockaddr *to, socklen_t tolen);
|
const struct sockaddr *to, socklen_t tolen);
|
||||||
int socket(int domain, int type, int protocol);
|
int socket(int domain, int type, int protocol);
|
||||||
|
int closesocket(int s);
|
||||||
|
int ioctlsocket(int s, long cmd, void *arg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -35,20 +35,20 @@ int dfs_ramfs_mount(struct dfs_filesystem *fs,
|
|||||||
{
|
{
|
||||||
struct dfs_ramfs* ramfs;
|
struct dfs_ramfs* ramfs;
|
||||||
|
|
||||||
if (data == RT_NULL)
|
if (data == NULL)
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs *)data;
|
ramfs = (struct dfs_ramfs *)data;
|
||||||
fs->data = ramfs;
|
fs->data = ramfs;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_unmount(struct dfs_filesystem *fs)
|
int dfs_ramfs_unmount(struct dfs_filesystem *fs)
|
||||||
{
|
{
|
||||||
fs->data = RT_NULL;
|
fs->data = NULL;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
int dfs_ramfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
||||||
@ -56,19 +56,19 @@ int dfs_ramfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
|
|||||||
struct dfs_ramfs *ramfs;
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs *)fs->data;
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
RT_ASSERT(ramfs != RT_NULL);
|
RT_ASSERT(ramfs != NULL);
|
||||||
RT_ASSERT(buf != RT_NULL);
|
RT_ASSERT(buf != NULL);
|
||||||
|
|
||||||
buf->f_bsize = 512;
|
buf->f_bsize = 512;
|
||||||
buf->f_blocks = ramfs->memheap.pool_size/512;
|
buf->f_blocks = ramfs->memheap.pool_size/512;
|
||||||
buf->f_bfree = ramfs->memheap.available_size/512;
|
buf->f_bfree = ramfs->memheap.available_size/512;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
int dfs_ramfs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
|
struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
|
||||||
@ -101,16 +101,16 @@ struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* not found */
|
/* not found */
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_read(struct dfs_fd *file, void *buf, rt_size_t count)
|
int dfs_ramfs_read(struct dfs_fd *file, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
rt_size_t length;
|
rt_size_t length;
|
||||||
struct ramfs_dirent *dirent;
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
dirent = (struct ramfs_dirent *)file->data;
|
dirent = (struct ramfs_dirent *)file->data;
|
||||||
RT_ASSERT(dirent != RT_NULL);
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
if (count < file->size - file->pos)
|
if (count < file->size - file->pos)
|
||||||
length = count;
|
length = count;
|
||||||
@ -126,23 +126,23 @@ int dfs_ramfs_read(struct dfs_fd *file, void *buf, rt_size_t count)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_write(struct dfs_fd *fd, const void *buf, rt_size_t count)
|
int dfs_ramfs_write(struct dfs_fd *fd, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct ramfs_dirent *dirent;
|
struct ramfs_dirent *dirent;
|
||||||
struct dfs_ramfs *ramfs;
|
struct dfs_ramfs *ramfs;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs*)fd->fs->data;
|
ramfs = (struct dfs_ramfs*)fd->fs->data;
|
||||||
RT_ASSERT(ramfs != RT_NULL);
|
RT_ASSERT(ramfs != NULL);
|
||||||
dirent = (struct ramfs_dirent*)fd->data;
|
dirent = (struct ramfs_dirent*)fd->data;
|
||||||
RT_ASSERT(dirent != RT_NULL);
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
if (count + fd->pos > fd->size)
|
if (count + fd->pos > fd->size)
|
||||||
{
|
{
|
||||||
rt_uint8_t *ptr;
|
rt_uint8_t *ptr;
|
||||||
ptr = rt_memheap_realloc(&(ramfs->memheap), dirent->data, fd->pos + count);
|
ptr = rt_memheap_realloc(&(ramfs->memheap), dirent->data, fd->pos + count);
|
||||||
if (ptr == RT_NULL)
|
if (ptr == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-RT_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -162,23 +162,23 @@ int dfs_ramfs_write(struct dfs_fd *fd, const void *buf, rt_size_t count)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_lseek(struct dfs_fd *file, rt_off_t offset)
|
int dfs_ramfs_lseek(struct dfs_fd *file, off_t offset)
|
||||||
{
|
{
|
||||||
if (offset <= (rt_off_t)file->size)
|
if (offset <= (off_t)file->size)
|
||||||
{
|
{
|
||||||
file->pos = offset;
|
file->pos = offset;
|
||||||
|
|
||||||
return file->pos;
|
return file->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_close(struct dfs_fd *file)
|
int dfs_ramfs_close(struct dfs_fd *file)
|
||||||
{
|
{
|
||||||
file->data = RT_NULL;
|
file->data = NULL;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_open(struct dfs_fd *file)
|
int dfs_ramfs_open(struct dfs_fd *file)
|
||||||
@ -188,24 +188,24 @@ int dfs_ramfs_open(struct dfs_fd *file)
|
|||||||
struct ramfs_dirent *dirent;
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs *)file->fs->data;
|
ramfs = (struct dfs_ramfs *)file->fs->data;
|
||||||
RT_ASSERT(ramfs != RT_NULL);
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
if (file->flags & DFS_O_DIRECTORY)
|
if (file->flags & O_DIRECTORY)
|
||||||
{
|
{
|
||||||
if (file->flags & DFS_O_CREAT)
|
if (file->flags & O_CREAT)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open directory */
|
/* open directory */
|
||||||
dirent = dfs_ramfs_lookup(ramfs, file->path, &size);
|
dirent = dfs_ramfs_lookup(ramfs, file->path, &size);
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
if (dirent == &(ramfs->root)) /* it's root directory */
|
if (dirent == &(ramfs->root)) /* it's root directory */
|
||||||
{
|
{
|
||||||
if (!(file->flags & DFS_O_DIRECTORY))
|
if (!(file->flags & O_DIRECTORY))
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,12 +214,12 @@ int dfs_ramfs_open(struct dfs_fd *file)
|
|||||||
dirent = dfs_ramfs_lookup(ramfs, file->path, &size);
|
dirent = dfs_ramfs_lookup(ramfs, file->path, &size);
|
||||||
if (dirent == &(ramfs->root)) /* it's root directory */
|
if (dirent == &(ramfs->root)) /* it's root directory */
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
{
|
{
|
||||||
if (file->flags & DFS_O_CREAT || file->flags & DFS_O_WRONLY)
|
if (file->flags & O_CREAT || file->flags & O_WRONLY)
|
||||||
{
|
{
|
||||||
char *name_ptr;
|
char *name_ptr;
|
||||||
|
|
||||||
@ -227,9 +227,9 @@ int dfs_ramfs_open(struct dfs_fd *file)
|
|||||||
dirent = (struct ramfs_dirent *)
|
dirent = (struct ramfs_dirent *)
|
||||||
rt_memheap_alloc(&(ramfs->memheap),
|
rt_memheap_alloc(&(ramfs->memheap),
|
||||||
sizeof(struct ramfs_dirent));
|
sizeof(struct ramfs_dirent));
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove '/' separator */
|
/* remove '/' separator */
|
||||||
@ -239,37 +239,37 @@ int dfs_ramfs_open(struct dfs_fd *file)
|
|||||||
strncpy(dirent->name, name_ptr, RAMFS_NAME_MAX);
|
strncpy(dirent->name, name_ptr, RAMFS_NAME_MAX);
|
||||||
|
|
||||||
rt_list_init(&(dirent->list));
|
rt_list_init(&(dirent->list));
|
||||||
dirent->data = RT_NULL;
|
dirent->data = NULL;
|
||||||
dirent->size = 0;
|
dirent->size = 0;
|
||||||
/* add to the root directory */
|
/* add to the root directory */
|
||||||
rt_list_insert_after(&(ramfs->root.list), &(dirent->list));
|
rt_list_insert_after(&(ramfs->root.list), &(dirent->list));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a new file.
|
/* Creates a new file.
|
||||||
* If the file is existing, it is truncated and overwritten.
|
* If the file is existing, it is truncated and overwritten.
|
||||||
*/
|
*/
|
||||||
if (file->flags & DFS_O_TRUNC)
|
if (file->flags & O_TRUNC)
|
||||||
{
|
{
|
||||||
dirent->size = 0;
|
dirent->size = 0;
|
||||||
if (dirent->data != RT_NULL)
|
if (dirent->data != NULL)
|
||||||
{
|
{
|
||||||
rt_memheap_free(dirent->data);
|
rt_memheap_free(dirent->data);
|
||||||
dirent->data = RT_NULL;
|
dirent->data = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file->data = dirent;
|
file->data = dirent;
|
||||||
file->size = dirent->size;
|
file->size = dirent->size;
|
||||||
if (file->flags & DFS_O_APPEND)
|
if (file->flags & O_APPEND)
|
||||||
file->pos = file->size;
|
file->pos = file->size;
|
||||||
else
|
else
|
||||||
file->pos = 0;
|
file->pos = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_stat(struct dfs_filesystem *fs,
|
int dfs_ramfs_stat(struct dfs_filesystem *fs,
|
||||||
@ -283,22 +283,22 @@ int dfs_ramfs_stat(struct dfs_filesystem *fs,
|
|||||||
ramfs = (struct dfs_ramfs *)fs->data;
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
||||||
|
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
st->st_size = dirent->size;
|
st->st_size = dirent->size;
|
||||||
st->st_mtime = 0;
|
st->st_mtime = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_getdents(struct dfs_fd *file,
|
int dfs_ramfs_getdents(struct dfs_fd *file,
|
||||||
struct dirent *dirp,
|
struct dirent *dirp,
|
||||||
rt_uint32_t count)
|
uint32_t count)
|
||||||
{
|
{
|
||||||
rt_size_t index, end;
|
rt_size_t index, end;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
@ -308,12 +308,12 @@ int dfs_ramfs_getdents(struct dfs_fd *file,
|
|||||||
ramfs = (struct dfs_ramfs *)file->fs->data;
|
ramfs = (struct dfs_ramfs *)file->fs->data;
|
||||||
dirent = (struct ramfs_dirent *)file->data;
|
dirent = (struct ramfs_dirent *)file->data;
|
||||||
if (dirent != &(ramfs->root))
|
if (dirent != &(ramfs->root))
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* make integer count */
|
/* make integer count */
|
||||||
count = (count / sizeof(struct dirent));
|
count = (count / sizeof(struct dirent));
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
end = file->pos + count;
|
end = file->pos + count;
|
||||||
index = 0;
|
index = 0;
|
||||||
@ -346,18 +346,18 @@ int dfs_ramfs_unlink(struct dfs_filesystem *fs, const char *path)
|
|||||||
struct ramfs_dirent *dirent;
|
struct ramfs_dirent *dirent;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs *)fs->data;
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
RT_ASSERT(ramfs != RT_NULL);
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
dirent = dfs_ramfs_lookup(ramfs, path, &size);
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
rt_list_remove(&(dirent->list));
|
rt_list_remove(&(dirent->list));
|
||||||
if (dirent->data != RT_NULL)
|
if (dirent->data != NULL)
|
||||||
rt_memheap_free(dirent->data);
|
rt_memheap_free(dirent->data);
|
||||||
rt_memheap_free(dirent);
|
rt_memheap_free(dirent);
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_ramfs_rename(struct dfs_filesystem *fs,
|
int dfs_ramfs_rename(struct dfs_filesystem *fs,
|
||||||
@ -369,38 +369,44 @@ int dfs_ramfs_rename(struct dfs_filesystem *fs,
|
|||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
|
|
||||||
ramfs = (struct dfs_ramfs *)fs->data;
|
ramfs = (struct dfs_ramfs *)fs->data;
|
||||||
RT_ASSERT(ramfs != RT_NULL);
|
RT_ASSERT(ramfs != NULL);
|
||||||
|
|
||||||
dirent = dfs_ramfs_lookup(ramfs, newpath, &size);
|
dirent = dfs_ramfs_lookup(ramfs, newpath, &size);
|
||||||
if (dirent != RT_NULL)
|
if (dirent != NULL)
|
||||||
return -DFS_STATUS_EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
dirent = dfs_ramfs_lookup(ramfs, oldpath, &size);
|
dirent = dfs_ramfs_lookup(ramfs, oldpath, &size);
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
strncpy(dirent->name, newpath, RAMFS_NAME_MAX);
|
strncpy(dirent->name, newpath, RAMFS_NAME_MAX);
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation _ramfs =
|
static const struct dfs_file_ops _ram_fops =
|
||||||
{
|
{
|
||||||
"ram",
|
|
||||||
DFS_FS_FLAG_DEFAULT,
|
|
||||||
dfs_ramfs_mount,
|
|
||||||
dfs_ramfs_unmount,
|
|
||||||
RT_NULL, /* mkfs */
|
|
||||||
dfs_ramfs_statfs,
|
|
||||||
|
|
||||||
dfs_ramfs_open,
|
dfs_ramfs_open,
|
||||||
dfs_ramfs_close,
|
dfs_ramfs_close,
|
||||||
dfs_ramfs_ioctl,
|
dfs_ramfs_ioctl,
|
||||||
dfs_ramfs_read,
|
dfs_ramfs_read,
|
||||||
dfs_ramfs_write,
|
dfs_ramfs_write,
|
||||||
RT_NULL, /* flush */
|
NULL, /* flush */
|
||||||
dfs_ramfs_lseek,
|
dfs_ramfs_lseek,
|
||||||
dfs_ramfs_getdents,
|
dfs_ramfs_getdents,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops _ramfs =
|
||||||
|
{
|
||||||
|
"ram",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_ram_fops,
|
||||||
|
|
||||||
|
dfs_ramfs_mount,
|
||||||
|
dfs_ramfs_unmount,
|
||||||
|
NULL, /* mkfs */
|
||||||
|
dfs_ramfs_statfs,
|
||||||
|
|
||||||
dfs_ramfs_unlink,
|
dfs_ramfs_unlink,
|
||||||
dfs_ramfs_stat,
|
dfs_ramfs_stat,
|
||||||
dfs_ramfs_rename,
|
dfs_ramfs_rename,
|
||||||
@ -430,7 +436,7 @@ struct dfs_ramfs* dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size)
|
|||||||
|
|
||||||
result = rt_memheap_init(&ramfs->memheap, "ramfs", data_ptr, size);
|
result = rt_memheap_init(&ramfs->memheap, "ramfs", data_ptr, size);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
/* detach this memheap object from the system */
|
/* detach this memheap object from the system */
|
||||||
rt_object_detach((rt_object_t)&(ramfs->memheap));
|
rt_object_detach((rt_object_t)&(ramfs->memheap));
|
||||||
|
|
||||||
|
@ -28,25 +28,25 @@
|
|||||||
|
|
||||||
int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
|
||||||
{
|
{
|
||||||
struct romfs_dirent *root_dirent;
|
struct romfs_dirent *root_dirent;
|
||||||
|
|
||||||
if (data == RT_NULL)
|
if (data == NULL)
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
|
|
||||||
root_dirent = (struct romfs_dirent *)data;
|
root_dirent = (struct romfs_dirent *)data;
|
||||||
fs->data = root_dirent;
|
fs->data = root_dirent;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_unmount(struct dfs_filesystem *fs)
|
int dfs_romfs_unmount(struct dfs_filesystem *fs)
|
||||||
{
|
{
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_inline int check_dirent(struct romfs_dirent *dirent)
|
rt_inline int check_dirent(struct romfs_dirent *dirent)
|
||||||
@ -59,269 +59,274 @@ rt_inline int check_dirent(struct romfs_dirent *dirent)
|
|||||||
|
|
||||||
struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
|
struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
|
||||||
{
|
{
|
||||||
rt_size_t index, found;
|
rt_size_t index, found;
|
||||||
const char *subpath, *subpath_end;
|
const char *subpath, *subpath_end;
|
||||||
struct romfs_dirent *dirent;
|
struct romfs_dirent *dirent;
|
||||||
rt_size_t dirent_size;
|
rt_size_t dirent_size;
|
||||||
|
|
||||||
/* Check the root_dirent. */
|
/* Check the root_dirent. */
|
||||||
if (check_dirent(root_dirent) != 0)
|
if (check_dirent(root_dirent) != 0)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
|
|
||||||
if (path[0] == '/' && path[1] == '\0')
|
if (path[0] == '/' && path[1] == '\0')
|
||||||
{
|
{
|
||||||
*size = root_dirent->size;
|
*size = root_dirent->size;
|
||||||
return root_dirent;
|
return root_dirent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* goto root directy entries */
|
/* goto root directy entries */
|
||||||
dirent = (struct romfs_dirent *)root_dirent->data;
|
dirent = (struct romfs_dirent *)root_dirent->data;
|
||||||
dirent_size = root_dirent->size;
|
dirent_size = root_dirent->size;
|
||||||
|
|
||||||
/* get the end position of this subpath */
|
/* get the end position of this subpath */
|
||||||
subpath_end = path;
|
subpath_end = path;
|
||||||
/* skip /// */
|
/* skip /// */
|
||||||
while (*subpath_end && *subpath_end == '/')
|
while (*subpath_end && *subpath_end == '/')
|
||||||
subpath_end ++;
|
subpath_end ++;
|
||||||
subpath = subpath_end;
|
subpath = subpath_end;
|
||||||
while ((*subpath_end != '/') && *subpath_end)
|
while ((*subpath_end != '/') && *subpath_end)
|
||||||
subpath_end ++;
|
subpath_end ++;
|
||||||
|
|
||||||
while (dirent != RT_NULL)
|
while (dirent != NULL)
|
||||||
{
|
{
|
||||||
found = 0;
|
found = 0;
|
||||||
|
|
||||||
/* search in folder */
|
/* search in folder */
|
||||||
for (index = 0; index < dirent_size; index ++)
|
for (index = 0; index < dirent_size; index ++)
|
||||||
{
|
{
|
||||||
if (check_dirent(&dirent[index]) != 0)
|
if (check_dirent(&dirent[index]) != 0)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
|
if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
|
||||||
rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
|
rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
|
||||||
{
|
{
|
||||||
dirent_size = dirent[index].size;
|
dirent_size = dirent[index].size;
|
||||||
|
|
||||||
/* skip /// */
|
/* skip /// */
|
||||||
while (*subpath_end && *subpath_end == '/')
|
while (*subpath_end && *subpath_end == '/')
|
||||||
subpath_end ++;
|
subpath_end ++;
|
||||||
subpath = subpath_end;
|
subpath = subpath_end;
|
||||||
while ((*subpath_end != '/') && *subpath_end)
|
while ((*subpath_end != '/') && *subpath_end)
|
||||||
subpath_end ++;
|
subpath_end ++;
|
||||||
|
|
||||||
if (!(*subpath))
|
if (!(*subpath))
|
||||||
{
|
{
|
||||||
*size = dirent_size;
|
*size = dirent_size;
|
||||||
return &dirent[index];
|
return &dirent[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirent[index].type == ROMFS_DIRENT_DIR)
|
if (dirent[index].type == ROMFS_DIRENT_DIR)
|
||||||
{
|
{
|
||||||
/* enter directory */
|
/* enter directory */
|
||||||
dirent = (struct romfs_dirent*)dirent[index].data;
|
dirent = (struct romfs_dirent*)dirent[index].data;
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* return file dirent */
|
/* return file dirent */
|
||||||
if (subpath != RT_NULL)
|
if (subpath != NULL)
|
||||||
break; /* not the end of path */
|
break; /* not the end of path */
|
||||||
|
|
||||||
return &dirent[index];
|
return &dirent[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
break; /* not found */
|
break; /* not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not found */
|
/* not found */
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_read(struct dfs_fd *file, void *buf, rt_size_t count)
|
int dfs_romfs_read(struct dfs_fd *file, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
rt_size_t length;
|
rt_size_t length;
|
||||||
struct romfs_dirent *dirent;
|
struct romfs_dirent *dirent;
|
||||||
|
|
||||||
dirent = (struct romfs_dirent *)file->data;
|
dirent = (struct romfs_dirent *)file->data;
|
||||||
RT_ASSERT(dirent != RT_NULL);
|
RT_ASSERT(dirent != NULL);
|
||||||
|
|
||||||
if (check_dirent(dirent) != 0)
|
if (check_dirent(dirent) != 0)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count < file->size - file->pos)
|
if (count < file->size - file->pos)
|
||||||
length = count;
|
length = count;
|
||||||
else
|
else
|
||||||
length = file->size - file->pos;
|
length = file->size - file->pos;
|
||||||
|
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
memcpy(buf, &(dirent->data[file->pos]), length);
|
memcpy(buf, &(dirent->data[file->pos]), length);
|
||||||
|
|
||||||
/* update file current position */
|
/* update file current position */
|
||||||
file->pos += length;
|
file->pos += length;
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_lseek(struct dfs_fd *file, rt_off_t offset)
|
int dfs_romfs_lseek(struct dfs_fd *file, off_t offset)
|
||||||
{
|
{
|
||||||
if (offset <= file->size)
|
if (offset <= file->size)
|
||||||
{
|
{
|
||||||
file->pos = offset;
|
file->pos = offset;
|
||||||
return file->pos;
|
return file->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_close(struct dfs_fd *file)
|
int dfs_romfs_close(struct dfs_fd *file)
|
||||||
{
|
{
|
||||||
file->data = RT_NULL;
|
file->data = NULL;
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_open(struct dfs_fd *file)
|
int dfs_romfs_open(struct dfs_fd *file)
|
||||||
{
|
{
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
struct romfs_dirent *dirent;
|
struct romfs_dirent *dirent;
|
||||||
struct romfs_dirent *root_dirent;
|
struct romfs_dirent *root_dirent;
|
||||||
|
|
||||||
root_dirent = (struct romfs_dirent *)file->fs->data;
|
root_dirent = (struct romfs_dirent *)file->fs->data;
|
||||||
|
|
||||||
if (check_dirent(root_dirent) != 0)
|
if (check_dirent(root_dirent) != 0)
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
|
if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
|
dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
/* entry is a directory file type */
|
/* entry is a directory file type */
|
||||||
if (dirent->type == ROMFS_DIRENT_DIR)
|
if (dirent->type == ROMFS_DIRENT_DIR)
|
||||||
{
|
{
|
||||||
if (!(file->flags & DFS_O_DIRECTORY))
|
if (!(file->flags & O_DIRECTORY))
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* entry is a file, but open it as a directory */
|
/* entry is a file, but open it as a directory */
|
||||||
if (file->flags & DFS_O_DIRECTORY)
|
if (file->flags & O_DIRECTORY)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->data = dirent;
|
file->data = dirent;
|
||||||
file->size = size;
|
file->size = size;
|
||||||
file->pos = 0;
|
file->pos = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
|
||||||
{
|
{
|
||||||
rt_size_t size;
|
rt_size_t size;
|
||||||
struct romfs_dirent *dirent;
|
struct romfs_dirent *dirent;
|
||||||
struct romfs_dirent *root_dirent;
|
struct romfs_dirent *root_dirent;
|
||||||
|
|
||||||
root_dirent = (struct romfs_dirent *)fs->data;
|
root_dirent = (struct romfs_dirent *)fs->data;
|
||||||
dirent = dfs_romfs_lookup(root_dirent, path, &size);
|
dirent = dfs_romfs_lookup(root_dirent, path, &size);
|
||||||
|
|
||||||
if (dirent == RT_NULL)
|
if (dirent == NULL)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
if (dirent->type == ROMFS_DIRENT_DIR)
|
if (dirent->type == ROMFS_DIRENT_DIR)
|
||||||
{
|
{
|
||||||
st->st_mode &= ~DFS_S_IFREG;
|
st->st_mode &= ~S_IFREG;
|
||||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
st->st_size = dirent->size;
|
st->st_size = dirent->size;
|
||||||
st->st_mtime = 0;
|
st->st_mtime = 0;
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
|
int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
|
||||||
{
|
{
|
||||||
rt_size_t index;
|
rt_size_t index;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
struct romfs_dirent *dirent, *sub_dirent;
|
struct romfs_dirent *dirent, *sub_dirent;
|
||||||
|
|
||||||
dirent = (struct romfs_dirent *)file->data;
|
dirent = (struct romfs_dirent *)file->data;
|
||||||
if (check_dirent(dirent) != 0)
|
if (check_dirent(dirent) != 0)
|
||||||
return -DFS_STATUS_EIO;
|
return -EIO;
|
||||||
RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
|
RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
|
||||||
|
|
||||||
/* enter directory */
|
/* enter directory */
|
||||||
dirent = (struct romfs_dirent *)dirent->data;
|
dirent = (struct romfs_dirent *)dirent->data;
|
||||||
|
|
||||||
/* make integer count */
|
/* make integer count */
|
||||||
count = (count / sizeof(struct dirent));
|
count = (count / sizeof(struct dirent));
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
for (index = 0; index < count && file->pos < file->size; index ++)
|
for (index = 0; index < count && file->pos < file->size; index ++)
|
||||||
{
|
{
|
||||||
d = dirp + index;
|
d = dirp + index;
|
||||||
|
|
||||||
sub_dirent = &dirent[file->pos];
|
sub_dirent = &dirent[file->pos];
|
||||||
name = sub_dirent->name;
|
name = sub_dirent->name;
|
||||||
|
|
||||||
/* fill dirent */
|
/* fill dirent */
|
||||||
if (sub_dirent->type == ROMFS_DIRENT_DIR)
|
if (sub_dirent->type == ROMFS_DIRENT_DIR)
|
||||||
d->d_type = DFS_DT_DIR;
|
d->d_type = DT_DIR;
|
||||||
else
|
else
|
||||||
d->d_type = DFS_DT_REG;
|
d->d_type = DT_REG;
|
||||||
|
|
||||||
d->d_namlen = rt_strlen(name);
|
d->d_namlen = rt_strlen(name);
|
||||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
|
rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
|
||||||
|
|
||||||
/* move to next position */
|
/* move to next position */
|
||||||
++ file->pos;
|
++ file->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
return index * sizeof(struct dirent);
|
return index * sizeof(struct dirent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation _romfs =
|
static const struct dfs_file_ops _rom_fops =
|
||||||
{
|
{
|
||||||
"rom",
|
dfs_romfs_open,
|
||||||
DFS_FS_FLAG_DEFAULT,
|
dfs_romfs_close,
|
||||||
dfs_romfs_mount,
|
dfs_romfs_ioctl,
|
||||||
dfs_romfs_unmount,
|
dfs_romfs_read,
|
||||||
RT_NULL,
|
NULL,
|
||||||
RT_NULL,
|
NULL,
|
||||||
|
dfs_romfs_lseek,
|
||||||
|
dfs_romfs_getdents,
|
||||||
|
};
|
||||||
|
static const struct dfs_filesystem_ops _romfs =
|
||||||
|
{
|
||||||
|
"rom",
|
||||||
|
DFS_FS_FLAG_DEFAULT,
|
||||||
|
&_rom_fops,
|
||||||
|
|
||||||
dfs_romfs_open,
|
dfs_romfs_mount,
|
||||||
dfs_romfs_close,
|
dfs_romfs_unmount,
|
||||||
dfs_romfs_ioctl,
|
NULL,
|
||||||
dfs_romfs_read,
|
NULL,
|
||||||
RT_NULL,
|
|
||||||
RT_NULL,
|
NULL,
|
||||||
dfs_romfs_lseek,
|
dfs_romfs_stat,
|
||||||
dfs_romfs_getdents,
|
NULL,
|
||||||
RT_NULL,
|
|
||||||
dfs_romfs_stat,
|
|
||||||
RT_NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int dfs_romfs_init(void)
|
int dfs_romfs_init(void)
|
||||||
{
|
{
|
||||||
/* register rom file system */
|
/* register rom file system */
|
||||||
dfs_register(&_romfs);
|
dfs_register(&_romfs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_FS_EXPORT(dfs_romfs_init);
|
INIT_FS_EXPORT(dfs_romfs_init);
|
||||||
|
|
||||||
|
@ -67,37 +67,37 @@ static int uffs_result_to_dfs(int result)
|
|||||||
break;
|
break;
|
||||||
case UEACCES:/** Tried to open read-only file for writing, or files sharing mode
|
case UEACCES:/** Tried to open read-only file for writing, or files sharing mode
|
||||||
does not allow specified operations, or given path is directory */
|
does not allow specified operations, or given path is directory */
|
||||||
status = -DFS_STATUS_EINVAL;
|
status = -EINVAL;
|
||||||
break;/* no suitable */
|
break;/* no suitable */
|
||||||
case UEEXIST: /** _O_CREAT and _O_EXCL flags specified, but filename already exists */
|
case UEEXIST: /** _O_CREAT and _O_EXCL flags specified, but filename already exists */
|
||||||
status = -DFS_STATUS_EEXIST;
|
status = -EEXIST;
|
||||||
break;
|
break;
|
||||||
case UEINVAL: /** Invalid oflag or pmode argument */
|
case UEINVAL: /** Invalid oflag or pmode argument */
|
||||||
status = -DFS_STATUS_EINVAL;
|
status = -EINVAL;
|
||||||
break;
|
break;
|
||||||
case UEMFILE: /** No more file handles available(too many open files) */
|
case UEMFILE: /** No more file handles available(too many open files) */
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
case UENOENT: /** file or path not found */
|
case UENOENT: /** file or path not found */
|
||||||
status = -DFS_STATUS_ENOENT;
|
status = -ENOENT;
|
||||||
break;
|
break;
|
||||||
case UETIME: /** can't set file time */
|
case UETIME: /** can't set file time */
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
case UEBADF: /** invalid file handle */
|
case UEBADF: /** invalid file handle */
|
||||||
status = -DFS_STATUS_EBADF;
|
status = -EBADF;
|
||||||
break;
|
break;
|
||||||
case UENOMEM:/** no enough memory */
|
case UENOMEM:/** no enough memory */
|
||||||
status = -DFS_STATUS_ENOSPC;
|
status = -ENOSPC;
|
||||||
break;
|
break;
|
||||||
case UEIOERR: /** I/O error from lower level flash operation */
|
case UEIOERR: /** I/O error from lower level flash operation */
|
||||||
status = -DFS_STATUS_EIO;
|
status = -EIO;
|
||||||
break;
|
break;
|
||||||
case UENOTDIR: /** Not a directory */
|
case UENOTDIR: /** Not a directory */
|
||||||
status = -DFS_STATUS_ENOTDIR;
|
status = -ENOTDIR;
|
||||||
break;
|
break;
|
||||||
case UEISDIR: /** Is a directory */
|
case UEISDIR: /** Is a directory */
|
||||||
status = -DFS_STATUS_EISDIR;
|
status = -EISDIR;
|
||||||
break;
|
break;
|
||||||
case UEUNKNOWN_ERR:
|
case UEUNKNOWN_ERR:
|
||||||
default:
|
default:
|
||||||
@ -172,7 +172,7 @@ static int dfs_uffs_mount(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index == UFFS_DEVICE_MAX)
|
if (index == UFFS_DEVICE_MAX)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
/*2. fill partition structure */
|
/*2. fill partition structure */
|
||||||
nand_part[index].dev = dev;
|
nand_part[index].dev = dev;
|
||||||
@ -216,7 +216,7 @@ static int dfs_uffs_unmount(struct dfs_filesystem* fs)
|
|||||||
return (result == U_SUCC) ? DFS_STATUS_OK : -1;
|
return (result == U_SUCC) ? DFS_STATUS_OK : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_uffs_mkfs(rt_device_t dev_id)
|
static int dfs_uffs_mkfs(rt_device_t dev_id)
|
||||||
@ -235,7 +235,7 @@ static int dfs_uffs_mkfs(rt_device_t dev_id)
|
|||||||
if (index == UFFS_DEVICE_MAX)
|
if (index == UFFS_DEVICE_MAX)
|
||||||
{
|
{
|
||||||
/* can't find device driver */
|
/* can't find device driver */
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*2. then unmount the partition */
|
/*2. then unmount the partition */
|
||||||
@ -277,7 +277,7 @@ static int dfs_uffs_statfs(struct dfs_filesystem* fs,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index == UFFS_DEVICE_MAX)
|
if (index == UFFS_DEVICE_MAX)
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
buf->f_bsize = mtd->page_size*mtd->pages_per_block;
|
buf->f_bsize = mtd->page_size*mtd->pages_per_block;
|
||||||
buf->f_blocks = (mtd->block_end - mtd->block_start + 1);
|
buf->f_blocks = (mtd->block_end - mtd->block_start + 1);
|
||||||
@ -293,11 +293,11 @@ static int dfs_uffs_open(struct dfs_fd* file)
|
|||||||
char * file_path;
|
char * file_path;
|
||||||
|
|
||||||
oflag = file->flags;
|
oflag = file->flags;
|
||||||
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
if (oflag & O_DIRECTORY) /* operations about dir */
|
||||||
{
|
{
|
||||||
uffs_DIR * dir;
|
uffs_DIR * dir;
|
||||||
|
|
||||||
if (oflag & DFS_O_CREAT) /* create a dir*/
|
if (oflag & O_CREAT) /* create a dir*/
|
||||||
{
|
{
|
||||||
if (uffs_mkdir(file->path) < 0)
|
if (uffs_mkdir(file->path) < 0)
|
||||||
return uffs_result_to_dfs(uffs_get_error());
|
return uffs_result_to_dfs(uffs_get_error());
|
||||||
@ -305,7 +305,7 @@ static int dfs_uffs_open(struct dfs_fd* file)
|
|||||||
/* open dir */
|
/* open dir */
|
||||||
file_path = rt_malloc(FILE_PATH_MAX);
|
file_path = rt_malloc(FILE_PATH_MAX);
|
||||||
if(file_path == RT_NULL)
|
if(file_path == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (file->path[0] == '/' && !(file->path[1] == 0))
|
if (file->path[0] == '/' && !(file->path[1] == 0))
|
||||||
rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path);
|
rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path);
|
||||||
@ -331,15 +331,15 @@ static int dfs_uffs_open(struct dfs_fd* file)
|
|||||||
/* int uffs_open(const char *name, int oflag, ...); what is this?
|
/* int uffs_open(const char *name, int oflag, ...); what is this?
|
||||||
* uffs_open can open dir!! **/
|
* uffs_open can open dir!! **/
|
||||||
mode = 0;
|
mode = 0;
|
||||||
if (oflag & DFS_O_RDONLY) mode |= UO_RDONLY;
|
if (oflag & O_RDONLY) mode |= UO_RDONLY;
|
||||||
if (oflag & DFS_O_WRONLY) mode |= UO_WRONLY;
|
if (oflag & O_WRONLY) mode |= UO_WRONLY;
|
||||||
if (oflag & DFS_O_RDWR) mode |= UO_RDWR;
|
if (oflag & O_RDWR) mode |= UO_RDWR;
|
||||||
/* Opens the file, if it is existing. If not, a new file is created. */
|
/* Opens the file, if it is existing. If not, a new file is created. */
|
||||||
if (oflag & DFS_O_CREAT) mode |= UO_CREATE;
|
if (oflag & O_CREAT) mode |= UO_CREATE;
|
||||||
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
||||||
if (oflag & DFS_O_TRUNC) mode |= UO_TRUNC;
|
if (oflag & O_TRUNC) mode |= UO_TRUNC;
|
||||||
/* Creates a new file. The function fails if the file is already existing. */
|
/* Creates a new file. The function fails if the file is already existing. */
|
||||||
if (oflag & DFS_O_EXCL) mode |= UO_EXCL;
|
if (oflag & O_EXCL) mode |= UO_EXCL;
|
||||||
|
|
||||||
fd = uffs_open(file->path, mode);
|
fd = uffs_open(file->path, mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -355,7 +355,7 @@ static int dfs_uffs_open(struct dfs_fd* file)
|
|||||||
file->size = uffs_seek(fd, 0, USEEK_END);
|
file->size = uffs_seek(fd, 0, USEEK_END);
|
||||||
uffs_seek(fd, file->pos, USEEK_SET);
|
uffs_seek(fd, file->pos, USEEK_SET);
|
||||||
|
|
||||||
if (oflag & DFS_O_APPEND)
|
if (oflag & O_APPEND)
|
||||||
{
|
{
|
||||||
file->pos = uffs_seek(fd, 0, USEEK_END);
|
file->pos = uffs_seek(fd, 0, USEEK_END);
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ static int dfs_uffs_close(struct dfs_fd* file)
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
oflag = file->flags;
|
oflag = file->flags;
|
||||||
if (oflag & DFS_O_DIRECTORY)
|
if (oflag & O_DIRECTORY)
|
||||||
{
|
{
|
||||||
/* operations about dir */
|
/* operations about dir */
|
||||||
if (uffs_closedir((uffs_DIR *)(file->data)) < 0)
|
if (uffs_closedir((uffs_DIR *)(file->data)) < 0)
|
||||||
@ -387,7 +387,7 @@ static int dfs_uffs_close(struct dfs_fd* file)
|
|||||||
|
|
||||||
static int dfs_uffs_ioctl(struct dfs_fd * file, int cmd, void* args)
|
static int dfs_uffs_ioctl(struct dfs_fd * file, int cmd, void* args)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_uffs_read(struct dfs_fd * file, void* buf, rt_size_t len)
|
static int dfs_uffs_read(struct dfs_fd * file, void* buf, rt_size_t len)
|
||||||
@ -493,12 +493,12 @@ static int dfs_uffs_getdents(
|
|||||||
|
|
||||||
/* round count, count is always 1 */
|
/* round count, count is always 1 */
|
||||||
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
||||||
if (count == 0) return -DFS_STATUS_EINVAL;
|
if (count == 0) return -EINVAL;
|
||||||
|
|
||||||
/* allocate file name */
|
/* allocate file name */
|
||||||
file_path = rt_malloc(FILE_PATH_MAX);
|
file_path = rt_malloc(FILE_PATH_MAX);
|
||||||
if (file_path == RT_NULL)
|
if (file_path == RT_NULL)
|
||||||
return -DFS_STATUS_ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
/* usually, the while loop should only be looped only once! */
|
/* usually, the while loop should only be looped only once! */
|
||||||
@ -623,19 +623,8 @@ static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct sta
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dfs_filesystem_operation dfs_uffs_ops =
|
static const struct dfs_file_ops dfs_uffs_fops =
|
||||||
{
|
{
|
||||||
"uffs", /* file system type: uffs */
|
|
||||||
#if RTTHREAD_VERSION >= 10100
|
|
||||||
DFS_FS_FLAG_FULLPATH,
|
|
||||||
#else
|
|
||||||
#error "uffs can only work with rtthread whose version should >= 1.01\n"
|
|
||||||
#endif
|
|
||||||
dfs_uffs_mount,
|
|
||||||
dfs_uffs_unmount,
|
|
||||||
dfs_uffs_mkfs,
|
|
||||||
dfs_uffs_statfs,
|
|
||||||
|
|
||||||
dfs_uffs_open,
|
dfs_uffs_open,
|
||||||
dfs_uffs_close,
|
dfs_uffs_close,
|
||||||
dfs_uffs_ioctl,
|
dfs_uffs_ioctl,
|
||||||
@ -644,6 +633,23 @@ static const struct dfs_filesystem_operation dfs_uffs_ops =
|
|||||||
dfs_uffs_flush,
|
dfs_uffs_flush,
|
||||||
dfs_uffs_seek,
|
dfs_uffs_seek,
|
||||||
dfs_uffs_getdents,
|
dfs_uffs_getdents,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_ops dfs_uffs_ops =
|
||||||
|
{
|
||||||
|
"uffs", /* file system type: uffs */
|
||||||
|
#if RTTHREAD_VERSION >= 10100
|
||||||
|
DFS_FS_FLAG_FULLPATH,
|
||||||
|
#else
|
||||||
|
#error "uffs can only work with rtthread whose version should >= 1.01\n"
|
||||||
|
#endif
|
||||||
|
&dfs_uffs_fops,
|
||||||
|
|
||||||
|
dfs_uffs_mount,
|
||||||
|
dfs_uffs_unmount,
|
||||||
|
dfs_uffs_mkfs,
|
||||||
|
dfs_uffs_statfs,
|
||||||
|
|
||||||
dfs_uffs_unlink,
|
dfs_uffs_unlink,
|
||||||
dfs_uffs_stat,
|
dfs_uffs_stat,
|
||||||
dfs_uffs_rename,
|
dfs_uffs_rename,
|
||||||
|
@ -25,17 +25,95 @@
|
|||||||
#ifndef __DFS_H__
|
#ifndef __DFS_H__
|
||||||
#define __DFS_H__
|
#define __DFS_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#ifndef DFS_FILESYSTEMS_MAX
|
||||||
|
#define DFS_FILESYSTEMS_MAX 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_FD_MAX
|
||||||
|
#define DFS_FD_MAX 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skip stdin/stdout/stderr normally
|
||||||
|
*/
|
||||||
|
#ifndef DFS_FD_OFFSET
|
||||||
|
#define DFS_FD_OFFSET 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_PATH_MAX
|
||||||
|
#define DFS_PATH_MAX 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SECTOR_SIZE
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFS_FILESYSTEM_TYPES_MAX
|
||||||
|
#define DFS_FILESYSTEM_TYPES_MAX 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */
|
||||||
|
#define DFS_FS_FLAG_FULLPATH 0x01 /* set full path to underlaying file system */
|
||||||
|
|
||||||
|
/* File types */
|
||||||
|
#define FT_REGULAR 0 /* regular file */
|
||||||
|
#define FT_SOCKET 1 /* socket file */
|
||||||
|
#define FT_DIRECTORY 2 /* directory */
|
||||||
|
#define FT_USER 3 /* user defined */
|
||||||
|
|
||||||
|
/* File flags */
|
||||||
|
#define DFS_F_OPEN 0x01000000
|
||||||
|
#define DFS_F_DIRECTORY 0x02000000
|
||||||
|
#define DFS_F_EOF 0x04000000
|
||||||
|
#define DFS_F_ERR 0x08000000
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NO_WORKING_DIR "system does not support working directory\n"
|
struct stat
|
||||||
|
{
|
||||||
|
struct rt_device* st_dev;
|
||||||
|
uint16_t st_mode;
|
||||||
|
uint32_t st_size;
|
||||||
|
time_t st_mtime;
|
||||||
|
uint32_t st_blksize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct statfs
|
||||||
|
{
|
||||||
|
size_t f_bsize; /* block size */
|
||||||
|
size_t f_blocks; /* total data blocks in file system */
|
||||||
|
size_t f_bfree; /* free blocks in file system */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dirent
|
||||||
|
{
|
||||||
|
uint8_t d_type; /* The type of the file */
|
||||||
|
uint8_t d_namlen; /* The length of the not including the terminating null file name */
|
||||||
|
uint16_t d_reclen; /* length of this record */
|
||||||
|
char d_name[DFS_PATH_MAX]; /* The null-terminated file name */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialization of dfs */
|
||||||
|
int dfs_init(void);
|
||||||
|
|
||||||
char *dfs_normalize_path(const char *directory, const char *filename);
|
char *dfs_normalize_path(const char *directory, const char *filename);
|
||||||
const char *dfs_subdir(const char *directory, const char *filename);
|
const char *dfs_subdir(const char *directory, const char *filename);
|
||||||
|
|
||||||
|
void dfs_lock(void);
|
||||||
|
void dfs_unlock(void);
|
||||||
|
|
||||||
/* FD APIs */
|
/* FD APIs */
|
||||||
int fd_new(void);
|
int fd_new(void);
|
||||||
struct dfs_fd *fd_get(int fd);
|
struct dfs_fd *fd_get(int fd);
|
||||||
|
@ -1,316 +0,0 @@
|
|||||||
/*
|
|
||||||
* File : dfs_def.h
|
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2004-2012, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2004-10-01 Beranard The first version.
|
|
||||||
* 2004-10-14 Beranard Clean up the code.
|
|
||||||
* 2005-01-22 Beranard Clean up the code, port to MinGW
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DFS_DEF_H__
|
|
||||||
#define __DFS_DEF_H__
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
#ifndef __D_FS__
|
|
||||||
#define __D_FS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEVICE_GETGEOME 0
|
|
||||||
#define DEVICE_GETINFO 1
|
|
||||||
#define DEVICE_FORMAT 2
|
|
||||||
#define DEVICE_CLEAN_SECTOR 3
|
|
||||||
|
|
||||||
/* File flags */
|
|
||||||
#define DFS_F_OPEN 0x01000000
|
|
||||||
#define DFS_F_DIRECTORY 0x02000000
|
|
||||||
#define DFS_F_EOF 0x04000000
|
|
||||||
#define DFS_F_ERR 0x08000000
|
|
||||||
|
|
||||||
#ifndef DFS_PATH_MAX
|
|
||||||
#define DFS_PATH_MAX 256
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SECTOR_SIZE
|
|
||||||
#define SECTOR_SIZE 512
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DFS_FILESYSTEM_TYPES_MAX
|
|
||||||
#define DFS_FILESYSTEM_TYPES_MAX 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DFS_DEBUG_INFO 0x01
|
|
||||||
#define DFS_DEBUG_WARNING 0x02
|
|
||||||
#define DFS_DEBUG_ERROR 0x04
|
|
||||||
#define DFS_DEBUG_LEVEL (DFS_DEBUG_INFO | DFS_DEBUG_WARNING | DFS_DEBUG_ERROR)
|
|
||||||
|
|
||||||
/* #define DFS_DEBUG */
|
|
||||||
#ifdef DFS_DEBUG
|
|
||||||
#define dfs_log(level, x) do { if (level & DFS_DEBUG_LEVEL) \
|
|
||||||
{rt_kprintf("DFS %s, %d:", __FUNCTION__, __LINE__); rt_kprintf x; \
|
|
||||||
rt_kprintf ("\n");}}while (0)
|
|
||||||
#else
|
|
||||||
#define dfs_log(level, x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RT_USING_NEWLIB)
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h> /* used for struct stat */
|
|
||||||
#include <sys/statfs.h> /* used for struct statfs */
|
|
||||||
#include <sys/errno.h> /* used for error number */
|
|
||||||
#include <sys/fcntl.h> /* used for operation flags */
|
|
||||||
#include <sys/unistd.h> /* used for SEEK_SET/CUR/END */
|
|
||||||
#include <dirent.h> /* used for struct dirent */
|
|
||||||
|
|
||||||
/* Device error codes */
|
|
||||||
#define DFS_STATUS_OK 0 /* no error */
|
|
||||||
#define DFS_STATUS_ENOENT ENOENT /* No such file or directory */
|
|
||||||
#define DFS_STATUS_EIO EIO /* I/O error */
|
|
||||||
#define DFS_STATUS_ENXIO ENXIO /* No such device or address */
|
|
||||||
#define DFS_STATUS_EBADF EBADF /* Bad file number */
|
|
||||||
#define DFS_STATUS_EAGAIN EAGAIN /* Try again */
|
|
||||||
#define DFS_STATUS_ENOMEM ENOMEM /* no memory */
|
|
||||||
#define DFS_STATUS_EBUSY EBUSY /* Device or resource busy */
|
|
||||||
#define DFS_STATUS_EEXIST EEXIST /* File exists */
|
|
||||||
#define DFS_STATUS_EXDEV EXDEV /* Cross-device link */
|
|
||||||
#define DFS_STATUS_ENODEV ENODEV /* No such device */
|
|
||||||
#define DFS_STATUS_ENOTDIR ENOTDIR /* Not a directory */
|
|
||||||
#define DFS_STATUS_EISDIR EISDIR /* Is a directory */
|
|
||||||
#define DFS_STATUS_EINVAL EINVAL /* Invalid argument */
|
|
||||||
#define DFS_STATUS_ENOSPC ENOSPC /* No space left on device */
|
|
||||||
#define DFS_STATUS_EROFS EROFS /* Read-only file system */
|
|
||||||
#define DFS_STATUS_ENOSYS ENOSYS /* Function not implemented */
|
|
||||||
#define DFS_STATUS_ENOTEMPTY ENOTEMPTY /* Directory not empty */
|
|
||||||
|
|
||||||
/* Operation flags */
|
|
||||||
#define DFS_O_RDONLY O_RDONLY
|
|
||||||
#define DFS_O_WRONLY O_WRONLY
|
|
||||||
#define DFS_O_RDWR O_RDWR
|
|
||||||
#define DFS_O_ACCMODE O_ACCMODE
|
|
||||||
#define DFS_O_CREAT O_CREAT
|
|
||||||
#define DFS_O_EXCL O_EXCL
|
|
||||||
#define DFS_O_TRUNC O_TRUNC
|
|
||||||
#define DFS_O_APPEND O_APPEND
|
|
||||||
#define DFS_O_DIRECTORY O_DIRECTORY
|
|
||||||
|
|
||||||
/* Seek flags */
|
|
||||||
#define DFS_SEEK_SET SEEK_SET
|
|
||||||
#define DFS_SEEK_CUR SEEK_CUR
|
|
||||||
#define DFS_SEEK_END SEEK_END
|
|
||||||
|
|
||||||
/* Stat codes */
|
|
||||||
#define DFS_S_IFMT S_IFMT
|
|
||||||
#define DFS_S_IFSOCK S_IFSOCK
|
|
||||||
#define DFS_S_IFLNK S_IFLNK
|
|
||||||
#define DFS_S_IFREG S_IFREG
|
|
||||||
#define DFS_S_IFBLK S_IFBLK
|
|
||||||
#define DFS_S_IFDIR S_IFDIR
|
|
||||||
#define DFS_S_IFCHR S_IFCHR
|
|
||||||
#define DFS_S_IFIFO S_IFIFO
|
|
||||||
#define DFS_S_ISUID S_ISUID
|
|
||||||
#define DFS_S_ISGID S_ISGID
|
|
||||||
#define DFS_S_ISVTX S_ISVTX
|
|
||||||
|
|
||||||
#define DFS_S_ISLNK(m) S_ISLNK(m)
|
|
||||||
#define DFS_S_ISREG(m) S_ISREG(m)
|
|
||||||
#define DFS_S_ISDIR(m) S_ISDIR(m)
|
|
||||||
#define DFS_S_ISCHR(m) S_ISCHR(m)
|
|
||||||
#define DFS_S_ISBLK(m) S_ISBLK(m)
|
|
||||||
#define DFS_S_ISFIFO(m) S_ISFIFO(m)
|
|
||||||
#define DFS_S_ISSOCK(m) S_ISSOCK(m)
|
|
||||||
|
|
||||||
#define DFS_S_IRWXU S_IRWXU
|
|
||||||
#define DFS_S_IRUSR S_IRUSR
|
|
||||||
#define DFS_S_IWUSR S_IWUSR
|
|
||||||
#define DFS_S_IXUSR S_IXUSR
|
|
||||||
|
|
||||||
#define DFS_S_IRWXG S_IRWXG
|
|
||||||
#define DFS_S_IRGRP S_IRGRP
|
|
||||||
#define DFS_S_IWGRP S_IWGRP
|
|
||||||
#define DFS_S_IXGRP S_IXGRP
|
|
||||||
|
|
||||||
#define DFS_S_IRWXO S_IRWXO
|
|
||||||
#define DFS_S_IROTH S_IROTH
|
|
||||||
#define DFS_S_IWOTH S_IWOTH
|
|
||||||
#define DFS_S_IXOTH S_IXOTH
|
|
||||||
|
|
||||||
/* Dirent types */
|
|
||||||
#define DFS_DT_UNKNOWN DT_UNKNOWN
|
|
||||||
#define DFS_DT_REG DT_REG
|
|
||||||
#define DFS_DT_DIR DT_DIR
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef RT_USING_MINILIBC
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
typedef long off_t;
|
|
||||||
typedef int mode_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Device error codes */
|
|
||||||
#define DFS_STATUS_OK 0 /* no error */
|
|
||||||
#define DFS_STATUS_ENOENT 2 /* No such file or directory */
|
|
||||||
#define DFS_STATUS_EIO 5 /* I/O error */
|
|
||||||
#define DFS_STATUS_ENXIO 6 /* No such device or address */
|
|
||||||
#define DFS_STATUS_EBADF 9 /* Bad file number */
|
|
||||||
#define DFS_STATUS_EAGAIN 11 /* Try again */
|
|
||||||
#define DFS_STATUS_ENOMEM 12 /* no memory */
|
|
||||||
#define DFS_STATUS_EBUSY 16 /* Device or resource busy */
|
|
||||||
#define DFS_STATUS_EEXIST 17 /* File exists */
|
|
||||||
#define DFS_STATUS_EXDEV 18 /* Cross-device link */
|
|
||||||
#define DFS_STATUS_ENODEV 19 /* No such device */
|
|
||||||
#define DFS_STATUS_ENOTDIR 20 /* Not a directory */
|
|
||||||
#define DFS_STATUS_EISDIR 21 /* Is a directory */
|
|
||||||
#define DFS_STATUS_EINVAL 22 /* Invalid argument */
|
|
||||||
#define DFS_STATUS_ENOSPC 28 /* No space left on device */
|
|
||||||
#define DFS_STATUS_EROFS 30 /* Read-only file system */
|
|
||||||
#define DFS_STATUS_ENOSYS 38 /* Function not implemented */
|
|
||||||
#define DFS_STATUS_ENOTEMPTY 39 /* Directory not empty */
|
|
||||||
|
|
||||||
/* Operation flags */
|
|
||||||
#define DFS_O_RDONLY 0x0000000
|
|
||||||
#define DFS_O_WRONLY 0x0000001
|
|
||||||
#define DFS_O_RDWR 0x0000002
|
|
||||||
#define DFS_O_ACCMODE 0x0000003
|
|
||||||
#define DFS_O_CREAT 0x0000100
|
|
||||||
#define DFS_O_EXCL 0x0000200
|
|
||||||
#define DFS_O_TRUNC 0x0001000
|
|
||||||
#define DFS_O_APPEND 0x0002000
|
|
||||||
#define DFS_O_BINARY 0x0008000
|
|
||||||
#define DFS_O_DIRECTORY 0x0200000
|
|
||||||
|
|
||||||
/* File flags */
|
|
||||||
#define DFS_F_OPEN 0x01000000
|
|
||||||
#define DFS_F_DIRECTORY 0x02000000
|
|
||||||
#define DFS_F_EOF 0x04000000
|
|
||||||
#define DFS_F_ERR 0x08000000
|
|
||||||
|
|
||||||
/* Seek flags */
|
|
||||||
#ifdef __CC_ARM
|
|
||||||
#include <stdio.h>
|
|
||||||
#define DFS_SEEK_SET SEEK_SET
|
|
||||||
#define DFS_SEEK_CUR SEEK_CUR
|
|
||||||
#define DFS_SEEK_END SEEK_END
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#include <stdio.h>
|
|
||||||
#define DFS_SEEK_SET SEEK_SET
|
|
||||||
#define DFS_SEEK_CUR SEEK_CUR
|
|
||||||
#define DFS_SEEK_END SEEK_END
|
|
||||||
#else
|
|
||||||
#define DFS_SEEK_SET 0
|
|
||||||
#define DFS_SEEK_CUR 1
|
|
||||||
#define DFS_SEEK_END 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Stat codes */
|
|
||||||
#define DFS_S_IFMT 00170000
|
|
||||||
#define DFS_S_IFSOCK 0140000
|
|
||||||
#define DFS_S_IFLNK 0120000
|
|
||||||
#define DFS_S_IFREG 0100000
|
|
||||||
#define DFS_S_IFBLK 0060000
|
|
||||||
#define DFS_S_IFDIR 0040000
|
|
||||||
#define DFS_S_IFCHR 0020000
|
|
||||||
#define DFS_S_IFIFO 0010000
|
|
||||||
#define DFS_S_ISUID 0004000
|
|
||||||
#define DFS_S_ISGID 0002000
|
|
||||||
#define DFS_S_ISVTX 0001000
|
|
||||||
|
|
||||||
#define DFS_S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK)
|
|
||||||
#define DFS_S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG)
|
|
||||||
#define DFS_S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR)
|
|
||||||
#define DFS_S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR)
|
|
||||||
#define DFS_S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK)
|
|
||||||
#define DFS_S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO)
|
|
||||||
#define DFS_S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK)
|
|
||||||
|
|
||||||
#define DFS_S_IRWXU 00700
|
|
||||||
#define DFS_S_IRUSR 00400
|
|
||||||
#define DFS_S_IWUSR 00200
|
|
||||||
#define DFS_S_IXUSR 00100
|
|
||||||
|
|
||||||
#define DFS_S_IRWXG 00070
|
|
||||||
#define DFS_S_IRGRP 00040
|
|
||||||
#define DFS_S_IWGRP 00020
|
|
||||||
#define DFS_S_IXGRP 00010
|
|
||||||
|
|
||||||
#define DFS_S_IRWXO 00007
|
|
||||||
#define DFS_S_IROTH 00004
|
|
||||||
#define DFS_S_IWOTH 00002
|
|
||||||
#define DFS_S_IXOTH 00001
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <wchar.h>
|
|
||||||
#else
|
|
||||||
struct stat
|
|
||||||
{
|
|
||||||
rt_device_t st_dev;
|
|
||||||
rt_uint16_t st_mode;
|
|
||||||
rt_uint32_t st_size;
|
|
||||||
rt_time_t st_mtime;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct statfs
|
|
||||||
{
|
|
||||||
rt_size_t f_bsize; /* block size */
|
|
||||||
rt_size_t f_blocks; /* total data blocks in file system */
|
|
||||||
rt_size_t f_bfree; /* free blocks in file system */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* File types */
|
|
||||||
#define FT_REGULAR 0 /* regular file */
|
|
||||||
#define FT_SOCKET 1 /* socket file */
|
|
||||||
#define FT_DIRECTORY 2 /* directory */
|
|
||||||
#define FT_USER 3 /* user defined */
|
|
||||||
|
|
||||||
/* Dirent types */
|
|
||||||
#define DFS_DT_UNKNOWN 0x00
|
|
||||||
#define DFS_DT_REG 0x01
|
|
||||||
#define DFS_DT_DIR 0x02
|
|
||||||
|
|
||||||
struct dirent
|
|
||||||
{
|
|
||||||
rt_uint8_t d_type; /* The type of the file */
|
|
||||||
rt_uint8_t d_namlen; /* The length of the not including the terminating null file name */
|
|
||||||
rt_uint16_t d_reclen; /* length of this record */
|
|
||||||
char d_name[DFS_PATH_MAX]; /* The null-terminated file name */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* file descriptor */
|
|
||||||
#define DFS_FD_MAGIC 0xfdfd
|
|
||||||
struct dfs_fd
|
|
||||||
{
|
|
||||||
rt_uint16_t magic; /* file descriptor magic number */
|
|
||||||
rt_uint16_t type; /* Type (regular or socket) */
|
|
||||||
char *path; /* Name (below mount point) */
|
|
||||||
int ref_count; /* Descriptor reference count */
|
|
||||||
|
|
||||||
struct dfs_filesystem *fs; /* Resident file system */
|
|
||||||
|
|
||||||
rt_uint32_t flags; /* Descriptor flags */
|
|
||||||
rt_size_t size; /* Size in bytes */
|
|
||||||
rt_off_t pos; /* Current file position */
|
|
||||||
|
|
||||||
void *data; /* Specific file system data */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -25,21 +25,63 @@
|
|||||||
#ifndef __DFS_FILE_H__
|
#ifndef __DFS_FILE_H__
|
||||||
#define __DFS_FILE_H__
|
#define __DFS_FILE_H__
|
||||||
|
|
||||||
#include <dfs_def.h>
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rt_pollreq;
|
||||||
|
|
||||||
|
struct dfs_file_ops
|
||||||
|
{
|
||||||
|
int (*open) (struct dfs_fd *fd);
|
||||||
|
int (*close) (struct dfs_fd *fd);
|
||||||
|
int (*ioctl) (struct dfs_fd *fd, int cmd, void *args);
|
||||||
|
int (*read) (struct dfs_fd *fd, void *buf, size_t count);
|
||||||
|
int (*write) (struct dfs_fd *fd, const void *buf, size_t count);
|
||||||
|
int (*flush) (struct dfs_fd *fd);
|
||||||
|
int (*lseek) (struct dfs_fd *fd, off_t offset);
|
||||||
|
int (*getdents) (struct dfs_fd *fd, struct dirent *dirp, uint32_t count);
|
||||||
|
|
||||||
|
int (*poll) (struct dfs_fd *fd, struct rt_pollreq *req);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* file descriptor */
|
||||||
|
#define DFS_FD_MAGIC 0xfdfd
|
||||||
|
struct dfs_fd
|
||||||
|
{
|
||||||
|
uint16_t magic; /* file descriptor magic number */
|
||||||
|
uint16_t type; /* Type (regular or socket) */
|
||||||
|
|
||||||
|
char *path; /* Name (below mount point) */
|
||||||
|
int ref_count; /* Descriptor reference count */
|
||||||
|
|
||||||
|
const struct dfs_file_ops *fops;
|
||||||
|
|
||||||
|
uint32_t flags; /* Descriptor flags */
|
||||||
|
size_t size; /* Size in bytes */
|
||||||
|
off_t pos; /* Current file position */
|
||||||
|
|
||||||
|
void *data; /* Specific file system data */
|
||||||
|
};
|
||||||
|
|
||||||
int dfs_file_open(struct dfs_fd *fd, const char *path, int flags);
|
int dfs_file_open(struct dfs_fd *fd, const char *path, int flags);
|
||||||
int dfs_file_close(struct dfs_fd *fd);
|
int dfs_file_close(struct dfs_fd *fd);
|
||||||
int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args);
|
int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args);
|
||||||
int dfs_file_read(struct dfs_fd *fd, void *buf, rt_size_t len);
|
int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len);
|
||||||
int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, rt_size_t nbytes);
|
int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, size_t nbytes);
|
||||||
int dfs_file_unlink(const char *path);
|
int dfs_file_unlink(const char *path);
|
||||||
int dfs_file_write(struct dfs_fd *fd, const void *buf, rt_size_t len);
|
int dfs_file_write(struct dfs_fd *fd, const void *buf, size_t len);
|
||||||
int dfs_file_flush(struct dfs_fd *fd);
|
int dfs_file_flush(struct dfs_fd *fd);
|
||||||
int dfs_file_lseek(struct dfs_fd *fd, rt_off_t offset);
|
int dfs_file_lseek(struct dfs_fd *fd, off_t offset);
|
||||||
|
|
||||||
int dfs_file_stat(const char *path, struct stat *buf);
|
int dfs_file_stat(const char *path, struct stat *buf);
|
||||||
int dfs_file_rename(const char *oldpath, const char *newpath);
|
int dfs_file_rename(const char *oldpath, const char *newpath);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -25,20 +25,24 @@
|
|||||||
#ifndef __DFS_FS_H__
|
#ifndef __DFS_FS_H__
|
||||||
#define __DFS_FS_H__
|
#define __DFS_FS_H__
|
||||||
|
|
||||||
#include <dfs_def.h>
|
#include <dfs.h>
|
||||||
|
|
||||||
#define DFS_FS_FLAG_DEFAULT 0x00 /* default flag */
|
#ifdef __cplusplus
|
||||||
#define DFS_FS_FLAG_FULLPATH 0x01 /* set full path to underlaying file system */
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Pre-declaration */
|
/* Pre-declaration */
|
||||||
struct dfs_filesystem;
|
struct dfs_filesystem;
|
||||||
struct dfs_fd;
|
struct dfs_fd;
|
||||||
|
|
||||||
/* File system operations struct */
|
/* File system operations */
|
||||||
struct dfs_filesystem_operation
|
struct dfs_filesystem_ops
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
rt_uint32_t flags; /* flags for file system operations */
|
uint32_t flags; /* flags for file system operations */
|
||||||
|
|
||||||
|
/* operations for file */
|
||||||
|
const struct dfs_file_ops *fops;
|
||||||
|
|
||||||
/* mount and unmount file system */
|
/* mount and unmount file system */
|
||||||
int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data);
|
int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data);
|
||||||
@ -48,15 +52,6 @@ struct dfs_filesystem_operation
|
|||||||
int (*mkfs) (rt_device_t devid);
|
int (*mkfs) (rt_device_t devid);
|
||||||
int (*statfs) (struct dfs_filesystem *fs, struct statfs *buf);
|
int (*statfs) (struct dfs_filesystem *fs, struct statfs *buf);
|
||||||
|
|
||||||
int (*open) (struct dfs_fd *fd);
|
|
||||||
int (*close) (struct dfs_fd *fd);
|
|
||||||
int (*ioctl) (struct dfs_fd *fd, int cmd, void *args);
|
|
||||||
int (*read) (struct dfs_fd *fd, void *buf, rt_size_t count);
|
|
||||||
int (*write) (struct dfs_fd *fd, const void *buf, rt_size_t count);
|
|
||||||
int (*flush) (struct dfs_fd *fd);
|
|
||||||
int (*lseek) (struct dfs_fd *fd, rt_off_t offset);
|
|
||||||
int (*getdents) (struct dfs_fd *fd, struct dirent *dirp, rt_uint32_t count);
|
|
||||||
|
|
||||||
int (*unlink) (struct dfs_filesystem *fs, const char *pathname);
|
int (*unlink) (struct dfs_filesystem *fs, const char *pathname);
|
||||||
int (*stat) (struct dfs_filesystem *fs, const char *filename, struct stat *buf);
|
int (*stat) (struct dfs_filesystem *fs, const char *filename, struct stat *buf);
|
||||||
int (*rename) (struct dfs_filesystem *fs, const char *oldpath, const char *newpath);
|
int (*rename) (struct dfs_filesystem *fs, const char *oldpath, const char *newpath);
|
||||||
@ -68,7 +63,7 @@ struct dfs_filesystem
|
|||||||
rt_device_t dev_id; /* Attached device */
|
rt_device_t dev_id; /* Attached device */
|
||||||
|
|
||||||
char *path; /* File system mount point */
|
char *path; /* File system mount point */
|
||||||
const struct dfs_filesystem_operation *ops; /* Operations for file system type */
|
const struct dfs_filesystem_ops *ops; /* Operations for file system type */
|
||||||
|
|
||||||
void *data; /* Specific file system data */
|
void *data; /* Specific file system data */
|
||||||
};
|
};
|
||||||
@ -76,47 +71,42 @@ struct dfs_filesystem
|
|||||||
/* file system partition table */
|
/* file system partition table */
|
||||||
struct dfs_partition
|
struct dfs_partition
|
||||||
{
|
{
|
||||||
rt_uint8_t type; /* file system type */
|
uint8_t type; /* file system type */
|
||||||
rt_off_t offset; /* partition start offset */
|
off_t offset; /* partition start offset */
|
||||||
rt_size_t size; /* partition size */
|
size_t size; /* partition size */
|
||||||
rt_sem_t lock;
|
rt_sem_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* mount table */
|
/* mount table */
|
||||||
struct dfs_mount_tbl
|
struct dfs_mount_tbl
|
||||||
{
|
{
|
||||||
const char *device_name;
|
const char *device_name;
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *filesystemtype;
|
const char *filesystemtype;
|
||||||
unsigned long rwflag;
|
unsigned long rwflag;
|
||||||
const void *data;
|
const void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
int dfs_register(const struct dfs_filesystem_operation *ops);
|
int dfs_register(const struct dfs_filesystem_ops *ops);
|
||||||
struct dfs_filesystem *dfs_filesystem_lookup(const char *path);
|
struct dfs_filesystem *dfs_filesystem_lookup(const char *path);
|
||||||
const char* dfs_filesystem_get_mounted_path(struct rt_device* device);
|
const char* dfs_filesystem_get_mounted_path(struct rt_device* device);
|
||||||
|
|
||||||
rt_err_t dfs_filesystem_get_partition(struct dfs_partition *part,
|
int dfs_filesystem_get_partition(struct dfs_partition *part,
|
||||||
rt_uint8_t *buf,
|
uint8_t *buf,
|
||||||
rt_uint32_t pindex);
|
uint32_t pindex);
|
||||||
|
|
||||||
int dfs_mount(const char *device_name,
|
int dfs_mount(const char *device_name,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *filesystemtype,
|
const char *filesystemtype,
|
||||||
rt_uint32_t rwflag,
|
unsigned long rwflag,
|
||||||
const void *data);
|
const void *data);
|
||||||
int dfs_unmount(const char *specialfile);
|
int dfs_unmount(const char *specialfile);
|
||||||
|
|
||||||
/* extern variable */
|
|
||||||
extern const struct dfs_filesystem_operation *filesystem_operation_table[];
|
|
||||||
extern struct dfs_filesystem filesystem_table[];
|
|
||||||
extern const struct dfs_mount_tbl mount_table[];
|
|
||||||
|
|
||||||
extern char working_directory[];
|
|
||||||
|
|
||||||
void dfs_lock(void);
|
|
||||||
void dfs_unlock(void);
|
|
||||||
int dfs_mkfs(const char *fs_name, const char *device_name);
|
int dfs_mkfs(const char *fs_name, const char *device_name);
|
||||||
int dfs_statfs(const char *path, struct statfs *buffer);
|
int dfs_statfs(const char *path, struct statfs *buffer);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* File : dfs_init.h
|
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2004-2012, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2005-02-21 Bernard The first version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DFS_INIT_H__
|
|
||||||
#define __DFS_INIT_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialization of dfs */
|
|
||||||
int dfs_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -20,81 +20,21 @@
|
|||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2009-05-27 Yi.qiu The first version.
|
* 2009-05-27 Yi.qiu The first version.
|
||||||
* 2010-07-18 Bernard add stat and statfs structure definitions.
|
* 2010-07-18 Bernard add stat and statfs structure definitions.
|
||||||
* 2011-05-16 Yi.qiu Change parameter name of rename, "new" is C++ key word.
|
* 2011-05-16 Yi.qiu Change parameter name of rename, "new" is C++ key word.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DFS_POSIX_H__
|
#ifndef __DFS_POSIX_H__
|
||||||
#define __DFS_POSIX_H__
|
#define __DFS_POSIX_H__
|
||||||
|
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
#include <dfs_def.h>
|
#include <sys/time.h> /* for struct timeval */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(RT_USING_NEWLIB)
|
typedef struct
|
||||||
#define O_RDONLY DFS_O_RDONLY
|
|
||||||
#define O_WRONLY DFS_O_WRONLY
|
|
||||||
#define O_RDWR DFS_O_RDWR
|
|
||||||
#define O_ACCMODE DFS_O_ACCMODE
|
|
||||||
#define O_CREAT DFS_O_CREAT
|
|
||||||
#define O_EXCL DFS_O_EXCL
|
|
||||||
#define O_TRUNC DFS_O_TRUNC
|
|
||||||
#define O_APPEND DFS_O_APPEND
|
|
||||||
#define O_BINARY DFS_O_BINARY
|
|
||||||
#define O_DIRECTORY DFS_O_DIRECTORY
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
#define S_IFMT DFS_S_IFMT
|
|
||||||
#define S_IFSOCK DFS_S_IFSOCK
|
|
||||||
#define S_IFLNK DFS_S_IFLNK
|
|
||||||
#define S_IFREG DFS_S_IFREG
|
|
||||||
#define S_IFBLK DFS_S_IFBLK
|
|
||||||
#define S_IFDIR DFS_S_IFDIR
|
|
||||||
#define S_IFCHR DFS_S_IFCHR
|
|
||||||
#define S_IFIFO DFS_S_IFIFO
|
|
||||||
#define S_ISUID DFS_S_ISUID
|
|
||||||
#define S_ISGID DFS_S_ISGID
|
|
||||||
#define S_ISVTX DFS_S_ISVTX
|
|
||||||
|
|
||||||
#define S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK)
|
|
||||||
#define S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG)
|
|
||||||
#define S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR)
|
|
||||||
#define S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR)
|
|
||||||
#define S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK)
|
|
||||||
#define S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO)
|
|
||||||
#define S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK)
|
|
||||||
|
|
||||||
#define S_IRWXU DFS_S_IRWXU
|
|
||||||
#define S_IRUSR DFS_S_IRUSR
|
|
||||||
#define S_IWUSR DFS_S_IWUSR
|
|
||||||
#define S_IXUSR DFS_S_IXUSR
|
|
||||||
|
|
||||||
#define S_IRWXG DFS_S_IRWXG
|
|
||||||
#define S_IRGRP DFS_S_IRGRP
|
|
||||||
#define S_IWGRP DFS_S_IWGRP
|
|
||||||
#define S_IXGRP DFS_S_IXGRP
|
|
||||||
|
|
||||||
#define S_IRWXO DFS_S_IRWXO
|
|
||||||
#define S_IROTH DFS_S_IROTH
|
|
||||||
#define S_IWOTH DFS_S_IWOTH
|
|
||||||
#define S_IXOTH DFS_S_IXOTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__CC_ARM)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#include <stdio.h>
|
|
||||||
#else
|
|
||||||
#define SEEK_SET DFS_SEEK_SET
|
|
||||||
#define SEEK_CUR DFS_SEEK_CUR
|
|
||||||
#define SEEK_END DFS_SEEK_END
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
int fd; /* directory file */
|
int fd; /* directory file */
|
||||||
char buf[512];
|
char buf[512];
|
||||||
@ -111,13 +51,6 @@ void seekdir(DIR *d, off_t offset);
|
|||||||
void rewinddir(DIR *d);
|
void rewinddir(DIR *d);
|
||||||
int closedir(DIR* d);
|
int closedir(DIR* d);
|
||||||
|
|
||||||
#else
|
|
||||||
/* use newlib header file */
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct stat;
|
|
||||||
|
|
||||||
/* file api*/
|
/* file api*/
|
||||||
int open(const char *file, int flags, int mode);
|
int open(const char *file, int flags, int mode);
|
||||||
int close(int d);
|
int close(int d);
|
||||||
@ -134,7 +67,7 @@ int unlink(const char *pathname);
|
|||||||
int stat(const char *file, struct stat *buf);
|
int stat(const char *file, struct stat *buf);
|
||||||
int fstat(int fildes, struct stat *buf);
|
int fstat(int fildes, struct stat *buf);
|
||||||
int fsync(int fildes);
|
int fsync(int fildes);
|
||||||
int ioctl(int fildes, long cmd, void *data);
|
int ioctl(int fildes, int cmd, void *data);
|
||||||
|
|
||||||
/* directory api*/
|
/* directory api*/
|
||||||
int rmdir(const char *path);
|
int rmdir(const char *path);
|
||||||
@ -144,6 +77,100 @@ char *getcwd(char *buf, size_t size);
|
|||||||
/* file system api */
|
/* file system api */
|
||||||
int statfs(const char *path, struct statfs *buf);
|
int statfs(const char *path, struct statfs *buf);
|
||||||
|
|
||||||
|
int access(const char *path, int amode);
|
||||||
|
int pipe(int fildes[2]);
|
||||||
|
int mkfifo(const char *path, mode_t mode);
|
||||||
|
|
||||||
|
/* poll and select */
|
||||||
|
|
||||||
|
#define POLLIN (0x01)
|
||||||
|
#define POLLRDNORM (0x01)
|
||||||
|
#define POLLRDBAND (0x01)
|
||||||
|
#define POLLPRI (0x01)
|
||||||
|
|
||||||
|
#define POLLOUT (0x02)
|
||||||
|
#define POLLWRNORM (0x02)
|
||||||
|
#define POLLWRBAND (0x02)
|
||||||
|
|
||||||
|
#define POLLERR (0x04)
|
||||||
|
#define POLLHUP (0x08)
|
||||||
|
#define POLLNVAL (0x10)
|
||||||
|
|
||||||
|
#define POLLMASK_DEFAULT (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
|
||||||
|
|
||||||
|
typedef unsigned int nfds_t;
|
||||||
|
|
||||||
|
struct pollfd
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
short events;
|
||||||
|
short revents;
|
||||||
|
};
|
||||||
|
|
||||||
|
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RT_USING_LWIP
|
||||||
|
/* we use lwIP's structure definitions. */
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef FD_SET
|
||||||
|
|
||||||
|
/* Get the total number of descriptors that we will have to support */
|
||||||
|
|
||||||
|
#define FD_SETSIZE (12)
|
||||||
|
|
||||||
|
/* We will use a 32-bit bitsets to represent the set of descriptors. How
|
||||||
|
* many uint32_t's do we need to span all descriptors?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if FD_SETSIZE <= 32
|
||||||
|
# define __SELECT_NUINT32 1
|
||||||
|
#elif FD_SETSIZE <= 64
|
||||||
|
# define __SELECT_NUINT32 2
|
||||||
|
#elif FD_SETSIZE <= 96
|
||||||
|
# define __SELECT_NUINT32 3
|
||||||
|
#elif FD_SETSIZE <= 128
|
||||||
|
# define __SELECT_NUINT32 4
|
||||||
|
#elif FD_SETSIZE <= 160
|
||||||
|
# define __SELECT_NUINT32 5
|
||||||
|
#elif FD_SETSIZE <= 192
|
||||||
|
# define __SELECT_NUINT32 6
|
||||||
|
#elif FD_SETSIZE <= 224
|
||||||
|
# define __SELECT_NUINT32 7
|
||||||
|
#elif FD_SETSIZE <= 256
|
||||||
|
# define __SELECT_NUINT32 8
|
||||||
|
#else
|
||||||
|
# warning "Larger fd_set needed"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These macros map a file descriptor to an index and bit number */
|
||||||
|
|
||||||
|
#define _FD_NDX(fd) ((fd) >> 5)
|
||||||
|
#define _FD_BIT(fd) ((fd) & 0x1f)
|
||||||
|
|
||||||
|
/* Standard helper macros */
|
||||||
|
|
||||||
|
#define FD_CLR(fd,set) \
|
||||||
|
((((fd_set*)(set))->arr)[_FD_NDX(fd)] &= ~(1 << _FD_BIT(fd)))
|
||||||
|
#define FD_SET(fd,set) \
|
||||||
|
((((fd_set*)(set))->arr)[_FD_NDX(fd)] |= (1 << _FD_BIT(fd)))
|
||||||
|
#define FD_ISSET(fd,set) \
|
||||||
|
(((((fd_set*)(set))->arr)[_FD_NDX(fd)] & (1 << _FD_BIT(fd))) != 0)
|
||||||
|
#define FD_ZERO(set) \
|
||||||
|
memset((set), 0, sizeof(fd_set))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t arr[__SELECT_NUINT32];
|
||||||
|
}fd_set;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
21
components/dfs/include/dfs_private.h
Normal file
21
components/dfs/include/dfs_private.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef DFS_PRIVATE_H__
|
||||||
|
#define DFS_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
|
||||||
|
// #define DBG_ENABLE
|
||||||
|
#define DBG_SECTION_NAME "[ DFS]"
|
||||||
|
#define DBG_COLOR
|
||||||
|
#define DBG_LEVEL DBG_LOG
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#define NO_WORKING_DIR "system does not support working directory\n"
|
||||||
|
|
||||||
|
/* extern variable */
|
||||||
|
extern const struct dfs_filesystem_ops *filesystem_operation_table[];
|
||||||
|
extern struct dfs_filesystem filesystem_table[];
|
||||||
|
extern const struct dfs_mount_tbl mount_table[];
|
||||||
|
|
||||||
|
extern char working_directory[];
|
||||||
|
|
||||||
|
#endif
|
@ -25,9 +25,10 @@
|
|||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
|
#include "dfs_private.h"
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
const struct dfs_filesystem_operation *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
|
const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
|
||||||
struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
|
struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
|
||||||
|
|
||||||
/* device filesystem lock */
|
/* device filesystem lock */
|
||||||
@ -37,11 +38,7 @@ static struct rt_mutex fslock;
|
|||||||
char working_directory[DFS_PATH_MAX] = {"/"};
|
char working_directory[DFS_PATH_MAX] = {"/"};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DFS_USING_STDIO
|
|
||||||
struct dfs_fd fd_table[3 + DFS_FD_MAX];
|
|
||||||
#else
|
|
||||||
struct dfs_fd fd_table[DFS_FD_MAX];
|
struct dfs_fd fd_table[DFS_FD_MAX];
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup DFS
|
* @addtogroup DFS
|
||||||
@ -55,23 +52,35 @@ struct dfs_fd fd_table[DFS_FD_MAX];
|
|||||||
int dfs_init(void)
|
int dfs_init(void)
|
||||||
{
|
{
|
||||||
/* clear filesystem operations table */
|
/* clear filesystem operations table */
|
||||||
rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
|
memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
|
||||||
/* clear filesystem table */
|
/* clear filesystem table */
|
||||||
rt_memset(filesystem_table, 0, sizeof(filesystem_table));
|
memset(filesystem_table, 0, sizeof(filesystem_table));
|
||||||
/* clean fd table */
|
/* clean fd table */
|
||||||
rt_memset(fd_table, 0, sizeof(fd_table));
|
memset(fd_table, 0, sizeof(fd_table));
|
||||||
|
|
||||||
/* create device filesystem lock */
|
/* create device filesystem lock */
|
||||||
rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
|
rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
/* set current working directory */
|
/* set current working directory */
|
||||||
rt_memset(working_directory, 0, sizeof(working_directory));
|
memset(working_directory, 0, sizeof(working_directory));
|
||||||
working_directory[0] = '/';
|
working_directory[0] = '/';
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
|
#ifdef RT_USING_DFS_DEVFS
|
||||||
|
{
|
||||||
|
extern int devfs_init(void);
|
||||||
|
|
||||||
|
/* if enable devfs, initialize and mount it as soon as possible */
|
||||||
|
devfs_init();
|
||||||
|
|
||||||
|
dfs_mount(NULL, "/dev", "devfs", 0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_COMPONENT_EXPORT(dfs_init);
|
INIT_PREV_EXPORT(dfs_init);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will lock device file system.
|
* this function will lock device file system.
|
||||||
@ -114,18 +123,10 @@ int fd_new(void)
|
|||||||
dfs_lock();
|
dfs_lock();
|
||||||
|
|
||||||
/* find an empty fd entry */
|
/* find an empty fd entry */
|
||||||
#ifdef DFS_USING_STDIO
|
|
||||||
for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++);
|
|
||||||
#else
|
|
||||||
for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
|
for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* can't find an empty fd entry */
|
/* can't find an empty fd entry */
|
||||||
#ifdef DFS_USING_STDIO
|
|
||||||
if (idx == DFS_FD_MAX + 3)
|
|
||||||
#else
|
|
||||||
if (idx == DFS_FD_MAX)
|
if (idx == DFS_FD_MAX)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
idx = -1;
|
idx = -1;
|
||||||
goto __result;
|
goto __result;
|
||||||
@ -137,7 +138,7 @@ int fd_new(void)
|
|||||||
|
|
||||||
__result:
|
__result:
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return idx;
|
return idx + DFS_FD_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,13 +154,9 @@ struct dfs_fd *fd_get(int fd)
|
|||||||
{
|
{
|
||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
|
||||||
#ifdef DFS_USING_STDIO
|
fd = fd - DFS_FD_OFFSET;
|
||||||
if (fd < 3 || fd >= DFS_FD_MAX + 3)
|
|
||||||
return RT_NULL;
|
|
||||||
#else
|
|
||||||
if (fd < 0 || fd >= DFS_FD_MAX)
|
if (fd < 0 || fd >= DFS_FD_MAX)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
d = &fd_table[fd];
|
d = &fd_table[fd];
|
||||||
@ -168,7 +165,7 @@ struct dfs_fd *fd_get(int fd)
|
|||||||
if (d->magic != DFS_FD_MAGIC)
|
if (d->magic != DFS_FD_MAGIC)
|
||||||
{
|
{
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increase the reference count */
|
/* increase the reference count */
|
||||||
@ -185,7 +182,7 @@ struct dfs_fd *fd_get(int fd)
|
|||||||
*/
|
*/
|
||||||
void fd_put(struct dfs_fd *fd)
|
void fd_put(struct dfs_fd *fd)
|
||||||
{
|
{
|
||||||
RT_ASSERT(fd != RT_NULL);
|
RT_ASSERT(fd != NULL);
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
fd->ref_count --;
|
fd->ref_count --;
|
||||||
@ -193,10 +190,10 @@ void fd_put(struct dfs_fd *fd)
|
|||||||
/* clear this fd entry */
|
/* clear this fd entry */
|
||||||
if (fd->ref_count == 0)
|
if (fd->ref_count == 0)
|
||||||
{
|
{
|
||||||
rt_memset(fd, 0, sizeof(struct dfs_fd));
|
memset(fd, 0, sizeof(struct dfs_fd));
|
||||||
}
|
}
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup Fd
|
* @ingroup Fd
|
||||||
@ -214,15 +211,15 @@ int fd_is_open(const char *pathname)
|
|||||||
struct dfs_filesystem *fs;
|
struct dfs_filesystem *fs;
|
||||||
struct dfs_fd *fd;
|
struct dfs_fd *fd;
|
||||||
|
|
||||||
fullpath = dfs_normalize_path(RT_NULL, pathname);
|
fullpath = dfs_normalize_path(NULL, pathname);
|
||||||
if (fullpath != RT_NULL)
|
if (fullpath != NULL)
|
||||||
{
|
{
|
||||||
char *mountpath;
|
char *mountpath;
|
||||||
fs = dfs_filesystem_lookup(fullpath);
|
fs = dfs_filesystem_lookup(fullpath);
|
||||||
if (fs == RT_NULL)
|
if (fs == NULL)
|
||||||
{
|
{
|
||||||
/* can't find mounted file system */
|
/* can't find mounted file system */
|
||||||
rt_free(fullpath);
|
free(fullpath);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -234,17 +231,14 @@ int fd_is_open(const char *pathname)
|
|||||||
mountpath = fullpath + strlen(fs->path);
|
mountpath = fullpath + strlen(fs->path);
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
#ifdef DFS_USING_STDIO
|
|
||||||
for (index = 3; index < DFS_FD_MAX+3; index++)
|
|
||||||
#else
|
|
||||||
for (index = 0; index < DFS_FD_MAX; index++)
|
for (index = 0; index < DFS_FD_MAX; index++)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
fd = &(fd_table[index]);
|
fd = &(fd_table[index]);
|
||||||
if (fd->fs == RT_NULL)
|
if (fd->fops == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fd->fs == fs && strcmp(fd->path, mountpath) == 0)
|
if (fd->fops == fs->ops->fops && strcmp(fd->path, mountpath) == 0)
|
||||||
{
|
{
|
||||||
/* found file in file descriptor table */
|
/* found file in file descriptor table */
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
@ -274,7 +268,7 @@ const char *dfs_subdir(const char *directory, const char *filename)
|
|||||||
const char *dir;
|
const char *dir;
|
||||||
|
|
||||||
if (strlen(directory) == strlen(filename)) /* it's a same path */
|
if (strlen(directory) == strlen(filename)) /* it's a same path */
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
|
|
||||||
dir = filename + strlen(directory);
|
dir = filename + strlen(directory);
|
||||||
if ((*dir != '/') && (dir != filename))
|
if ((*dir != '/') && (dir != filename))
|
||||||
@ -301,17 +295,17 @@ char *dfs_normalize_path(const char *directory, const char *filename)
|
|||||||
char *dst0, *dst, *src;
|
char *dst0, *dst, *src;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
RT_ASSERT(filename != RT_NULL);
|
RT_ASSERT(filename != NULL);
|
||||||
|
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
if (directory == RT_NULL) /* shall use working directory */
|
if (directory == NULL) /* shall use working directory */
|
||||||
directory = &working_directory[0];
|
directory = &working_directory[0];
|
||||||
#else
|
#else
|
||||||
if ((directory == RT_NULL) && (filename[0] != '/'))
|
if ((directory == NULL) && (filename[0] != '/'))
|
||||||
{
|
{
|
||||||
rt_kprintf(NO_WORKING_DIR);
|
rt_kprintf(NO_WORKING_DIR);
|
||||||
|
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -319,8 +313,8 @@ char *dfs_normalize_path(const char *directory, const char *filename)
|
|||||||
{
|
{
|
||||||
fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
|
fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
|
||||||
|
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
|
|
||||||
/* join path and file name */
|
/* join path and file name */
|
||||||
rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
|
rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
|
||||||
@ -330,8 +324,8 @@ char *dfs_normalize_path(const char *directory, const char *filename)
|
|||||||
{
|
{
|
||||||
fullpath = rt_strdup(filename); /* copy string */
|
fullpath = rt_strdup(filename); /* copy string */
|
||||||
|
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = fullpath;
|
src = fullpath;
|
||||||
@ -396,7 +390,7 @@ up_one:
|
|||||||
if (dst < dst0)
|
if (dst < dst0)
|
||||||
{
|
{
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
while (dst0 < dst && dst[-1] != '/')
|
while (dst0 < dst && dst[-1] != '/')
|
||||||
dst --;
|
dst --;
|
||||||
@ -413,5 +407,37 @@ up_one:
|
|||||||
}
|
}
|
||||||
RTM_EXPORT(dfs_normalize_path);
|
RTM_EXPORT(dfs_normalize_path);
|
||||||
|
|
||||||
|
#include <finsh.h>
|
||||||
|
int list_fd(void)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
rt_enter_critical();
|
||||||
|
|
||||||
|
for (index = 0; index < DFS_FD_MAX; index ++)
|
||||||
|
{
|
||||||
|
struct dfs_fd *fd = &(fd_table[index]);
|
||||||
|
|
||||||
|
if (fd->fops)
|
||||||
|
{
|
||||||
|
rt_kprintf("--fd: %d--", index);
|
||||||
|
if (fd->type == FT_DIRECTORY) rt_kprintf("[dir]\n");
|
||||||
|
if (fd->type == FT_REGULAR) rt_kprintf("[file]\n");
|
||||||
|
if (fd->type == FT_SOCKET) rt_kprintf("[socket]\n");
|
||||||
|
if (fd->type == FT_USER) rt_kprintf("[user]\n");
|
||||||
|
rt_kprintf("refcount=%d\n", fd->ref_count);
|
||||||
|
rt_kprintf("magic=0x%04x\n", fd->magic);
|
||||||
|
if (fd->path)
|
||||||
|
{
|
||||||
|
rt_kprintf("path: %s\n", fd->path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(list_fd, list file descriptor);
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
|
#include <dfs_private.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup FileApi
|
* @addtogroup FileApi
|
||||||
@ -49,44 +50,53 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* parameter check */
|
/* parameter check */
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* make sure we have an absolute path */
|
/* make sure we have an absolute path */
|
||||||
fullpath = dfs_normalize_path(RT_NULL, path);
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
|
dbg_log(DBG_LOG, "open file:%s\n", fullpath);
|
||||||
|
|
||||||
/* find filesystem */
|
/* Check whether file is already open */
|
||||||
fs = dfs_filesystem_lookup(fullpath);
|
if (fd_is_open(fullpath) == 0)
|
||||||
if (fs == RT_NULL)
|
|
||||||
{
|
{
|
||||||
rt_free(fullpath); /* release path */
|
rt_free(fullpath); /* release path */
|
||||||
|
|
||||||
return -DFS_STATUS_ENOENT;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
|
/* find filesystem */
|
||||||
fd->fs = fs;
|
fs = dfs_filesystem_lookup(fullpath);
|
||||||
|
if (fs == NULL)
|
||||||
|
{
|
||||||
|
rt_free(fullpath); /* release path */
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg_log(DBG_LOG, "open in filesystem:%s\n", fs->ops->name);
|
||||||
|
fd->fops = fs->ops->fops; /* set file ops */
|
||||||
|
|
||||||
/* initialize the fd item */
|
/* initialize the fd item */
|
||||||
fd->type = FT_REGULAR;
|
fd->type = FT_REGULAR;
|
||||||
fd->flags = flags;
|
fd->flags = flags;
|
||||||
fd->size = 0;
|
fd->size = 0;
|
||||||
fd->pos = 0;
|
fd->pos = 0;
|
||||||
|
fd->data = fs;
|
||||||
|
|
||||||
if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
|
if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
|
||||||
{
|
{
|
||||||
if (dfs_subdir(fs->path, fullpath) == RT_NULL)
|
if (dfs_subdir(fs->path, fullpath) == NULL)
|
||||||
fd->path = rt_strdup("/");
|
fd->path = rt_strdup("/");
|
||||||
else
|
else
|
||||||
fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
|
fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
dfs_log(DFS_DEBUG_INFO, ("Actual file path: %s\n", fd->path));
|
dbg_log(DBG_LOG, "Actual file path: %s\n", fd->path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -94,34 +104,34 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* specific file system open routine */
|
/* specific file system open routine */
|
||||||
if (fs->ops->open == RT_NULL)
|
if (fd->fops->open == NULL)
|
||||||
{
|
{
|
||||||
/* clear fd */
|
/* clear fd */
|
||||||
rt_free(fd->path);
|
rt_free(fd->path);
|
||||||
fd->path = RT_NULL;
|
fd->path = NULL;
|
||||||
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = fs->ops->open(fd)) < 0)
|
if ((result = fd->fops->open(fd)) < 0)
|
||||||
{
|
{
|
||||||
/* clear fd */
|
/* clear fd */
|
||||||
rt_free(fd->path);
|
rt_free(fd->path);
|
||||||
fd->path = RT_NULL;
|
fd->path = NULL;
|
||||||
|
|
||||||
dfs_log(DFS_DEBUG_INFO, ("open failed"));
|
dbg_log(DBG_ERROR, "open failed\n");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd->flags |= DFS_F_OPEN;
|
fd->flags |= DFS_F_OPEN;
|
||||||
if (flags & DFS_O_DIRECTORY)
|
if (flags & O_DIRECTORY)
|
||||||
{
|
{
|
||||||
fd->type = FT_DIRECTORY;
|
fd->type = FT_DIRECTORY;
|
||||||
fd->flags |= DFS_F_DIRECTORY;
|
fd->flags |= DFS_F_DIRECTORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_log(DFS_DEBUG_INFO, ("open successful"));
|
dbg_log(DBG_INFO, "open successful\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,18 +146,18 @@ int dfs_file_close(struct dfs_fd *fd)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
return -DFS_STATUS_ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (fd != RT_NULL && fd->fs->ops->close != RT_NULL)
|
if (fd->fops->close != NULL)
|
||||||
result = fd->fs->ops->close(fd);
|
result = fd->fops->close(fd);
|
||||||
|
|
||||||
/* close fd error, return */
|
/* close fd error, return */
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
rt_free(fd->path);
|
rt_free(fd->path);
|
||||||
fd->path = RT_NULL;
|
fd->path = NULL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -163,16 +173,13 @@ int dfs_file_close(struct dfs_fd *fd)
|
|||||||
*/
|
*/
|
||||||
int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
|
int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *fs;
|
if (fd == NULL || fd->type != FT_REGULAR)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (fd == RT_NULL || fd->type != FT_REGULAR)
|
if (fd->fops->ioctl != NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return fd->fops->ioctl(fd, cmd, args);
|
||||||
|
|
||||||
fs = fd->fs;
|
return -ENOSYS;
|
||||||
if (fs->ops->ioctl != RT_NULL)
|
|
||||||
return fs->ops->ioctl(fd, cmd, args);
|
|
||||||
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,19 +192,17 @@ int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
|
|||||||
*
|
*
|
||||||
* @return the actual read data bytes or 0 on end of file or failed.
|
* @return the actual read data bytes or 0 on end of file or failed.
|
||||||
*/
|
*/
|
||||||
int dfs_file_read(struct dfs_fd *fd, void *buf, rt_size_t len)
|
int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *fs;
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fs = (struct dfs_filesystem *)fd->fs;
|
if (fd->fops->read == NULL)
|
||||||
if (fs->ops->read == RT_NULL)
|
return -ENOSYS;
|
||||||
return -DFS_STATUS_ENOSYS;
|
|
||||||
|
|
||||||
if ((result = fs->ops->read(fd, buf, len)) < 0)
|
if ((result = fd->fops->read(fd, buf, len)) < 0)
|
||||||
fd->flags |= DFS_F_EOF;
|
fd->flags |= DFS_F_EOF;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -212,19 +217,16 @@ int dfs_file_read(struct dfs_fd *fd, void *buf, rt_size_t len)
|
|||||||
*
|
*
|
||||||
* @return the read dirent, others on failed.
|
* @return the read dirent, others on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, rt_size_t nbytes)
|
int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, size_t nbytes)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *fs;
|
|
||||||
|
|
||||||
/* parameter check */
|
/* parameter check */
|
||||||
if (fd == RT_NULL || fd->type != FT_DIRECTORY)
|
if (fd == NULL || fd->type != FT_DIRECTORY)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fs = (struct dfs_filesystem *)fd->fs;
|
if (fd->fops->getdents != NULL)
|
||||||
if (fs->ops->getdents != RT_NULL)
|
return fd->fops->getdents(fd, dirp, nbytes);
|
||||||
return fs->ops->getdents(fd, dirp, nbytes);
|
|
||||||
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -241,31 +243,31 @@ int dfs_file_unlink(const char *path)
|
|||||||
struct dfs_filesystem *fs;
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
/* Make sure we have an absolute path */
|
/* Make sure we have an absolute path */
|
||||||
fullpath = dfs_normalize_path(RT_NULL, path);
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get filesystem */
|
/* get filesystem */
|
||||||
if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
|
if ((fs = dfs_filesystem_lookup(fullpath)) == NULL)
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_ENOENT;
|
result = -ENOENT;
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether file is already open */
|
/* Check whether file is already open */
|
||||||
if (fd_is_open(fullpath) == 0)
|
if (fd_is_open(fullpath) == 0)
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_EBUSY;
|
result = -EBUSY;
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs->ops->unlink != RT_NULL)
|
if (fs->ops->unlink != NULL)
|
||||||
{
|
{
|
||||||
if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
|
if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
|
||||||
{
|
{
|
||||||
if (dfs_subdir(fs->path, fullpath) == RT_NULL)
|
if (dfs_subdir(fs->path, fullpath) == NULL)
|
||||||
result = fs->ops->unlink(fs, "/");
|
result = fs->ops->unlink(fs, "/");
|
||||||
else
|
else
|
||||||
result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
|
result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
|
||||||
@ -273,7 +275,7 @@ int dfs_file_unlink(const char *path)
|
|||||||
else
|
else
|
||||||
result = fs->ops->unlink(fs, fullpath);
|
result = fs->ops->unlink(fs, fullpath);
|
||||||
}
|
}
|
||||||
else result = -DFS_STATUS_ENOSYS;
|
else result = -ENOSYS;
|
||||||
|
|
||||||
__exit:
|
__exit:
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
@ -289,18 +291,15 @@ __exit:
|
|||||||
*
|
*
|
||||||
* @return the actual written data length.
|
* @return the actual written data length.
|
||||||
*/
|
*/
|
||||||
int dfs_file_write(struct dfs_fd *fd, const void *buf, rt_size_t len)
|
int dfs_file_write(struct dfs_fd *fd, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *fs;
|
if (fd == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (fd == RT_NULL)
|
if (fd->fops->write == NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -ENOSYS;
|
||||||
|
|
||||||
fs = fd->fs;
|
return fd->fops->write(fd, buf, len);
|
||||||
if (fs->ops->write == RT_NULL)
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
|
||||||
|
|
||||||
return fs->ops->write(fd, buf, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -312,16 +311,13 @@ int dfs_file_write(struct dfs_fd *fd, const void *buf, rt_size_t len)
|
|||||||
*/
|
*/
|
||||||
int dfs_file_flush(struct dfs_fd *fd)
|
int dfs_file_flush(struct dfs_fd *fd)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *fs;
|
if (fd == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (fd == RT_NULL)
|
if (fd->fops->flush == NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -ENOSYS;
|
||||||
|
|
||||||
fs = fd->fs;
|
return fd->fops->flush(fd);
|
||||||
if (fs->ops->flush == RT_NULL)
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
|
||||||
|
|
||||||
return fs->ops->flush(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,20 +328,17 @@ int dfs_file_flush(struct dfs_fd *fd)
|
|||||||
*
|
*
|
||||||
* @return the current position after seek.
|
* @return the current position after seek.
|
||||||
*/
|
*/
|
||||||
int dfs_file_lseek(struct dfs_fd *fd, rt_off_t offset)
|
int dfs_file_lseek(struct dfs_fd *fd, off_t offset)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
struct dfs_filesystem *fs = fd->fs;
|
|
||||||
|
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
return -DFS_STATUS_EINVAL;
|
return -EINVAL;
|
||||||
fs = fd->fs;
|
|
||||||
if (fs == RT_NULL)
|
|
||||||
return -DFS_STATUS_EINVAL;
|
|
||||||
if (fs->ops->lseek == RT_NULL)
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
|
||||||
|
|
||||||
result = fs->ops->lseek(fd, offset);
|
if (fd->fops->lseek == NULL)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
result = fd->fops->lseek(fd, offset);
|
||||||
|
|
||||||
/* update current position */
|
/* update current position */
|
||||||
if (result >= 0)
|
if (result >= 0)
|
||||||
@ -368,30 +361,30 @@ int dfs_file_stat(const char *path, struct stat *buf)
|
|||||||
char *fullpath;
|
char *fullpath;
|
||||||
struct dfs_filesystem *fs;
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
fullpath = dfs_normalize_path(RT_NULL, path);
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
|
if ((fs = dfs_filesystem_lookup(fullpath)) == NULL)
|
||||||
{
|
{
|
||||||
dfs_log(DFS_DEBUG_ERROR,
|
dbg_log(DBG_ERROR,
|
||||||
("can't find mounted filesystem on this path:%s", fullpath));
|
"can't find mounted filesystem on this path:%s\n", fullpath);
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
|
|
||||||
return -DFS_STATUS_ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
|
if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
|
||||||
(dfs_subdir(fs->path, fullpath) == RT_NULL))
|
(dfs_subdir(fs->path, fullpath) == NULL))
|
||||||
{
|
{
|
||||||
/* it's the root directory */
|
/* it's the root directory */
|
||||||
buf->st_dev = 0;
|
buf->st_dev = 0;
|
||||||
|
|
||||||
buf->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
|
|
||||||
buf->st_size = 0;
|
buf->st_size = 0;
|
||||||
buf->st_mtime = 0;
|
buf->st_mtime = 0;
|
||||||
@ -399,17 +392,17 @@ int dfs_file_stat(const char *path, struct stat *buf)
|
|||||||
/* release full path */
|
/* release full path */
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fs->ops->stat == RT_NULL)
|
if (fs->ops->stat == NULL)
|
||||||
{
|
{
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
dfs_log(DFS_DEBUG_ERROR,
|
dbg_log(DBG_ERROR,
|
||||||
("the filesystem didn't implement this function"));
|
"the filesystem didn't implement this function\n");
|
||||||
|
|
||||||
return -DFS_STATUS_ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the real file path and get file stat */
|
/* get the real file path and get file stat */
|
||||||
@ -438,21 +431,21 @@ int dfs_file_rename(const char *oldpath, const char *newpath)
|
|||||||
struct dfs_filesystem *oldfs, *newfs;
|
struct dfs_filesystem *oldfs, *newfs;
|
||||||
char *oldfullpath, *newfullpath;
|
char *oldfullpath, *newfullpath;
|
||||||
|
|
||||||
result = DFS_STATUS_OK;
|
result = RT_EOK;
|
||||||
newfullpath = RT_NULL;
|
newfullpath = NULL;
|
||||||
oldfullpath = RT_NULL;
|
oldfullpath = NULL;
|
||||||
|
|
||||||
oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
|
oldfullpath = dfs_normalize_path(NULL, oldpath);
|
||||||
if (oldfullpath == RT_NULL)
|
if (oldfullpath == NULL)
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_ENOENT;
|
result = -ENOENT;
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
newfullpath = dfs_normalize_path(RT_NULL, newpath);
|
newfullpath = dfs_normalize_path(NULL, newpath);
|
||||||
if (newfullpath == RT_NULL)
|
if (newfullpath == NULL)
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_ENOENT;
|
result = -ENOENT;
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,9 +454,9 @@ int dfs_file_rename(const char *oldpath, const char *newpath)
|
|||||||
|
|
||||||
if (oldfs == newfs)
|
if (oldfs == newfs)
|
||||||
{
|
{
|
||||||
if (oldfs->ops->rename == RT_NULL)
|
if (oldfs->ops->rename == NULL)
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_ENOSYS;
|
result = -ENOSYS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -478,7 +471,7 @@ int dfs_file_rename(const char *oldpath, const char *newpath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = -DFS_STATUS_EXDEV;
|
result = -EXDEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
__exit:
|
__exit:
|
||||||
@ -500,8 +493,8 @@ void ls(const char *pathname)
|
|||||||
int length;
|
int length;
|
||||||
char *fullpath, *path;
|
char *fullpath, *path;
|
||||||
|
|
||||||
fullpath = RT_NULL;
|
fullpath = NULL;
|
||||||
if (pathname == RT_NULL)
|
if (pathname == NULL)
|
||||||
{
|
{
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
/* open current working directory */
|
/* open current working directory */
|
||||||
@ -509,7 +502,7 @@ void ls(const char *pathname)
|
|||||||
#else
|
#else
|
||||||
path = rt_strdup("/");
|
path = rt_strdup("/");
|
||||||
#endif
|
#endif
|
||||||
if (path == RT_NULL)
|
if (path == NULL)
|
||||||
return ; /* out of memory */
|
return ; /* out of memory */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -518,26 +511,26 @@ void ls(const char *pathname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* list directory */
|
/* list directory */
|
||||||
if (dfs_file_open(&fd, path, DFS_O_DIRECTORY) == 0)
|
if (dfs_file_open(&fd, path, O_DIRECTORY) == 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("Directory %s:\n", path);
|
rt_kprintf("Directory %s:\n", path);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rt_memset(&dirent, 0, sizeof(struct dirent));
|
memset(&dirent, 0, sizeof(struct dirent));
|
||||||
length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
|
length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
rt_memset(&stat, 0, sizeof(struct stat));
|
memset(&stat, 0, sizeof(struct stat));
|
||||||
|
|
||||||
/* build full path for each file */
|
/* build full path for each file */
|
||||||
fullpath = dfs_normalize_path(path, dirent.d_name);
|
fullpath = dfs_normalize_path(path, dirent.d_name);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dfs_file_stat(fullpath, &stat) == 0)
|
if (dfs_file_stat(fullpath, &stat) == 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("%-20s", dirent.d_name);
|
rt_kprintf("%-20s", dirent.d_name);
|
||||||
if ( DFS_S_ISDIR(stat.st_mode))
|
if (S_ISDIR(stat.st_mode))
|
||||||
{
|
{
|
||||||
rt_kprintf("%-25s\n", "<DIR>");
|
rt_kprintf("%-25s\n", "<DIR>");
|
||||||
}
|
}
|
||||||
@ -558,7 +551,7 @@ void ls(const char *pathname)
|
|||||||
{
|
{
|
||||||
rt_kprintf("No such directory\n");
|
rt_kprintf("No such directory\n");
|
||||||
}
|
}
|
||||||
if (pathname == RT_NULL)
|
if (pathname == NULL)
|
||||||
rt_free(path);
|
rt_free(path);
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(ls, list directory contents);
|
FINSH_FUNCTION_EXPORT(ls, list directory contents);
|
||||||
@ -574,10 +567,10 @@ FINSH_FUNCTION_EXPORT(rm, remove files or directories);
|
|||||||
|
|
||||||
void cat(const char* filename)
|
void cat(const char* filename)
|
||||||
{
|
{
|
||||||
rt_uint32_t length;
|
uint32_t length;
|
||||||
char buffer[81];
|
char buffer[81];
|
||||||
|
|
||||||
if (dfs_file_open(&fd, filename, DFS_O_RDONLY) < 0)
|
if (dfs_file_open(&fd, filename, O_RDONLY) < 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("Open %s failed\n", filename);
|
rt_kprintf("Open %s failed\n", filename);
|
||||||
|
|
||||||
@ -586,7 +579,7 @@ void cat(const char* filename)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rt_memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 );
|
length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 );
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
@ -606,21 +599,21 @@ static void copyfile(const char *src, const char *dst)
|
|||||||
rt_int32_t read_bytes;
|
rt_int32_t read_bytes;
|
||||||
|
|
||||||
block_ptr = rt_malloc(BUF_SZ);
|
block_ptr = rt_malloc(BUF_SZ);
|
||||||
if (block_ptr == RT_NULL)
|
if (block_ptr == NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("out of memory\n");
|
rt_kprintf("out of memory\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dfs_file_open(&src_fd, src, DFS_O_RDONLY) < 0)
|
if (dfs_file_open(&src_fd, src, O_RDONLY) < 0)
|
||||||
{
|
{
|
||||||
rt_free(block_ptr);
|
rt_free(block_ptr);
|
||||||
rt_kprintf("Read %s failed\n", src);
|
rt_kprintf("Read %s failed\n", src);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dfs_file_open(&fd, dst, DFS_O_WRONLY | DFS_O_CREAT) < 0)
|
if (dfs_file_open(&fd, dst, O_WRONLY | O_CREAT) < 0)
|
||||||
{
|
{
|
||||||
rt_free(block_ptr);
|
rt_free(block_ptr);
|
||||||
dfs_file_close(&src_fd);
|
dfs_file_close(&src_fd);
|
||||||
@ -659,7 +652,7 @@ static void copydir(const char * src, const char * dst)
|
|||||||
struct stat stat;
|
struct stat stat;
|
||||||
int length;
|
int length;
|
||||||
struct dfs_fd cpfd;
|
struct dfs_fd cpfd;
|
||||||
if (dfs_file_open(&cpfd, src, DFS_O_DIRECTORY) < 0)
|
if (dfs_file_open(&cpfd, src, O_DIRECTORY) < 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("open %s failed\n", src);
|
rt_kprintf("open %s failed\n", src);
|
||||||
return ;
|
return ;
|
||||||
@ -667,37 +660,38 @@ static void copydir(const char * src, const char * dst)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
rt_memset(&dirent, 0, sizeof(struct dirent));
|
memset(&dirent, 0, sizeof(struct dirent));
|
||||||
|
|
||||||
length = dfs_file_getdents(&cpfd, &dirent, sizeof(struct dirent));
|
length = dfs_file_getdents(&cpfd, &dirent, sizeof(struct dirent));
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
char * src_entry_full = RT_NULL;
|
char * src_entry_full = NULL;
|
||||||
char * dst_entry_full = RT_NULL;
|
char * dst_entry_full = NULL;
|
||||||
|
|
||||||
if (strcmp(dirent.d_name, "..") == 0 || strcmp(dirent.d_name, ".") == 0)
|
if (strcmp(dirent.d_name, "..") == 0 || strcmp(dirent.d_name, ".") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* build full path for each file */
|
/* build full path for each file */
|
||||||
if ((src_entry_full = dfs_normalize_path(src, dirent.d_name)) == RT_NULL)
|
if ((src_entry_full = dfs_normalize_path(src, dirent.d_name)) == NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("out of memory!\n");
|
rt_kprintf("out of memory!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((dst_entry_full = dfs_normalize_path(dst, dirent.d_name)) == RT_NULL)
|
if ((dst_entry_full = dfs_normalize_path(dst, dirent.d_name)) == NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("out of memory!\n");
|
rt_kprintf("out of memory!\n");
|
||||||
rt_free(src_entry_full);
|
rt_free(src_entry_full);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_memset(&stat, 0, sizeof(struct stat));
|
memset(&stat, 0, sizeof(struct stat));
|
||||||
if (dfs_file_stat(src_entry_full, &stat) != 0)
|
if (dfs_file_stat(src_entry_full, &stat) != 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("open file: %s failed\n", dirent.d_name);
|
rt_kprintf("open file: %s failed\n", dirent.d_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DFS_S_ISDIR(stat.st_mode))
|
if (S_ISDIR(stat.st_mode))
|
||||||
{
|
{
|
||||||
mkdir(dst_entry_full, 0);
|
mkdir(dst_entry_full, 0);
|
||||||
copydir(src_entry_full, dst_entry_full);
|
copydir(src_entry_full, dst_entry_full);
|
||||||
@ -717,7 +711,7 @@ static void copydir(const char * src, const char * dst)
|
|||||||
static const char *_get_path_lastname(const char *path)
|
static const char *_get_path_lastname(const char *path)
|
||||||
{
|
{
|
||||||
char * ptr;
|
char * ptr;
|
||||||
if ((ptr = strrchr(path, '/')) == RT_NULL)
|
if ((ptr = strrchr(path, '/')) == NULL)
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
/* skip the '/' then return */
|
/* skip the '/' then return */
|
||||||
@ -736,7 +730,7 @@ void copy(const char *src, const char *dst)
|
|||||||
#define FLAG_DST_NON_EXSIT 0x00
|
#define FLAG_DST_NON_EXSIT 0x00
|
||||||
|
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
rt_uint32_t flag = 0;
|
uint32_t flag = 0;
|
||||||
|
|
||||||
/* check the staus of src and dst */
|
/* check the staus of src and dst */
|
||||||
if (dfs_file_stat(src, &stat) < 0)
|
if (dfs_file_stat(src, &stat) < 0)
|
||||||
@ -744,7 +738,7 @@ void copy(const char *src, const char *dst)
|
|||||||
rt_kprintf("copy failed, bad %s\n", src);
|
rt_kprintf("copy failed, bad %s\n", src);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DFS_S_ISDIR(stat.st_mode))
|
if (S_ISDIR(stat.st_mode))
|
||||||
flag |= FLAG_SRC_IS_DIR;
|
flag |= FLAG_SRC_IS_DIR;
|
||||||
else
|
else
|
||||||
flag |= FLAG_SRC_IS_FILE;
|
flag |= FLAG_SRC_IS_FILE;
|
||||||
@ -755,7 +749,7 @@ void copy(const char *src, const char *dst)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (DFS_S_ISDIR(stat.st_mode))
|
if (S_ISDIR(stat.st_mode))
|
||||||
flag |= FLAG_DST_IS_DIR;
|
flag |= FLAG_DST_IS_DIR;
|
||||||
else
|
else
|
||||||
flag |= FLAG_DST_IS_FILE;
|
flag |= FLAG_DST_IS_FILE;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
|
#include "dfs_private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup FsApi
|
* @addtogroup FsApi
|
||||||
@ -37,13 +38,13 @@
|
|||||||
*
|
*
|
||||||
* @param ops the file system instance to be registered.
|
* @param ops the file system instance to be registered.
|
||||||
*
|
*
|
||||||
* @return RT_EOK on successful, -RT_ERROR on failed.
|
* @return 0 on successful, -1 on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_register(const struct dfs_filesystem_operation *ops)
|
int dfs_register(const struct dfs_filesystem_ops *ops)
|
||||||
{
|
{
|
||||||
int ret = RT_EOK;
|
int ret = RT_EOK;
|
||||||
const struct dfs_filesystem_operation **empty = RT_NULL;
|
const struct dfs_filesystem_ops **empty = NULL;
|
||||||
const struct dfs_filesystem_operation **iter;
|
const struct dfs_filesystem_ops **iter;
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
@ -52,18 +53,26 @@ int dfs_register(const struct dfs_filesystem_operation *ops)
|
|||||||
iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++)
|
iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++)
|
||||||
{
|
{
|
||||||
/* find out an empty filesystem type entry */
|
/* find out an empty filesystem type entry */
|
||||||
if (*iter == RT_NULL)
|
if (*iter == NULL)
|
||||||
(empty == RT_NULL) ? (empty = iter) : 0;
|
(empty == NULL) ? (empty = iter) : 0;
|
||||||
else if (strcmp((*iter)->name, ops->name) == 0)
|
else if (strcmp((*iter)->name, ops->name) == 0)
|
||||||
{
|
{
|
||||||
|
rt_set_errno(-EEXIST);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the filesystem's operations */
|
/* save the filesystem's operations */
|
||||||
if ((ret == RT_EOK) && (empty != RT_NULL))
|
if (empty == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-ENOSPC);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
else if (ret == RT_EOK)
|
||||||
|
{
|
||||||
*empty = ops;
|
*empty = ops;
|
||||||
|
}
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
@ -80,8 +89,8 @@ int dfs_register(const struct dfs_filesystem_operation *ops)
|
|||||||
struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
|
struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem *iter;
|
struct dfs_filesystem *iter;
|
||||||
struct dfs_filesystem *fs = RT_NULL;
|
struct dfs_filesystem *fs = NULL;
|
||||||
rt_uint32_t fspath, prefixlen;
|
uint32_t fspath, prefixlen;
|
||||||
|
|
||||||
prefixlen = 0;
|
prefixlen = 0;
|
||||||
|
|
||||||
@ -94,7 +103,7 @@ struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
|
|||||||
for (iter = &filesystem_table[0];
|
for (iter = &filesystem_table[0];
|
||||||
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
{
|
{
|
||||||
if ((iter->path == RT_NULL) || (iter->ops == RT_NULL))
|
if ((iter->path == NULL) || (iter->ops == NULL))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fspath = strlen(iter->path);
|
fspath = strlen(iter->path);
|
||||||
@ -116,34 +125,34 @@ struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will return the mounted path for specified device.
|
* this function will return the mounted path for specified device.
|
||||||
*
|
*
|
||||||
* @param device the device object which is mounted.
|
* @param device the device object which is mounted.
|
||||||
*
|
*
|
||||||
* @return the mounted path or RT_NULL if none device mounted.
|
* @return the mounted path or NULL if none device mounted.
|
||||||
*/
|
*/
|
||||||
const char* dfs_filesystem_get_mounted_path(struct rt_device* device)
|
const char* dfs_filesystem_get_mounted_path(struct rt_device* device)
|
||||||
{
|
{
|
||||||
const char* path = RT_NULL;
|
const char* path = NULL;
|
||||||
struct dfs_filesystem *iter;
|
struct dfs_filesystem *iter;
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
for (iter = &filesystem_table[0];
|
for (iter = &filesystem_table[0];
|
||||||
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
{
|
{
|
||||||
/* fint the mounted device */
|
/* fint the mounted device */
|
||||||
if (iter->ops == RT_NULL) continue;
|
if (iter->ops == NULL) continue;
|
||||||
else if (iter->dev_id == device)
|
else if (iter->dev_id == device)
|
||||||
{
|
{
|
||||||
path = iter->path;
|
path = iter->path;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release filesystem_table lock */
|
/* release filesystem_table lock */
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,29 +164,29 @@ const char* dfs_filesystem_get_mounted_path(struct rt_device* device)
|
|||||||
*
|
*
|
||||||
* @return RT_EOK on successful or -RT_ERROR on failed.
|
* @return RT_EOK on successful or -RT_ERROR on failed.
|
||||||
*/
|
*/
|
||||||
rt_err_t dfs_filesystem_get_partition(struct dfs_partition *part,
|
int dfs_filesystem_get_partition(struct dfs_partition *part,
|
||||||
rt_uint8_t *buf,
|
uint8_t *buf,
|
||||||
rt_uint32_t pindex)
|
uint32_t pindex)
|
||||||
{
|
{
|
||||||
#define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */
|
#define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */
|
||||||
#define DPT_ITEM_SIZE 16 /* partition item size */
|
#define DPT_ITEM_SIZE 16 /* partition item size */
|
||||||
|
|
||||||
rt_uint8_t *dpt;
|
uint8_t *dpt;
|
||||||
rt_uint8_t type;
|
uint8_t type;
|
||||||
|
|
||||||
RT_ASSERT(part != RT_NULL);
|
RT_ASSERT(part != NULL);
|
||||||
RT_ASSERT(buf != RT_NULL);
|
RT_ASSERT(buf != NULL);
|
||||||
|
|
||||||
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
|
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
|
||||||
|
|
||||||
/* check if it is a valid partition table */
|
/* check if it is a valid partition table */
|
||||||
if ((*dpt != 0x80) && (*dpt != 0x00))
|
if ((*dpt != 0x80) && (*dpt != 0x00))
|
||||||
return -RT_ERROR;
|
return -EIO;
|
||||||
|
|
||||||
/* get partition type */
|
/* get partition type */
|
||||||
type = *(dpt+4);
|
type = *(dpt+4);
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
return -RT_ERROR;
|
return -EIO;
|
||||||
|
|
||||||
/* set partition information
|
/* set partition information
|
||||||
* size is the number of 512-Byte */
|
* size is the number of 512-Byte */
|
||||||
@ -219,22 +228,22 @@ int dfs_mount(const char *device_name,
|
|||||||
unsigned long rwflag,
|
unsigned long rwflag,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
const struct dfs_filesystem_operation **ops;
|
const struct dfs_filesystem_ops **ops;
|
||||||
struct dfs_filesystem *iter;
|
struct dfs_filesystem *iter;
|
||||||
struct dfs_filesystem *fs = RT_NULL;
|
struct dfs_filesystem *fs = NULL;
|
||||||
char *fullpath = RT_NULL;
|
char *fullpath = NULL;
|
||||||
rt_device_t dev_id;
|
rt_device_t dev_id;
|
||||||
|
|
||||||
/* open specific device */
|
/* open specific device */
|
||||||
if (device_name == RT_NULL)
|
if (device_name == NULL)
|
||||||
{
|
{
|
||||||
/* which is a non-device filesystem mount */
|
/* which is a non-device filesystem mount */
|
||||||
dev_id = NULL;
|
dev_id = NULL;
|
||||||
}
|
}
|
||||||
else if ((dev_id = rt_device_find(device_name)) == RT_NULL)
|
else if ((dev_id = rt_device_find(device_name)) == NULL)
|
||||||
{
|
{
|
||||||
/* no this device */
|
/* no this device */
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-ENODEV);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +252,7 @@ int dfs_mount(const char *device_name,
|
|||||||
|
|
||||||
for (ops = &filesystem_operation_table[0];
|
for (ops = &filesystem_operation_table[0];
|
||||||
ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
|
ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
|
||||||
if ((ops != RT_NULL) && (strcmp((*ops)->name, filesystemtype) == 0))
|
if ((ops != NULL) && (strcmp((*ops)->name, filesystemtype) == 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
@ -251,22 +260,22 @@ int dfs_mount(const char *device_name,
|
|||||||
if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
|
if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
|
||||||
{
|
{
|
||||||
/* can't find filesystem */
|
/* can't find filesystem */
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-ENODEV);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if there is mount implementation */
|
/* check if there is mount implementation */
|
||||||
if ((*ops == NULL) || ((*ops)->mount == NULL))
|
if ((*ops == NULL) || ((*ops)->mount == NULL))
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOSYS);
|
rt_set_errno(-ENOSYS);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make full path for special file */
|
/* make full path for special file */
|
||||||
fullpath = dfs_normalize_path(RT_NULL, path);
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
if (fullpath == RT_NULL) /* not an abstract path */
|
if (fullpath == NULL) /* not an abstract path */
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-ENOTDIR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,10 +284,10 @@ int dfs_mount(const char *device_name,
|
|||||||
{
|
{
|
||||||
struct dfs_fd fd;
|
struct dfs_fd fd;
|
||||||
|
|
||||||
if (dfs_file_open(&fd, fullpath, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0)
|
if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0)
|
||||||
{
|
{
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -293,19 +302,19 @@ int dfs_mount(const char *device_name,
|
|||||||
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
|
||||||
{
|
{
|
||||||
/* check if it is an empty filesystem table entry? if it is, save fs */
|
/* check if it is an empty filesystem table entry? if it is, save fs */
|
||||||
if (iter->ops == RT_NULL)
|
if (iter->ops == NULL)
|
||||||
(fs == RT_NULL) ? (fs = iter) : 0;
|
(fs == NULL) ? (fs = iter) : 0;
|
||||||
/* check if the PATH is mounted */
|
/* check if the PATH is mounted */
|
||||||
else if (strcmp(iter->path, path) == 0)
|
else if (strcmp(iter->path, path) == 0)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
rt_set_errno(-EINVAL);
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fs == RT_NULL) && (iter == &filesystem_table[DFS_FILESYSTEMS_MAX]))
|
if ((fs == NULL) && (iter == &filesystem_table[DFS_FILESYSTEMS_MAX]))
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOSPC);
|
rt_set_errno(-ENOSPC);
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,14 +326,15 @@ int dfs_mount(const char *device_name,
|
|||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
/* open device, but do not check the status of device */
|
/* open device, but do not check the status of device */
|
||||||
if (dev_id != RT_NULL)
|
if (dev_id != NULL)
|
||||||
{
|
{
|
||||||
if (rt_device_open(fs->dev_id,
|
if (rt_device_open(fs->dev_id,
|
||||||
RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
RT_DEVICE_OFLAG_RDWR) != RT_EOK)
|
||||||
{
|
{
|
||||||
/* The underlaying device has error, clear the entry. */
|
/* The underlaying device has error, clear the entry. */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,13 +343,14 @@ int dfs_mount(const char *device_name,
|
|||||||
if ((*ops)->mount(fs, rwflag, data) < 0)
|
if ((*ops)->mount(fs, rwflag, data) < 0)
|
||||||
{
|
{
|
||||||
/* close device */
|
/* close device */
|
||||||
if (dev_id != RT_NULL)
|
if (dev_id != NULL)
|
||||||
rt_device_close(fs->dev_id);
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
/* mount failed */
|
/* mount failed */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
/* clear filesystem table entry */
|
/* clear filesystem table entry */
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,12 +374,12 @@ int dfs_unmount(const char *specialfile)
|
|||||||
{
|
{
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
struct dfs_filesystem *iter;
|
struct dfs_filesystem *iter;
|
||||||
struct dfs_filesystem *fs = RT_NULL;
|
struct dfs_filesystem *fs = NULL;
|
||||||
|
|
||||||
fullpath = dfs_normalize_path(RT_NULL, specialfile);
|
fullpath = dfs_normalize_path(NULL, specialfile);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -387,22 +398,22 @@ int dfs_unmount(const char *specialfile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs == RT_NULL ||
|
if (fs == NULL ||
|
||||||
fs->ops->unmount == RT_NULL ||
|
fs->ops->unmount == NULL ||
|
||||||
fs->ops->unmount(fs) < 0)
|
fs->ops->unmount(fs) < 0)
|
||||||
{
|
{
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close device, but do not check the status of device */
|
/* close device, but do not check the status of device */
|
||||||
if (fs->dev_id != RT_NULL)
|
if (fs->dev_id != NULL)
|
||||||
rt_device_close(fs->dev_id);
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
if (fs->path != RT_NULL)
|
if (fs->path != NULL)
|
||||||
rt_free(fs->path);
|
rt_free(fs->path);
|
||||||
|
|
||||||
/* clear this filesystem table entry */
|
/* clear this filesystem table entry */
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
@ -427,15 +438,15 @@ err1:
|
|||||||
int dfs_mkfs(const char *fs_name, const char *device_name)
|
int dfs_mkfs(const char *fs_name, const char *device_name)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
rt_device_t dev_id = RT_NULL;
|
rt_device_t dev_id = NULL;
|
||||||
|
|
||||||
/* check device name, and it should not be NULL */
|
/* check device name, and it should not be NULL */
|
||||||
if (device_name != RT_NULL)
|
if (device_name != NULL)
|
||||||
dev_id = rt_device_find(device_name);
|
dev_id = rt_device_find(device_name);
|
||||||
|
|
||||||
if (dev_id == RT_NULL)
|
if (dev_id == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-ENODEV);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +455,7 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
|
|||||||
/* find the file system operations */
|
/* find the file system operations */
|
||||||
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++)
|
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++)
|
||||||
{
|
{
|
||||||
if (filesystem_operation_table[index] != RT_NULL &&
|
if (filesystem_operation_table[index] != NULL &&
|
||||||
strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
|
strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -453,10 +464,10 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
|
|||||||
if (index < DFS_FILESYSTEM_TYPES_MAX)
|
if (index < DFS_FILESYSTEM_TYPES_MAX)
|
||||||
{
|
{
|
||||||
/* find file system operation */
|
/* find file system operation */
|
||||||
const struct dfs_filesystem_operation *ops = filesystem_operation_table[index];
|
const struct dfs_filesystem_ops *ops = filesystem_operation_table[index];
|
||||||
if (ops->mkfs == RT_NULL)
|
if (ops->mkfs == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOSYS);
|
rt_set_errno(-ENOSYS);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,9 +491,9 @@ int dfs_statfs(const char *path, struct statfs *buffer)
|
|||||||
struct dfs_filesystem *fs;
|
struct dfs_filesystem *fs;
|
||||||
|
|
||||||
fs = dfs_filesystem_lookup(path);
|
fs = dfs_filesystem_lookup(path);
|
||||||
if (fs != RT_NULL)
|
if (fs != NULL)
|
||||||
{
|
{
|
||||||
if (fs->ops->statfs != RT_NULL)
|
if (fs->ops->statfs != NULL)
|
||||||
return fs->ops->statfs(fs, buffer);
|
return fs->ops->statfs(fs, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,26 +503,26 @@ int dfs_statfs(const char *path, struct statfs *buffer)
|
|||||||
#ifdef RT_USING_DFS_MNTTABLE
|
#ifdef RT_USING_DFS_MNTTABLE
|
||||||
int dfs_mount_table(void)
|
int dfs_mount_table(void)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (mount_table[index].path == RT_NULL) break;
|
if (mount_table[index].path == NULL) break;
|
||||||
|
|
||||||
if (dfs_mount(mount_table[index].device_name,
|
if (dfs_mount(mount_table[index].device_name,
|
||||||
mount_table[index].path,
|
mount_table[index].path,
|
||||||
mount_table[index].filesystemtype,
|
mount_table[index].filesystemtype,
|
||||||
mount_table[index].rwflag,
|
mount_table[index].rwflag,
|
||||||
mount_table[index].data) != 0)
|
mount_table[index].data) != 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
|
rt_kprintf("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
|
||||||
mount_table[index].path);
|
mount_table[index].path);
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
index ++;
|
index ++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_ENV_EXPORT(dfs_mount_table);
|
INIT_ENV_EXPORT(dfs_mount_table);
|
||||||
#endif
|
#endif
|
||||||
@ -530,7 +541,7 @@ int df(const char *path)
|
|||||||
long long cap;
|
long long cap;
|
||||||
struct statfs buffer;
|
struct statfs buffer;
|
||||||
|
|
||||||
result = dfs_statfs(path ? path : RT_NULL, &buffer);
|
result = dfs_statfs(path ? path : NULL, &buffer);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("dfs_statfs failed.\n");
|
rt_kprintf("dfs_statfs failed.\n");
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
|
#include "dfs_private.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup FsPosixApi
|
* @addtogroup FsPosixApi
|
||||||
@ -50,7 +51,7 @@ int open(const char *file, int flags, int mode)
|
|||||||
fd = fd_new();
|
fd = fd_new();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -89,9 +90,9 @@ int close(int fd)
|
|||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -134,9 +135,9 @@ int read(int fd, void *buf, size_t len)
|
|||||||
|
|
||||||
/* get the fd */
|
/* get the fd */
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -178,9 +179,9 @@ int write(int fd, const void *buf, size_t len)
|
|||||||
|
|
||||||
/* get the fd */
|
/* get the fd */
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -217,29 +218,29 @@ off_t lseek(int fd, off_t offset, int whence)
|
|||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case DFS_SEEK_SET:
|
case SEEK_SET:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DFS_SEEK_CUR:
|
case SEEK_CUR:
|
||||||
offset += d->pos;
|
offset += d->pos;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DFS_SEEK_END:
|
case SEEK_END:
|
||||||
offset += d->size;
|
offset += d->size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
rt_set_errno(-EINVAL);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -247,7 +248,7 @@ off_t lseek(int fd, off_t offset, int whence)
|
|||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
{
|
{
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
rt_set_errno(-EINVAL);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -357,9 +358,9 @@ int fstat(int fildes, struct stat *buf)
|
|||||||
|
|
||||||
/* get the fd */
|
/* get the fd */
|
||||||
d = fd_get(fildes);
|
d = fd_get(fildes);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -367,12 +368,12 @@ int fstat(int fildes, struct stat *buf)
|
|||||||
/* it's the root directory */
|
/* it's the root directory */
|
||||||
buf->st_dev = 0;
|
buf->st_dev = 0;
|
||||||
|
|
||||||
buf->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
if (d->type == FT_DIRECTORY)
|
if (d->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
buf->st_mode &= ~DFS_S_IFREG;
|
buf->st_mode &= ~S_IFREG;
|
||||||
buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->st_size = d->size;
|
buf->st_size = d->size;
|
||||||
@ -380,7 +381,7 @@ int fstat(int fildes, struct stat *buf)
|
|||||||
|
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
|
|
||||||
return DFS_STATUS_OK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(fstat);
|
RTM_EXPORT(fstat);
|
||||||
#endif
|
#endif
|
||||||
@ -402,9 +403,9 @@ int fsync(int fildes)
|
|||||||
|
|
||||||
/* get the fd */
|
/* get the fd */
|
||||||
d = fd_get(fildes);
|
d = fd_get(fildes);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,28 +428,28 @@ RTM_EXPORT(fsync);
|
|||||||
* @return 0 on successful completion. Otherwise, -1 shall be returned and errno
|
* @return 0 on successful completion. Otherwise, -1 shall be returned and errno
|
||||||
* set to indicate the error.
|
* set to indicate the error.
|
||||||
*/
|
*/
|
||||||
int ioctl(int fildes, long cmd, void *data)
|
int ioctl(int fildes, int cmd, void *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct dfs_fd *d;
|
struct dfs_fd *d;
|
||||||
|
|
||||||
/* get the fd */
|
/* get the fd */
|
||||||
d = fd_get(fildes);
|
d = fd_get(fildes);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dfs_file_ioctl(d, cmd, data);
|
ret = dfs_file_ioctl(d, cmd, data);
|
||||||
if (ret != DFS_STATUS_OK)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
rt_set_errno(ret);
|
rt_set_errno(ret);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(ioctl);
|
RTM_EXPORT(ioctl);
|
||||||
|
|
||||||
@ -494,14 +495,14 @@ int mkdir(const char *path, mode_t mode)
|
|||||||
fd = fd_new();
|
fd = fd_new();
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
|
|
||||||
result = dfs_file_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT);
|
result = dfs_file_open(d, path, O_DIRECTORY | O_CREAT);
|
||||||
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
@ -561,31 +562,32 @@ DIR *opendir(const char *name)
|
|||||||
int fd, result;
|
int fd, result;
|
||||||
DIR *t;
|
DIR *t;
|
||||||
|
|
||||||
t = RT_NULL;
|
t = NULL;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* allocate a fd */
|
||||||
fd = fd_new();
|
fd = fd_new();
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOMEM);
|
rt_set_errno(-ENOMEM);
|
||||||
|
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
d = fd_get(fd);
|
d = fd_get(fd);
|
||||||
|
|
||||||
result = dfs_file_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY);
|
result = dfs_file_open(d, name, O_RDONLY | O_DIRECTORY);
|
||||||
if (result >= 0)
|
if (result >= 0)
|
||||||
{
|
{
|
||||||
/* open successfully */
|
/* open successfully */
|
||||||
t = (DIR *) rt_malloc(sizeof(DIR));
|
t = (DIR *) rt_malloc(sizeof(DIR));
|
||||||
if (t == RT_NULL)
|
if (t == NULL)
|
||||||
{
|
{
|
||||||
dfs_file_close(d);
|
dfs_file_close(d);
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_memset(t, 0, sizeof(DIR));
|
memset(t, 0, sizeof(DIR));
|
||||||
|
|
||||||
t->fd = fd;
|
t->fd = fd;
|
||||||
}
|
}
|
||||||
fd_put(d);
|
fd_put(d);
|
||||||
@ -598,7 +600,7 @@ DIR *opendir(const char *name)
|
|||||||
fd_put(d);
|
fd_put(d);
|
||||||
rt_set_errno(result);
|
rt_set_errno(result);
|
||||||
|
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
RTM_EXPORT(opendir);
|
RTM_EXPORT(opendir);
|
||||||
|
|
||||||
@ -617,10 +619,10 @@ struct dirent *readdir(DIR *d)
|
|||||||
struct dfs_fd *fd;
|
struct dfs_fd *fd;
|
||||||
|
|
||||||
fd = fd_get(d->fd);
|
fd = fd_get(d->fd);
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->num)
|
if (d->num)
|
||||||
@ -641,7 +643,7 @@ struct dirent *readdir(DIR *d)
|
|||||||
fd_put(fd);
|
fd_put(fd);
|
||||||
rt_set_errno(result);
|
rt_set_errno(result);
|
||||||
|
|
||||||
return RT_NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->num = result;
|
d->num = result;
|
||||||
@ -668,9 +670,9 @@ long telldir(DIR *d)
|
|||||||
long result;
|
long result;
|
||||||
|
|
||||||
fd = fd_get(d->fd);
|
fd = fd_get(d->fd);
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -694,9 +696,9 @@ void seekdir(DIR *d, off_t offset)
|
|||||||
struct dfs_fd *fd;
|
struct dfs_fd *fd;
|
||||||
|
|
||||||
fd = fd_get(d->fd);
|
fd = fd_get(d->fd);
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
@ -719,9 +721,9 @@ void rewinddir(DIR *d)
|
|||||||
struct dfs_fd *fd;
|
struct dfs_fd *fd;
|
||||||
|
|
||||||
fd = fd_get(d->fd);
|
fd = fd_get(d->fd);
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
@ -747,9 +749,9 @@ int closedir(DIR *d)
|
|||||||
struct dfs_fd *fd;
|
struct dfs_fd *fd;
|
||||||
|
|
||||||
fd = fd_get(d->fd);
|
fd = fd_get(d->fd);
|
||||||
if (fd == RT_NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EBADF);
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -785,7 +787,7 @@ int chdir(const char *path)
|
|||||||
char *fullpath;
|
char *fullpath;
|
||||||
DIR *d;
|
DIR *d;
|
||||||
|
|
||||||
if (path == RT_NULL)
|
if (path == NULL)
|
||||||
{
|
{
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
rt_kprintf("%s\n", working_directory);
|
rt_kprintf("%s\n", working_directory);
|
||||||
@ -794,24 +796,24 @@ int chdir(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt_strlen(path) > DFS_PATH_MAX)
|
if (strlen(path) > DFS_PATH_MAX)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fullpath = dfs_normalize_path(NULL, path);
|
fullpath = dfs_normalize_path(NULL, path);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-ENOTDIR);
|
||||||
|
|
||||||
return -1; /* build path failed */
|
return -1; /* build path failed */
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
d = opendir(fullpath);
|
d = opendir(fullpath);
|
||||||
if (d == RT_NULL)
|
if (d == NULL)
|
||||||
{
|
{
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
/* this is a not exist directory */
|
/* this is a not exist directory */
|
||||||
@ -839,6 +841,25 @@ FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function is a POSIX compliant version, which shall check the file named
|
||||||
|
* by the pathname pointed to by the path argument for accessibility according
|
||||||
|
* to the bit pattern contained in amode.
|
||||||
|
*
|
||||||
|
* @param path the specified file/dir path.
|
||||||
|
* @param amode the value is either the bitwise-inclusive OR of the access
|
||||||
|
* permissions to be checked (R_OK, W_OK, X_OK) or the existence test (F_OK).
|
||||||
|
*/
|
||||||
|
int access(const char *path, int amode)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(path, &sb) < 0)
|
||||||
|
return -1; /* already sets errno */
|
||||||
|
|
||||||
|
/* ignore R_OK,W_OK,X_OK condition */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function is a POSIX compliant version, which will return current
|
* this function is a POSIX compliant version, which will return current
|
||||||
* working directory.
|
* working directory.
|
||||||
@ -852,7 +873,7 @@ char *getcwd(char *buf, size_t size)
|
|||||||
{
|
{
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
rt_enter_critical();
|
rt_enter_critical();
|
||||||
rt_strncpy(buf, working_directory, size);
|
strncpy(buf, working_directory, size);
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
#else
|
#else
|
||||||
rt_kprintf(NO_WORKING_DIR);
|
rt_kprintf(NO_WORKING_DIR);
|
||||||
|
227
components/dfs/src/poll.c
Normal file
227
components/dfs/src/poll.c
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/*
|
||||||
|
* File : poll.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2016-12-28 Bernard first version
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_file.h>
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
|
struct rt_poll_node;
|
||||||
|
|
||||||
|
struct rt_poll_table
|
||||||
|
{
|
||||||
|
rt_pollreq_t req;
|
||||||
|
rt_uint32_t triggered; /* the waited thread whether triggered */
|
||||||
|
rt_thread_t polling_thread;
|
||||||
|
struct rt_poll_node *nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_poll_node
|
||||||
|
{
|
||||||
|
struct rt_wqueue_node wqn;
|
||||||
|
struct rt_poll_table *pt;
|
||||||
|
struct rt_poll_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __wqueue_pollwake(struct rt_wqueue_node *wait, void *key)
|
||||||
|
{
|
||||||
|
struct rt_poll_node *pn;
|
||||||
|
|
||||||
|
if (key && !((rt_uint32_t)key & wait->key))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pn = rt_container_of(wait, struct rt_poll_node, wqn);
|
||||||
|
pn->pt->triggered = 1;
|
||||||
|
|
||||||
|
return __wqueue_default_wake(wait, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req)
|
||||||
|
{
|
||||||
|
struct rt_poll_table *pt;
|
||||||
|
struct rt_poll_node *node;
|
||||||
|
|
||||||
|
node = rt_malloc(sizeof(struct rt_poll_node));
|
||||||
|
if (node == RT_NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pt = rt_container_of(req, struct rt_poll_table, req);
|
||||||
|
|
||||||
|
node->wqn.key = req->_key;
|
||||||
|
rt_list_init(&(node->wqn.list));
|
||||||
|
node->wqn.polling_thread = pt->polling_thread;
|
||||||
|
node->wqn.wakeup = __wqueue_pollwake;
|
||||||
|
node->next = pt->nodes;
|
||||||
|
node->pt = pt;
|
||||||
|
pt->nodes = node;
|
||||||
|
rt_wqueue_add(wq, &node->wqn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void poll_table_init(struct rt_poll_table *pt)
|
||||||
|
{
|
||||||
|
pt->req._proc = _poll_add;
|
||||||
|
pt->triggered = 0;
|
||||||
|
pt->nodes = RT_NULL;
|
||||||
|
pt->polling_thread = rt_thread_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int poll_wait_timeout(struct rt_poll_table *pt, int msec)
|
||||||
|
{
|
||||||
|
rt_int32_t timeout;
|
||||||
|
int ret = 0;
|
||||||
|
struct rt_thread *thread;
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
|
thread = pt->polling_thread;
|
||||||
|
|
||||||
|
timeout = rt_tick_from_millisecond(msec);
|
||||||
|
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
if (timeout != 0 && !pt->triggered)
|
||||||
|
{
|
||||||
|
rt_thread_suspend(thread);
|
||||||
|
if (timeout > 0)
|
||||||
|
{
|
||||||
|
rt_timer_control(&(thread->thread_timer),
|
||||||
|
RT_TIMER_CTRL_SET_TIME,
|
||||||
|
&timeout);
|
||||||
|
rt_timer_start(&(thread->thread_timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
rt_schedule();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = !pt->triggered;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_pollfd(struct pollfd *pollfd, rt_pollreq_t *req)
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = pollfd->fd;
|
||||||
|
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
struct dfs_fd *f = fd_get(fd);
|
||||||
|
mask = POLLNVAL;
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
mask = POLLMASK_DEFAULT;
|
||||||
|
if (f->fops->poll)
|
||||||
|
{
|
||||||
|
req->_key = pollfd->events | POLLERR| POLLHUP;
|
||||||
|
|
||||||
|
mask = f->fops->poll(f, req);
|
||||||
|
}
|
||||||
|
/* Mask out unneeded events. */
|
||||||
|
mask &= pollfd->events | POLLERR | POLLHUP;
|
||||||
|
fd_put(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pollfd->revents = mask;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int poll_do(struct pollfd *fds, nfds_t nfds, struct rt_poll_table *pt, int msec)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
int istimeout = 0;
|
||||||
|
int n;
|
||||||
|
struct pollfd *pf;
|
||||||
|
|
||||||
|
if (msec == 0)
|
||||||
|
{
|
||||||
|
pt->req._proc = RT_NULL;
|
||||||
|
istimeout = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pf = fds;
|
||||||
|
num = 0;
|
||||||
|
|
||||||
|
for (n = 0; n < nfds; n ++)
|
||||||
|
{
|
||||||
|
if (do_pollfd(pf, &pt->req))
|
||||||
|
{
|
||||||
|
num ++;
|
||||||
|
pt->req._proc = RT_NULL;
|
||||||
|
}
|
||||||
|
pf ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt->req._proc = RT_NULL;
|
||||||
|
|
||||||
|
if (num || istimeout)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (poll_wait_timeout(pt, msec))
|
||||||
|
istimeout = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void poll_teardown(struct rt_poll_table *pt)
|
||||||
|
{
|
||||||
|
struct rt_poll_node *node, *next;
|
||||||
|
|
||||||
|
next = pt->nodes;
|
||||||
|
while (next)
|
||||||
|
{
|
||||||
|
node = next;
|
||||||
|
rt_wqueue_remove(&node->wqn);
|
||||||
|
next = node->next;
|
||||||
|
rt_free(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
struct rt_poll_table table;
|
||||||
|
|
||||||
|
poll_table_init(&table);
|
||||||
|
|
||||||
|
num = poll_do(fds, nfds, &table, timeout);
|
||||||
|
|
||||||
|
poll_teardown(&table);
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
174
components/dfs/src/select.c
Normal file
174
components/dfs/src/select.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* File : select.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2016-12-28 Bernard first version
|
||||||
|
*/
|
||||||
|
#include <dfs.h>
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
#include <dfs_posix.h>
|
||||||
|
|
||||||
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int npfds;
|
||||||
|
int msec;
|
||||||
|
int ndx;
|
||||||
|
int ret;
|
||||||
|
struct pollfd *pollset = RT_NULL;
|
||||||
|
|
||||||
|
/* How many pollfd structures do we need to allocate? */
|
||||||
|
for (fd = 0, npfds = 0; fd < nfds; fd++)
|
||||||
|
{
|
||||||
|
/* Check if any monitor operation is requested on this fd */
|
||||||
|
if ((readfds && FD_ISSET(fd, readfds)) ||
|
||||||
|
(writefds && FD_ISSET(fd, writefds)) ||
|
||||||
|
(exceptfds && FD_ISSET(fd, exceptfds)))
|
||||||
|
{
|
||||||
|
npfds++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the descriptor list for poll() */
|
||||||
|
if (npfds > 0)
|
||||||
|
{
|
||||||
|
pollset = (struct pollfd *)rt_malloc(npfds * sizeof(struct pollfd));
|
||||||
|
if (!pollset)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the descriptor list for poll() */
|
||||||
|
for (fd = 0, ndx = 0; fd < nfds; fd++)
|
||||||
|
{
|
||||||
|
int incr = 0;
|
||||||
|
|
||||||
|
/* The readfs set holds the set of FDs that the caller can be assured
|
||||||
|
* of reading from without blocking. Note that POLLHUP is included as
|
||||||
|
* a read-able condition. POLLHUP will be reported at the end-of-file
|
||||||
|
* or when a connection is lost. In either case, the read() can then
|
||||||
|
* be performed without blocking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (readfds && FD_ISSET(fd, readfds))
|
||||||
|
{
|
||||||
|
pollset[ndx].fd = fd;
|
||||||
|
pollset[ndx].events |= POLLIN;
|
||||||
|
incr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writefds && FD_ISSET(fd, writefds))
|
||||||
|
{
|
||||||
|
pollset[ndx].fd = fd;
|
||||||
|
pollset[ndx].events |= POLLOUT;
|
||||||
|
incr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceptfds && FD_ISSET(fd, exceptfds))
|
||||||
|
{
|
||||||
|
pollset[ndx].fd = fd;
|
||||||
|
incr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndx += incr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_ASSERT(ndx == npfds);
|
||||||
|
|
||||||
|
/* Convert the timeout to milliseconds */
|
||||||
|
if (timeout)
|
||||||
|
{
|
||||||
|
msec = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msec = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then let poll do all of the real work. */
|
||||||
|
|
||||||
|
ret = poll(pollset, npfds, msec);
|
||||||
|
|
||||||
|
/* Now set up the return values */
|
||||||
|
if (readfds)
|
||||||
|
{
|
||||||
|
memset(readfds, 0, sizeof(fd_set));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writefds)
|
||||||
|
{
|
||||||
|
memset(writefds, 0, sizeof(fd_set));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceptfds)
|
||||||
|
{
|
||||||
|
memset(exceptfds, 0, sizeof(fd_set));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the poll descriptor list back into selects 3 bitsets */
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
for (ndx = 0; ndx < npfds; ndx++)
|
||||||
|
{
|
||||||
|
/* Check for read conditions. Note that POLLHUP is included as a
|
||||||
|
* read condition. POLLHUP will be reported when no more data will
|
||||||
|
* be available (such as when a connection is lost). In either
|
||||||
|
* case, the read() can then be performed without blocking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (readfds)
|
||||||
|
{
|
||||||
|
if (pollset[ndx].revents & (POLLIN | POLLHUP))
|
||||||
|
{
|
||||||
|
FD_SET(pollset[ndx].fd, readfds);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for write conditions */
|
||||||
|
if (writefds)
|
||||||
|
{
|
||||||
|
if (pollset[ndx].revents & POLLOUT)
|
||||||
|
{
|
||||||
|
FD_SET(pollset[ndx].fd, writefds);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for exceptions */
|
||||||
|
if (exceptfds)
|
||||||
|
{
|
||||||
|
if (pollset[ndx].revents & POLLERR)
|
||||||
|
{
|
||||||
|
FD_SET(pollset[ndx].fd, exceptfds);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pollset) rt_free(pollset);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user