change to UNIX end of line.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1746 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
9278fe2a8c
commit
b2f9217686
|
@ -1,85 +1,85 @@
|
||||||
/*
|
/*
|
||||||
* RT-Thread Console Device File
|
* RT-Thread Console Device File
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
struct console_device
|
struct console_device
|
||||||
{
|
{
|
||||||
struct rt_device parent;
|
struct rt_device parent;
|
||||||
|
|
||||||
rt_device_t device; /* the actual device */
|
rt_device_t device; /* the actual device */
|
||||||
};
|
};
|
||||||
struct console_device _console;
|
struct console_device _console;
|
||||||
|
|
||||||
/* common device interface */
|
/* common device interface */
|
||||||
static rt_err_t console_init(rt_device_t dev)
|
static rt_err_t console_init(rt_device_t dev)
|
||||||
{
|
{
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t console_open(rt_device_t dev, rt_uint16_t oflag)
|
static rt_err_t console_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
{
|
{
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t console_close(rt_device_t dev)
|
static rt_err_t console_close(rt_device_t dev)
|
||||||
{
|
{
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_size_t console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
static rt_size_t console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
{
|
{
|
||||||
struct console_device* device;
|
struct console_device* device;
|
||||||
|
|
||||||
device = (struct console_device*)dev;
|
device = (struct console_device*)dev;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
return rt_device_read(device->device, pos, buffer, size);
|
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)
|
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;
|
struct console_device* device;
|
||||||
|
|
||||||
device = (struct console_device*)dev;
|
device = (struct console_device*)dev;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
return rt_device_write(device->device, pos, buffer, size);
|
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)
|
static rt_err_t console_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||||
{
|
{
|
||||||
return rt_device_control(_console.device, cmd, args);
|
return rt_device_control(_console.device, cmd, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_console_init(const char* device_name)
|
void rt_console_init(const char* device_name)
|
||||||
{
|
{
|
||||||
rt_device_t device;
|
rt_device_t device;
|
||||||
/* register to device framework */
|
/* register to device framework */
|
||||||
|
|
||||||
device = rt_device_find(device_name);
|
device = rt_device_find(device_name);
|
||||||
if (device != RT_NULL)
|
if (device != RT_NULL)
|
||||||
{
|
{
|
||||||
struct console_device* console;
|
struct console_device* console;
|
||||||
/* get console device */
|
/* get console device */
|
||||||
console = &_console;
|
console = &_console;
|
||||||
rt_memset(console, 0, sizeof(_console));
|
rt_memset(console, 0, sizeof(_console));
|
||||||
|
|
||||||
/* device initialization */
|
/* device initialization */
|
||||||
console->parent.type = RT_Device_Class_Char;
|
console->parent.type = RT_Device_Class_Char;
|
||||||
/* set device interface */
|
/* set device interface */
|
||||||
console->parent.init = console_init;
|
console->parent.init = console_init;
|
||||||
console->parent.open = console_open;
|
console->parent.open = console_open;
|
||||||
console->parent.close = console_close;
|
console->parent.close = console_close;
|
||||||
console->parent.read = console_read;
|
console->parent.read = console_read;
|
||||||
console->parent.write = console_write;
|
console->parent.write = console_write;
|
||||||
console->parent.control = RT_NULL;
|
console->parent.control = RT_NULL;
|
||||||
console->parent.user_data = RT_NULL;
|
console->parent.user_data = RT_NULL;
|
||||||
|
|
||||||
console->device = device;
|
console->device = device;
|
||||||
|
|
||||||
rt_device_register(&console->parent, "console", RT_DEVICE_FLAG_RDWR);
|
rt_device_register(&console->parent, "console", RT_DEVICE_FLAG_RDWR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,276 +1,276 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
#include "devfs.h"
|
#include "devfs.h"
|
||||||
|
|
||||||
/* introduce from kservice.c */
|
/* introduce from kservice.c */
|
||||||
#define rt_list_entry(node, type, member) \
|
#define rt_list_entry(node, type, member) \
|
||||||
((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
|
((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
|
||||||
|
|
||||||
struct device_dirent
|
|
||||||
{
|
|
||||||
rt_device_t *devices;
|
|
||||||
rt_uint16_t read_index;
|
|
||||||
rt_uint16_t device_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
int dfs_device_fs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
|
|
||||||
{
|
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dfs_device_fs_ioctl(struct dfs_fd* file, int cmd, void* args)
|
|
||||||
{
|
|
||||||
rt_err_t result;
|
|
||||||
rt_device_t dev_id;
|
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
|
||||||
|
|
||||||
/* get device handler */
|
|
||||||
dev_id = (rt_device_t)file->data;
|
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
|
||||||
|
|
||||||
/* close device handler */
|
|
||||||
result = rt_device_control(dev_id, cmd, args);
|
|
||||||
if (result == RT_EOK)
|
|
||||||
return DFS_STATUS_OK;
|
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dfs_device_fs_read(struct dfs_fd* file, void *buf, rt_size_t count)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
rt_device_t dev_id;
|
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
|
||||||
|
|
||||||
/* get device handler */
|
|
||||||
dev_id = (rt_device_t)file->data;
|
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
|
||||||
|
|
||||||
/* read device data */
|
|
||||||
result = rt_device_read(dev_id, file->pos, buf, count);
|
|
||||||
file->pos += result;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dfs_device_fs_write(struct dfs_fd* file, const void *buf, rt_size_t count)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
rt_device_t dev_id;
|
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
|
||||||
|
|
||||||
/* get device handler */
|
|
||||||
dev_id = (rt_device_t)file->data;
|
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
|
||||||
|
|
||||||
/* read device data */
|
|
||||||
result = rt_device_write(dev_id, file->pos, buf, count);
|
|
||||||
file->pos += result;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dfs_device_fs_close(struct dfs_fd* file)
|
|
||||||
{
|
|
||||||
rt_err_t result;
|
|
||||||
rt_device_t dev_id;
|
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
|
||||||
|
|
||||||
if (file->type == FT_DIRECTORY)
|
|
||||||
{
|
|
||||||
struct device_dirent *root_dirent;
|
|
||||||
|
|
||||||
root_dirent = (struct device_dirent*)file->data;
|
|
||||||
RT_ASSERT(root_dirent != RT_NULL);
|
|
||||||
|
|
||||||
/* release dirent */
|
|
||||||
rt_free(root_dirent);
|
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get device handler */
|
|
||||||
dev_id = (rt_device_t)file->data;
|
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
|
||||||
|
|
||||||
/* close device handler */
|
|
||||||
result = rt_device_close(dev_id);
|
|
||||||
if (result == RT_EOK)
|
|
||||||
{
|
|
||||||
file->data = RT_NULL;
|
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -DFS_STATUS_EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dfs_device_fs_open(struct dfs_fd* file)
|
|
||||||
{
|
|
||||||
rt_device_t device;
|
|
||||||
|
|
||||||
if (file->flags & DFS_O_CREAT) return -DFS_STATUS_EINVAL;
|
|
||||||
|
|
||||||
/* open root directory */
|
|
||||||
if ((file->path[0] == '/') && (file->path[1] == '\0') &&
|
|
||||||
(file->flags & DFS_O_DIRECTORY))
|
|
||||||
{
|
|
||||||
struct rt_object* object;
|
|
||||||
struct rt_list_node* node;
|
|
||||||
struct rt_object_information *information;
|
|
||||||
struct device_dirent* root_dirent;
|
|
||||||
rt_uint32_t count = 0;
|
|
||||||
|
|
||||||
extern struct rt_object_information rt_object_container[];
|
|
||||||
|
|
||||||
/* lock scheduler */
|
|
||||||
rt_enter_critical();
|
|
||||||
|
|
||||||
/* traverse device object */
|
struct device_dirent
|
||||||
information = &rt_object_container[RT_Object_Class_Device];
|
{
|
||||||
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
rt_device_t *devices;
|
||||||
{
|
rt_uint16_t read_index;
|
||||||
count ++;
|
rt_uint16_t device_count;
|
||||||
}
|
};
|
||||||
|
|
||||||
root_dirent = (struct device_dirent*) rt_malloc (sizeof(struct device_dirent) +
|
int dfs_device_fs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
|
||||||
count * sizeof(rt_device_t));
|
{
|
||||||
if (root_dirent != RT_NULL)
|
return DFS_STATUS_OK;
|
||||||
{
|
}
|
||||||
root_dirent->devices = (rt_device_t *)(root_dirent + 1);
|
|
||||||
root_dirent->read_index = 0;
|
int dfs_device_fs_ioctl(struct dfs_fd* file, int cmd, void* args)
|
||||||
root_dirent->device_count = count;
|
{
|
||||||
count = 0;
|
rt_err_t result;
|
||||||
/* get all device node */
|
rt_device_t dev_id;
|
||||||
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
|
||||||
{
|
RT_ASSERT(file != RT_NULL);
|
||||||
object = rt_list_entry(node, struct rt_object, list);
|
|
||||||
root_dirent->devices[count] = (rt_device_t)object;
|
/* get device handler */
|
||||||
count ++;
|
dev_id = (rt_device_t)file->data;
|
||||||
}
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
}
|
|
||||||
rt_exit_critical();
|
/* close device handler */
|
||||||
|
result = rt_device_control(dev_id, cmd, args);
|
||||||
/* set data */
|
if (result == RT_EOK)
|
||||||
file->data = root_dirent;
|
return DFS_STATUS_OK;
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
return -DFS_STATUS_EIO;
|
||||||
|
}
|
||||||
device = rt_device_find(&file->path[1]);
|
|
||||||
if (device == RT_NULL)
|
int dfs_device_fs_read(struct dfs_fd* file, void *buf, rt_size_t count)
|
||||||
return -DFS_STATUS_ENODEV;
|
{
|
||||||
|
int result;
|
||||||
file->data = device;
|
rt_device_t dev_id;
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
int dfs_device_fs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
|
/* get device handler */
|
||||||
{
|
dev_id = (rt_device_t)file->data;
|
||||||
/* stat root directory */
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
if ((path[0] == '/') && (path[1] == '\0'))
|
|
||||||
{
|
/* read device data */
|
||||||
st->st_dev = 0;
|
result = rt_device_read(dev_id, file->pos, buf, count);
|
||||||
|
file->pos += result;
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
return result;
|
||||||
st->st_mode &= ~DFS_S_IFREG;
|
}
|
||||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
|
||||||
|
int dfs_device_fs_write(struct dfs_fd* file, const void *buf, rt_size_t count)
|
||||||
st->st_size = 0;
|
{
|
||||||
st->st_mtime = 0;
|
int result;
|
||||||
st->st_blksize = 512;
|
rt_device_t dev_id;
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
RT_ASSERT(file != RT_NULL);
|
||||||
else
|
|
||||||
{
|
/* get device handler */
|
||||||
rt_device_t dev_id;
|
dev_id = (rt_device_t)file->data;
|
||||||
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
dev_id = rt_device_find(&path[1]);
|
|
||||||
if (dev_id != RT_NULL)
|
/* read device data */
|
||||||
{
|
result = rt_device_write(dev_id, file->pos, buf, count);
|
||||||
st->st_dev = 0;
|
file->pos += result;
|
||||||
|
|
||||||
st->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
return result;
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
}
|
||||||
|
|
||||||
if (dev_id->type == RT_Device_Class_Char)
|
int dfs_device_fs_close(struct dfs_fd* file)
|
||||||
st->st_mode |= DFS_S_IFCHR;
|
{
|
||||||
else if (dev_id->type == RT_Device_Class_Block)
|
rt_err_t result;
|
||||||
st->st_mode |= DFS_S_IFBLK;
|
rt_device_t dev_id;
|
||||||
else
|
|
||||||
st->st_mode |= DFS_S_IFREG;
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
st->st_size = 0;
|
if (file->type == FT_DIRECTORY)
|
||||||
st->st_mtime = 0;
|
{
|
||||||
st->st_blksize = 512;
|
struct device_dirent *root_dirent;
|
||||||
return DFS_STATUS_OK;
|
|
||||||
}
|
root_dirent = (struct device_dirent*)file->data;
|
||||||
}
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
return -DFS_STATUS_ENOENT;
|
/* release dirent */
|
||||||
}
|
rt_free(root_dirent);
|
||||||
|
return DFS_STATUS_OK;
|
||||||
int dfs_device_fs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
|
}
|
||||||
{
|
|
||||||
rt_uint32_t index;
|
/* get device handler */
|
||||||
rt_object_t object;
|
dev_id = (rt_device_t)file->data;
|
||||||
struct dirent* d;
|
RT_ASSERT(dev_id != RT_NULL);
|
||||||
struct device_dirent *root_dirent;
|
|
||||||
|
/* close device handler */
|
||||||
root_dirent = (struct device_dirent*)file->data;
|
result = rt_device_close(dev_id);
|
||||||
RT_ASSERT(root_dirent != RT_NULL);
|
if (result == RT_EOK)
|
||||||
|
{
|
||||||
/* make integer count */
|
file->data = RT_NULL;
|
||||||
count = (count / sizeof(struct dirent));
|
return DFS_STATUS_OK;
|
||||||
if ( count == 0 ) return -DFS_STATUS_EINVAL;
|
}
|
||||||
|
|
||||||
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
return -DFS_STATUS_EIO;
|
||||||
index ++)
|
}
|
||||||
{
|
|
||||||
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
int dfs_device_fs_open(struct dfs_fd* file)
|
||||||
|
{
|
||||||
d = dirp + index;
|
rt_device_t device;
|
||||||
d->d_type = DFS_DT_REG;
|
|
||||||
d->d_namlen = RT_NAME_MAX;
|
if (file->flags & DFS_O_CREAT) return -DFS_STATUS_EINVAL;
|
||||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
|
||||||
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
/* open root directory */
|
||||||
}
|
if ((file->path[0] == '/') && (file->path[1] == '\0') &&
|
||||||
|
(file->flags & DFS_O_DIRECTORY))
|
||||||
root_dirent->read_index += index;
|
{
|
||||||
|
struct rt_object* object;
|
||||||
return index * sizeof(struct dirent);
|
struct rt_list_node* node;
|
||||||
}
|
struct rt_object_information *information;
|
||||||
|
struct device_dirent* root_dirent;
|
||||||
static const struct dfs_filesystem_operation _device_fs =
|
rt_uint32_t count = 0;
|
||||||
{
|
|
||||||
"devfs",
|
extern struct rt_object_information rt_object_container[];
|
||||||
dfs_device_fs_mount,
|
|
||||||
RT_NULL,
|
/* lock scheduler */
|
||||||
RT_NULL,
|
rt_enter_critical();
|
||||||
RT_NULL,
|
|
||||||
|
/* traverse device object */
|
||||||
dfs_device_fs_open,
|
information = &rt_object_container[RT_Object_Class_Device];
|
||||||
dfs_device_fs_close,
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
dfs_device_fs_ioctl,
|
{
|
||||||
dfs_device_fs_read,
|
count ++;
|
||||||
dfs_device_fs_write,
|
}
|
||||||
RT_NULL,
|
|
||||||
RT_NULL,
|
root_dirent = (struct device_dirent*) rt_malloc (sizeof(struct device_dirent) +
|
||||||
dfs_device_fs_getdents,
|
count * sizeof(rt_device_t));
|
||||||
RT_NULL,
|
if (root_dirent != RT_NULL)
|
||||||
dfs_device_fs_stat,
|
{
|
||||||
RT_NULL,
|
root_dirent->devices = (rt_device_t *)(root_dirent + 1);
|
||||||
};
|
root_dirent->read_index = 0;
|
||||||
|
root_dirent->device_count = count;
|
||||||
int devfs_init(void)
|
count = 0;
|
||||||
{
|
/* get all device node */
|
||||||
/* register rom file system */
|
for (node = information->object_list.next; node != &(information->object_list); node = node->next)
|
||||||
dfs_register(&_device_fs);
|
{
|
||||||
|
object = rt_list_entry(node, struct rt_object, list);
|
||||||
return 0;
|
root_dirent->devices[count] = (rt_device_t)object;
|
||||||
}
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_exit_critical();
|
||||||
|
|
||||||
|
/* set data */
|
||||||
|
file->data = root_dirent;
|
||||||
|
return DFS_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = rt_device_find(&file->path[1]);
|
||||||
|
if (device == RT_NULL)
|
||||||
|
return -DFS_STATUS_ENODEV;
|
||||||
|
|
||||||
|
file->data = device;
|
||||||
|
return DFS_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
|
||||||
|
{
|
||||||
|
/* stat root directory */
|
||||||
|
if ((path[0] == '/') && (path[1] == '\0'))
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
||||||
|
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
||||||
|
st->st_mode &= ~DFS_S_IFREG;
|
||||||
|
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
st->st_blksize = 512;
|
||||||
|
return DFS_STATUS_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
dev_id = rt_device_find(&path[1]);
|
||||||
|
if (dev_id != RT_NULL)
|
||||||
|
{
|
||||||
|
st->st_dev = 0;
|
||||||
|
|
||||||
|
st->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
||||||
|
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
||||||
|
|
||||||
|
if (dev_id->type == RT_Device_Class_Char)
|
||||||
|
st->st_mode |= DFS_S_IFCHR;
|
||||||
|
else if (dev_id->type == RT_Device_Class_Block)
|
||||||
|
st->st_mode |= DFS_S_IFBLK;
|
||||||
|
else
|
||||||
|
st->st_mode |= DFS_S_IFREG;
|
||||||
|
|
||||||
|
st->st_size = 0;
|
||||||
|
st->st_mtime = 0;
|
||||||
|
st->st_blksize = 512;
|
||||||
|
return DFS_STATUS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -DFS_STATUS_ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_device_fs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
|
||||||
|
{
|
||||||
|
rt_uint32_t index;
|
||||||
|
rt_object_t object;
|
||||||
|
struct dirent* d;
|
||||||
|
struct device_dirent *root_dirent;
|
||||||
|
|
||||||
|
root_dirent = (struct device_dirent*)file->data;
|
||||||
|
RT_ASSERT(root_dirent != RT_NULL);
|
||||||
|
|
||||||
|
/* make integer count */
|
||||||
|
count = (count / sizeof(struct dirent));
|
||||||
|
if ( count == 0 ) return -DFS_STATUS_EINVAL;
|
||||||
|
|
||||||
|
for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
|
||||||
|
index ++)
|
||||||
|
{
|
||||||
|
object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
|
||||||
|
|
||||||
|
d = dirp + index;
|
||||||
|
d->d_type = DFS_DT_REG;
|
||||||
|
d->d_namlen = RT_NAME_MAX;
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
root_dirent->read_index += index;
|
||||||
|
|
||||||
|
return index * sizeof(struct dirent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dfs_filesystem_operation _device_fs =
|
||||||
|
{
|
||||||
|
"devfs",
|
||||||
|
dfs_device_fs_mount,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
|
||||||
|
dfs_device_fs_open,
|
||||||
|
dfs_device_fs_close,
|
||||||
|
dfs_device_fs_ioctl,
|
||||||
|
dfs_device_fs_read,
|
||||||
|
dfs_device_fs_write,
|
||||||
|
RT_NULL,
|
||||||
|
RT_NULL,
|
||||||
|
dfs_device_fs_getdents,
|
||||||
|
RT_NULL,
|
||||||
|
dfs_device_fs_stat,
|
||||||
|
RT_NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
int devfs_init(void)
|
||||||
|
{
|
||||||
|
/* register rom file system */
|
||||||
|
dfs_register(&_device_fs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef __DEVICE_FS_H__
|
#ifndef __DEVICE_FS_H__
|
||||||
#define __DEVICE_FS_H__
|
#define __DEVICE_FS_H__
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
int devfs_init(void);
|
int devfs_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,104 +1,104 @@
|
||||||
#ifndef __AUTH_H__
|
#ifndef __AUTH_H__
|
||||||
#define __AUTH_H__
|
#define __AUTH_H__
|
||||||
|
|
||||||
#include <rpc/xdr.h>
|
#include <rpc/xdr.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status returned from authentication check
|
* Status returned from authentication check
|
||||||
*/
|
*/
|
||||||
enum auth_stat {
|
enum auth_stat {
|
||||||
AUTH_OK=0,
|
AUTH_OK=0,
|
||||||
/*
|
/*
|
||||||
* failed at remote end
|
* failed at remote end
|
||||||
*/
|
*/
|
||||||
AUTH_BADCRED=1, /* bogus credentials (seal broken) */
|
AUTH_BADCRED=1, /* bogus credentials (seal broken) */
|
||||||
AUTH_REJECTEDCRED=2, /* client should begin new session */
|
AUTH_REJECTEDCRED=2, /* client should begin new session */
|
||||||
AUTH_BADVERF=3, /* bogus verifier (seal broken) */
|
AUTH_BADVERF=3, /* bogus verifier (seal broken) */
|
||||||
AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
|
AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
|
||||||
AUTH_TOOWEAK=5, /* rejected due to security reasons */
|
AUTH_TOOWEAK=5, /* rejected due to security reasons */
|
||||||
/*
|
/*
|
||||||
* failed locally
|
* failed locally
|
||||||
*/
|
*/
|
||||||
AUTH_INVALIDRESP=6, /* bogus response verifier */
|
AUTH_INVALIDRESP=6, /* bogus response verifier */
|
||||||
AUTH_FAILED=7 /* some unknown reason */
|
AUTH_FAILED=7 /* some unknown reason */
|
||||||
};
|
};
|
||||||
|
|
||||||
union des_block {
|
union des_block {
|
||||||
struct {
|
struct {
|
||||||
uint32_t high;
|
uint32_t high;
|
||||||
uint32_t low;
|
uint32_t low;
|
||||||
} key;
|
} key;
|
||||||
char c[8];
|
char c[8];
|
||||||
};
|
};
|
||||||
typedef union des_block des_block;
|
typedef union des_block des_block;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authentication info. Opaque to client.
|
* Authentication info. Opaque to client.
|
||||||
*/
|
*/
|
||||||
struct opaque_auth {
|
struct opaque_auth {
|
||||||
enum_t oa_flavor; /* flavor of auth */
|
enum_t oa_flavor; /* flavor of auth */
|
||||||
char* oa_base; /* address of more auth stuff */
|
char* oa_base; /* address of more auth stuff */
|
||||||
unsigned int oa_length; /* not to exceed MAX_AUTH_BYTES */
|
unsigned int oa_length; /* not to exceed MAX_AUTH_BYTES */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Auth handle, interface to client side authenticators.
|
* Auth handle, interface to client side authenticators.
|
||||||
*/
|
*/
|
||||||
typedef struct AUTH AUTH;
|
typedef struct AUTH AUTH;
|
||||||
struct AUTH {
|
struct AUTH {
|
||||||
struct opaque_auth ah_cred;
|
struct opaque_auth ah_cred;
|
||||||
struct opaque_auth ah_verf;
|
struct opaque_auth ah_verf;
|
||||||
union des_block ah_key;
|
union des_block ah_key;
|
||||||
struct auth_ops {
|
struct auth_ops {
|
||||||
void (*ah_nextverf) (AUTH *);
|
void (*ah_nextverf) (AUTH *);
|
||||||
int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */
|
int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */
|
||||||
int (*ah_validate) (AUTH *, struct opaque_auth *);
|
int (*ah_validate) (AUTH *, struct opaque_auth *);
|
||||||
/* validate verifier */
|
/* validate verifier */
|
||||||
int (*ah_refresh) (AUTH *); /* refresh credentials */
|
int (*ah_refresh) (AUTH *); /* refresh credentials */
|
||||||
void (*ah_destroy) (AUTH *); /* destroy this structure */
|
void (*ah_destroy) (AUTH *); /* destroy this structure */
|
||||||
} *ah_ops;
|
} *ah_ops;
|
||||||
char* ah_private;
|
char* ah_private;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct opaque_auth _null_auth;
|
extern struct opaque_auth _null_auth;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authentication ops.
|
* Authentication ops.
|
||||||
* The ops and the auth handle provide the interface to the authenticators.
|
* The ops and the auth handle provide the interface to the authenticators.
|
||||||
*
|
*
|
||||||
* AUTH *auth;
|
* AUTH *auth;
|
||||||
* XDR *xdrs;
|
* XDR *xdrs;
|
||||||
* struct opaque_auth verf;
|
* struct opaque_auth verf;
|
||||||
*/
|
*/
|
||||||
#define AUTH_NEXTVERF(auth) \
|
#define AUTH_NEXTVERF(auth) \
|
||||||
((*((auth)->ah_ops->ah_nextverf))(auth))
|
((*((auth)->ah_ops->ah_nextverf))(auth))
|
||||||
#define auth_nextverf(auth) \
|
#define auth_nextverf(auth) \
|
||||||
((*((auth)->ah_ops->ah_nextverf))(auth))
|
((*((auth)->ah_ops->ah_nextverf))(auth))
|
||||||
|
|
||||||
#define AUTH_MARSHALL(auth, xdrs) \
|
#define AUTH_MARSHALL(auth, xdrs) \
|
||||||
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
||||||
#define auth_marshall(auth, xdrs) \
|
#define auth_marshall(auth, xdrs) \
|
||||||
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
|
||||||
|
|
||||||
#define AUTH_VALIDATE(auth, verfp) \
|
#define AUTH_VALIDATE(auth, verfp) \
|
||||||
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
||||||
#define auth_validate(auth, verfp) \
|
#define auth_validate(auth, verfp) \
|
||||||
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
||||||
|
|
||||||
#define AUTH_REFRESH(auth) \
|
#define AUTH_REFRESH(auth) \
|
||||||
((*((auth)->ah_ops->ah_refresh))(auth))
|
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||||
#define auth_refresh(auth) \
|
#define auth_refresh(auth) \
|
||||||
((*((auth)->ah_ops->ah_refresh))(auth))
|
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||||
|
|
||||||
#define AUTH_DESTROY(auth) \
|
#define AUTH_DESTROY(auth) \
|
||||||
((*((auth)->ah_ops->ah_destroy))(auth))
|
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||||
#define auth_destroy(auth) \
|
#define auth_destroy(auth) \
|
||||||
((*((auth)->ah_ops->ah_destroy))(auth))
|
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||||
|
|
||||||
#define MAX_AUTH_BYTES 400
|
#define MAX_AUTH_BYTES 400
|
||||||
#define MAXNETNAMELEN 255 /* maximum length of network user's name */
|
#define MAXNETNAMELEN 255 /* maximum length of network user's name */
|
||||||
|
|
||||||
AUTH *authnone_create(void);
|
AUTH *authnone_create(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,60 +1,60 @@
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "clnt.h"
|
#include "clnt.h"
|
||||||
#include <rpc/rpc.h>
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
static struct timeval timeout = { 5, 0 };
|
static struct timeval timeout = { 5, 0 };
|
||||||
static struct timeval tottimeout = { 60, 0 };
|
static struct timeval tottimeout = { 60, 0 };
|
||||||
|
|
||||||
|
|
||||||
bool_t xdr_pmap(xdrs, regs)
|
bool_t xdr_pmap(xdrs, regs)
|
||||||
XDR *xdrs;
|
XDR *xdrs;
|
||||||
struct pmap *regs;
|
struct pmap *regs;
|
||||||
{
|
{
|
||||||
if (xdr_u_long(xdrs, ®s->pm_prog) &&
|
if (xdr_u_long(xdrs, ®s->pm_prog) &&
|
||||||
xdr_u_long(xdrs, ®s->pm_vers) &&
|
xdr_u_long(xdrs, ®s->pm_vers) &&
|
||||||
xdr_u_long(xdrs, ®s->pm_prot))
|
xdr_u_long(xdrs, ®s->pm_prot))
|
||||||
return (xdr_u_long(xdrs, ®s->pm_port));
|
return (xdr_u_long(xdrs, ®s->pm_port));
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the mapped port for program,version.
|
* Find the mapped port for program,version.
|
||||||
* Calls the pmap service remotely to do the lookup.
|
* Calls the pmap service remotely to do the lookup.
|
||||||
* Returns 0 if no map exists.
|
* Returns 0 if no map exists.
|
||||||
*/
|
*/
|
||||||
unsigned short pmap_getport(address, program, version, protocol)
|
unsigned short pmap_getport(address, program, version, protocol)
|
||||||
struct sockaddr_in *address;
|
struct sockaddr_in *address;
|
||||||
unsigned long program;
|
unsigned long program;
|
||||||
unsigned long version;
|
unsigned long version;
|
||||||
unsigned int protocol;
|
unsigned int protocol;
|
||||||
{
|
{
|
||||||
unsigned short port = 0;
|
unsigned short port = 0;
|
||||||
int socket = -1;
|
int socket = -1;
|
||||||
register CLIENT *client;
|
register CLIENT *client;
|
||||||
struct pmap parms;
|
struct pmap parms;
|
||||||
|
|
||||||
address->sin_port = htons((unsigned short)PMAPPORT);
|
address->sin_port = htons((unsigned short)PMAPPORT);
|
||||||
if (protocol == IPPROTO_UDP)
|
if (protocol == IPPROTO_UDP)
|
||||||
client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
|
client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
|
||||||
&socket, RPCSMALLMSGSIZE,
|
&socket, RPCSMALLMSGSIZE,
|
||||||
RPCSMALLMSGSIZE);
|
RPCSMALLMSGSIZE);
|
||||||
|
|
||||||
if (client != (CLIENT *) NULL)
|
if (client != (CLIENT *) NULL)
|
||||||
{
|
{
|
||||||
parms.pm_prog = program;
|
parms.pm_prog = program;
|
||||||
parms.pm_vers = version;
|
parms.pm_vers = version;
|
||||||
parms.pm_prot = protocol;
|
parms.pm_prot = protocol;
|
||||||
parms.pm_port = 0; /* not needed or used */
|
parms.pm_port = 0; /* not needed or used */
|
||||||
if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
|
if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
|
||||||
(xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
|
(xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
|
||||||
{
|
{
|
||||||
rt_kprintf("pmap failure\n");
|
rt_kprintf("pmap failure\n");
|
||||||
}
|
}
|
||||||
CLNT_DESTROY(client);
|
CLNT_DESTROY(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) lwip_close(socket);
|
(void) lwip_close(socket);
|
||||||
address->sin_port = 0;
|
address->sin_port = 0;
|
||||||
|
|
||||||
return (port);
|
return (port);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,58 @@
|
||||||
#ifndef __RPC_PMAP_PROT_H__
|
#ifndef __RPC_PMAP_PROT_H__
|
||||||
#define __RPC_PMAP_PROT_H__
|
#define __RPC_PMAP_PROT_H__
|
||||||
|
|
||||||
#include <rpc/xdr.h>
|
#include <rpc/xdr.h>
|
||||||
|
|
||||||
/* The following procedures are supported by the protocol:
|
/* The following procedures are supported by the protocol:
|
||||||
*
|
*
|
||||||
* PMAPPROC_NULL() returns ()
|
* PMAPPROC_NULL() returns ()
|
||||||
* takes nothing, returns nothing
|
* takes nothing, returns nothing
|
||||||
*
|
*
|
||||||
* PMAPPROC_SET(struct pmap) returns (bool_t)
|
* PMAPPROC_SET(struct pmap) returns (bool_t)
|
||||||
* TRUE is success, FALSE is failure. Registers the tuple
|
* TRUE is success, FALSE is failure. Registers the tuple
|
||||||
* [prog, vers, prot, port].
|
* [prog, vers, prot, port].
|
||||||
*
|
*
|
||||||
* PMAPPROC_UNSET(struct pmap) returns (bool_t)
|
* PMAPPROC_UNSET(struct pmap) returns (bool_t)
|
||||||
* TRUE is success, FALSE is failure. Un-registers pair
|
* TRUE is success, FALSE is failure. Un-registers pair
|
||||||
* [prog, vers]. prot and port are ignored.
|
* [prog, vers]. prot and port are ignored.
|
||||||
*
|
*
|
||||||
* PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
|
* PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
|
||||||
* 0 is failure. Otherwise returns the port number where the pair
|
* 0 is failure. Otherwise returns the port number where the pair
|
||||||
* [prog, vers] is registered. It may lie!
|
* [prog, vers] is registered. It may lie!
|
||||||
*
|
*
|
||||||
* PMAPPROC_DUMP() RETURNS (struct pmaplist *)
|
* PMAPPROC_DUMP() RETURNS (struct pmaplist *)
|
||||||
*
|
*
|
||||||
* PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
|
* PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
|
||||||
* RETURNS (port, string<>);
|
* RETURNS (port, string<>);
|
||||||
* usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
|
* usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
|
||||||
* Calls the procedure on the local machine. If it is not registered,
|
* Calls the procedure on the local machine. If it is not registered,
|
||||||
* this procedure is quite; ie it does not return error information!!!
|
* this procedure is quite; ie it does not return error information!!!
|
||||||
* This procedure only is supported on rpc/udp and calls via
|
* This procedure only is supported on rpc/udp and calls via
|
||||||
* rpc/udp. This routine only passes null authentication parameters.
|
* rpc/udp. This routine only passes null authentication parameters.
|
||||||
* This file has no interface to xdr routines for PMAPPROC_CALLIT.
|
* This file has no interface to xdr routines for PMAPPROC_CALLIT.
|
||||||
*
|
*
|
||||||
* The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
|
* The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PMAPPORT ((unsigned short)111)
|
#define PMAPPORT ((unsigned short)111)
|
||||||
#define PMAPPROG ((unsigned long)100000)
|
#define PMAPPROG ((unsigned long)100000)
|
||||||
#define PMAPVERS ((unsigned long)2)
|
#define PMAPVERS ((unsigned long)2)
|
||||||
#define PMAPVERS_PROTO ((unsigned long)2)
|
#define PMAPVERS_PROTO ((unsigned long)2)
|
||||||
#define PMAPVERS_ORIG ((unsigned long)1)
|
#define PMAPVERS_ORIG ((unsigned long)1)
|
||||||
#define PMAPPROC_NULL ((unsigned long)0)
|
#define PMAPPROC_NULL ((unsigned long)0)
|
||||||
#define PMAPPROC_SET ((unsigned long)1)
|
#define PMAPPROC_SET ((unsigned long)1)
|
||||||
#define PMAPPROC_UNSET ((unsigned long)2)
|
#define PMAPPROC_UNSET ((unsigned long)2)
|
||||||
#define PMAPPROC_GETPORT ((unsigned long)3)
|
#define PMAPPROC_GETPORT ((unsigned long)3)
|
||||||
#define PMAPPROC_DUMP ((unsigned long)4)
|
#define PMAPPROC_DUMP ((unsigned long)4)
|
||||||
#define PMAPPROC_CALLIT ((unsigned long)5)
|
#define PMAPPROC_CALLIT ((unsigned long)5)
|
||||||
|
|
||||||
struct pmap {
|
struct pmap {
|
||||||
long unsigned pm_prog;
|
long unsigned pm_prog;
|
||||||
long unsigned pm_vers;
|
long unsigned pm_vers;
|
||||||
long unsigned pm_prot;
|
long unsigned pm_prot;
|
||||||
long unsigned pm_port;
|
long unsigned pm_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
|
extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs.h
|
* File : dfs.h
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
* This file is part of Device File System in RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rt-thread.org/license/LICENSE.
|
* http://www.rt-thread.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2005-02-22 Bernard The first version.
|
* 2005-02-22 Bernard The first version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DFS_H__
|
#ifndef __DFS_H__
|
||||||
#define __DFS_H__
|
#define __DFS_H__
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
/* 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);
|
||||||
void fd_put(struct dfs_fd* fd);
|
void fd_put(struct dfs_fd* fd);
|
||||||
int fd_is_open(const char* pathname);
|
int fd_is_open(const char* pathname);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
/*
|
/*
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
| Project : Device Filesystem
|
| Project : Device Filesystem
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
| Copyright 2004, 2005 www.fayfayspace.org.
|
| Copyright 2004, 2005 www.fayfayspace.org.
|
||||||
| All rights reserved.
|
| All rights reserved.
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
| File : dfs_efs.h
|
| File : dfs_efs.h
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
| Chang Logs:
|
| Chang Logs:
|
||||||
| Date Author Notes
|
| Date Author Notes
|
||||||
| 2010-02-06 Bernard Add elm_init function declaration
|
| 2010-02-06 Bernard Add elm_init function declaration
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DFS_ELM_H__
|
#ifndef __DFS_ELM_H__
|
||||||
#define __DFS_ELM_H__
|
#define __DFS_ELM_H__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int elm_init(void);
|
int elm_init(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
/*
|
/*
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
| Project : Device Filesystem
|
| Project : Device Filesystem
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
| Copyright 2004, 2005 www.fayfayspace.org.
|
| Copyright 2004, 2005 www.fayfayspace.org.
|
||||||
| All rights reserved.
|
| All rights reserved.
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
| File : dfs_raw.h, the raw APIs of Device FileSystem
|
| File : dfs_raw.h, the raw APIs of Device FileSystem
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
| Chang Logs:
|
| Chang Logs:
|
||||||
| Date Author Notes
|
| Date Author Notes
|
||||||
| 2005-01-26 ffxz The first version
|
| 2005-01-26 ffxz The first version
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DFS_RAW_H__
|
#ifndef __DFS_RAW_H__
|
||||||
#define __DFS_RAW_H__
|
#define __DFS_RAW_H__
|
||||||
|
|
||||||
#include <dfs_def.h>
|
#include <dfs_def.h>
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
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, rt_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, rt_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, rt_size_t len);
|
||||||
int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset);
|
int dfs_file_lseek(struct dfs_fd* fd, rt_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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,89 +1,89 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs_fs.h
|
* File : dfs_fs.h
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
* This file is part of Device File System in RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rt-thread.org/license/LICENSE.
|
* http://www.rt-thread.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2005-02-22 Bernard The first version.
|
* 2005-02-22 Bernard The first version.
|
||||||
*/
|
*/
|
||||||
#ifndef __DFS_FS_H__
|
#ifndef __DFS_FS_H__
|
||||||
#define __DFS_FS_H__
|
#define __DFS_FS_H__
|
||||||
|
|
||||||
#include <dfs_def.h>
|
#include <dfs_def.h>
|
||||||
|
|
||||||
/* Pre-declaration */
|
/* Pre-declaration */
|
||||||
struct dfs_filesystem;
|
struct dfs_filesystem;
|
||||||
struct dfs_fd;
|
struct dfs_fd;
|
||||||
|
|
||||||
/* File system operations struct */
|
/* File system operations struct */
|
||||||
struct dfs_filesystem_operation
|
struct dfs_filesystem_operation
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
/* 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);
|
||||||
int (*unmount) (struct dfs_filesystem* fs);
|
int (*unmount) (struct dfs_filesystem* fs);
|
||||||
|
|
||||||
/* make a file system */
|
/* make a file system */
|
||||||
int (*mkfs) (const char* device_name);
|
int (*mkfs) (const char* device_name);
|
||||||
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 (*open) (struct dfs_fd* fd);
|
||||||
int (*close) (struct dfs_fd* fd);
|
int (*close) (struct dfs_fd* fd);
|
||||||
int (*ioctl) (struct dfs_fd* fd, int cmd, void *args);
|
int (*ioctl) (struct dfs_fd* fd, int cmd, void *args);
|
||||||
int (*read) (struct dfs_fd* fd, void* buf, rt_size_t count);
|
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 (*write) (struct dfs_fd* fd, const void* buf, rt_size_t count);
|
||||||
int (*flush) (struct dfs_fd* fd);
|
int (*flush) (struct dfs_fd* fd);
|
||||||
int (*lseek) (struct dfs_fd* fd, rt_off_t offset);
|
int (*lseek) (struct dfs_fd* fd, rt_off_t offset);
|
||||||
int (*getdents) (struct dfs_fd* fd, struct dirent* dirp, rt_uint32_t count);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mounted file system */
|
/* Mounted file system */
|
||||||
struct dfs_filesystem
|
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_operation* ops; /* Operations for file system type */
|
||||||
|
|
||||||
void *data; /* Specific file system data */
|
void *data; /* Specific file system data */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* file system partition table */
|
/* file system partition table */
|
||||||
struct dfs_partition
|
struct dfs_partition
|
||||||
{
|
{
|
||||||
rt_uint8_t type; /* file system type */
|
rt_uint8_t type; /* file system type */
|
||||||
rt_off_t offset; /* partition start offset */
|
rt_off_t offset; /* partition start offset */
|
||||||
rt_size_t size; /* partition size */
|
rt_size_t size; /* partition size */
|
||||||
rt_sem_t lock;
|
rt_sem_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
int dfs_register(const struct dfs_filesystem_operation* ops);
|
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);
|
||||||
rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex);
|
rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex);
|
||||||
|
|
||||||
int dfs_mount(const char* device_name, const char* path,
|
int dfs_mount(const char* device_name, const char* path,
|
||||||
const char* filesystemtype, rt_uint32_t rwflag, const
|
const char* filesystemtype, rt_uint32_t rwflag, const
|
||||||
void* data);
|
void* data);
|
||||||
int dfs_unmount(const char *specialfile);
|
int dfs_unmount(const char *specialfile);
|
||||||
|
|
||||||
/* extern variable */
|
/* extern variable */
|
||||||
extern const struct dfs_filesystem_operation* filesystem_operation_table[];
|
extern const struct dfs_filesystem_operation* filesystem_operation_table[];
|
||||||
extern struct dfs_filesystem filesystem_table[];
|
extern struct dfs_filesystem filesystem_table[];
|
||||||
|
|
||||||
extern char working_directory[];
|
extern char working_directory[];
|
||||||
|
|
||||||
void dfs_lock(void);
|
void dfs_lock(void);
|
||||||
void dfs_unlock(void);
|
void dfs_unlock(void);
|
||||||
int dfs_statfs(const char* path, struct statfs* buffer);
|
int dfs_statfs(const char* path, struct statfs* buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
|
|
||||||
| Project : Device Filesystem
|
| Project : Device Filesystem
|
||||||
|
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
|
|
||||||
| Copyright 2004, 2005 www.fayfayspace.org.
|
| Copyright 2004, 2005 www.fayfayspace.org.
|
||||||
|
|
||||||
| All rights reserved.
|
| All rights reserved.
|
||||||
|
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
|
|
||||||
| File : dfs_init.h, the initilization definitions of Device FileSystem
|
| File : dfs_init.h, the initilization definitions of Device FileSystem
|
||||||
|------------------------------------------------------------------------------
|
|------------------------------------------------------------------------------
|
||||||
| Chang Logs:
|
| Chang Logs:
|
||||||
|
|
||||||
| Date Author Notes
|
| Date Author Notes
|
||||||
|
|
||||||
| 2005-02-21 ffxz The first version.
|
| 2005-02-21 ffxz The first version.
|
||||||
+------------------------------------------------------------------------------
|
+------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DFS_INIT_H__
|
#ifndef __DFS_INIT_H__
|
||||||
#define __DFS_INIT_H__
|
#define __DFS_INIT_H__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* initilization of dfs */
|
/* initilization of dfs */
|
||||||
void dfs_init(void);
|
void dfs_init(void);
|
||||||
|
|
||||||
/* initilization of dfs with filesystem server */
|
/* initilization of dfs with filesystem server */
|
||||||
void dfs_server_init(void);
|
void dfs_server_init(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,116 +1,116 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs_def.h
|
* File : dfs_def.h
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
* This file is part of Device File System in RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rt-thread.org/license/LICENSE.
|
* http://www.rt-thread.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* 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 <dfs_def.h>
|
||||||
|
|
||||||
#ifndef RT_USING_NEWLIB
|
#ifndef RT_USING_NEWLIB
|
||||||
#define O_RDONLY DFS_O_RDONLY
|
#define O_RDONLY DFS_O_RDONLY
|
||||||
#define O_WRONLY DFS_O_WRONLY
|
#define O_WRONLY DFS_O_WRONLY
|
||||||
#define O_RDWR DFS_O_RDWR
|
#define O_RDWR DFS_O_RDWR
|
||||||
#define O_ACCMODE DFS_O_ACCMODE
|
#define O_ACCMODE DFS_O_ACCMODE
|
||||||
#define O_CREAT DFS_O_CREAT
|
#define O_CREAT DFS_O_CREAT
|
||||||
#define O_EXCL DFS_O_EXCL
|
#define O_EXCL DFS_O_EXCL
|
||||||
#define O_TRUNC DFS_O_TRUNC
|
#define O_TRUNC DFS_O_TRUNC
|
||||||
#define O_APPEND DFS_O_APPEND
|
#define O_APPEND DFS_O_APPEND
|
||||||
#define O_DIRECTORY DFS_O_DIRECTORY
|
#define O_DIRECTORY DFS_O_DIRECTORY
|
||||||
|
|
||||||
#define S_IFMT DFS_S_IFMT
|
#define S_IFMT DFS_S_IFMT
|
||||||
#define S_IFSOCK DFS_S_IFSOCK
|
#define S_IFSOCK DFS_S_IFSOCK
|
||||||
#define S_IFLNK DFS_S_IFLNK
|
#define S_IFLNK DFS_S_IFLNK
|
||||||
#define S_IFREG DFS_S_IFREG
|
#define S_IFREG DFS_S_IFREG
|
||||||
#define S_IFBLK DFS_S_IFBLK
|
#define S_IFBLK DFS_S_IFBLK
|
||||||
#define S_IFDIR DFS_S_IFDIR
|
#define S_IFDIR DFS_S_IFDIR
|
||||||
#define S_IFCHR DFS_S_IFCHR
|
#define S_IFCHR DFS_S_IFCHR
|
||||||
#define S_IFIFO DFS_S_IFIFO
|
#define S_IFIFO DFS_S_IFIFO
|
||||||
#define S_ISUID DFS_S_ISUID
|
#define S_ISUID DFS_S_ISUID
|
||||||
#define S_ISGID DFS_S_ISGID
|
#define S_ISGID DFS_S_ISGID
|
||||||
#define S_ISVTX DFS_S_ISVTX
|
#define S_ISVTX DFS_S_ISVTX
|
||||||
|
|
||||||
#define S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK)
|
#define S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK)
|
||||||
#define S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG)
|
#define S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG)
|
||||||
#define S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR)
|
#define S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR)
|
||||||
#define S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR)
|
#define S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR)
|
||||||
#define S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK)
|
#define S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK)
|
||||||
#define S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO)
|
#define S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO)
|
||||||
#define S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK)
|
#define S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK)
|
||||||
|
|
||||||
#define S_IRWXU DFS_S_IRWXU
|
#define S_IRWXU DFS_S_IRWXU
|
||||||
#define S_IRUSR DFS_S_IRUSR
|
#define S_IRUSR DFS_S_IRUSR
|
||||||
#define S_IWUSR DFS_S_IWUSR
|
#define S_IWUSR DFS_S_IWUSR
|
||||||
#define S_IXUSR DFS_S_IXUSR
|
#define S_IXUSR DFS_S_IXUSR
|
||||||
|
|
||||||
#define S_IRWXG DFS_S_IRWXG
|
#define S_IRWXG DFS_S_IRWXG
|
||||||
#define S_IRGRP DFS_S_IRGRP
|
#define S_IRGRP DFS_S_IRGRP
|
||||||
#define S_IWGRP DFS_S_IWGRP
|
#define S_IWGRP DFS_S_IWGRP
|
||||||
#define S_IXGRP DFS_S_IXGRP
|
#define S_IXGRP DFS_S_IXGRP
|
||||||
|
|
||||||
#define S_IRWXO DFS_S_IRWXO
|
#define S_IRWXO DFS_S_IRWXO
|
||||||
#define S_IROTH DFS_S_IROTH
|
#define S_IROTH DFS_S_IROTH
|
||||||
#define S_IWOTH DFS_S_IWOTH
|
#define S_IWOTH DFS_S_IWOTH
|
||||||
#define S_IXOTH DFS_S_IXOTH
|
#define S_IXOTH DFS_S_IXOTH
|
||||||
|
|
||||||
#if defined(__CC_ARM)
|
#if defined(__CC_ARM)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#else
|
#else
|
||||||
#define SEEK_SET DFS_SEEK_SET
|
#define SEEK_SET DFS_SEEK_SET
|
||||||
#define SEEK_CUR DFS_SEEK_CUR
|
#define SEEK_CUR DFS_SEEK_CUR
|
||||||
#define SEEK_END DFS_SEEK_END
|
#define SEEK_END DFS_SEEK_END
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int fd; /* directory file */
|
int fd; /* directory file */
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int num;
|
int num;
|
||||||
int cur;
|
int cur;
|
||||||
} DIR;
|
} DIR;
|
||||||
|
|
||||||
/* directory api*/
|
/* directory api*/
|
||||||
int mkdir (const char *path, mode_t mode);
|
int mkdir (const char *path, mode_t mode);
|
||||||
DIR* opendir(const char* name);
|
DIR* opendir(const char* name);
|
||||||
struct dirent* readdir(DIR *d);
|
struct dirent* readdir(DIR *d);
|
||||||
long telldir(DIR *d);
|
long telldir(DIR *d);
|
||||||
void seekdir(DIR *d, off_t offset);
|
void seekdir(DIR *d, off_t offset);
|
||||||
void rewinddir(DIR *d);
|
void rewinddir(DIR *d);
|
||||||
int closedir(DIR* d);
|
int closedir(DIR* d);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* use newlib header file */
|
/* use newlib header file */
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 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);
|
||||||
int read(int fd, void *buf, size_t len);
|
int read(int fd, void *buf, size_t len);
|
||||||
int write(int fd, const void *buf, size_t len);
|
int write(int fd, const void *buf, size_t len);
|
||||||
off_t lseek(int fd, off_t offset, int whence);
|
off_t lseek(int fd, off_t offset, int whence);
|
||||||
int rename(const char *from, const char *to);
|
int rename(const char *from, const char *to);
|
||||||
int unlink(const char *pathname);
|
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 statfs(const char *path, struct statfs *buf);
|
int statfs(const char *path, struct statfs *buf);
|
||||||
|
|
||||||
/* directory api*/
|
/* directory api*/
|
||||||
int rmdir(const char *path);
|
int rmdir(const char *path);
|
||||||
int chdir(const char *path);
|
int chdir(const char *path);
|
||||||
char *getcwd(char *buf, size_t size);
|
char *getcwd(char *buf, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,365 +1,365 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs.c
|
* File : dfs.c
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
* This file is part of Device File System in RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rt-thread.org/license/LICENSE.
|
* http://www.rt-thread.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2005-02-22 Bernard The first version.
|
* 2005-02-22 Bernard The first version.
|
||||||
* 2010-07-16
|
* 2010-07-16
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
|
|
||||||
#define NO_WORKING_DIR "system does not support working dir\n"
|
#define NO_WORKING_DIR "system does not support working dir\n"
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
const struct dfs_filesystem_operation* filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
|
const struct dfs_filesystem_operation* 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 */
|
||||||
static struct rt_mutex fslock;
|
static struct rt_mutex fslock;
|
||||||
|
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
char working_directory[DFS_PATH_MAX] = {"/"};
|
char working_directory[DFS_PATH_MAX] = {"/"};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DFS_USING_STDIO
|
#ifdef DFS_USING_STDIO
|
||||||
struct dfs_fd fd_table[3 + DFS_FD_MAX];
|
struct dfs_fd fd_table[3 + DFS_FD_MAX];
|
||||||
#else
|
#else
|
||||||
struct dfs_fd fd_table[DFS_FD_MAX];
|
struct dfs_fd fd_table[DFS_FD_MAX];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup DFS
|
* @addtogroup DFS
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will initialize device file system.
|
* this function will initialize device file system.
|
||||||
*/
|
*/
|
||||||
void dfs_init()
|
void dfs_init()
|
||||||
{
|
{
|
||||||
/* clear filesystem operations table */
|
/* clear filesystem operations table */
|
||||||
rt_memset(filesystem_operation_table, 0, sizeof(filesystem_operation_table));
|
rt_memset(filesystem_operation_table, 0, sizeof(filesystem_operation_table));
|
||||||
/* clear filesystem table */
|
/* clear filesystem table */
|
||||||
rt_memset(filesystem_table, 0, sizeof(filesystem_table));
|
rt_memset(filesystem_table, 0, sizeof(filesystem_table));
|
||||||
/* clean fd table */
|
/* clean fd table */
|
||||||
rt_memset(fd_table, 0, sizeof(fd_table));
|
rt_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));
|
rt_memset(working_directory, 0, sizeof(working_directory));
|
||||||
working_directory[0] = '/';
|
working_directory[0] = '/';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will lock device file system.
|
* this function will lock device file system.
|
||||||
*
|
*
|
||||||
* @note please don't invoke it on ISR.
|
* @note please don't invoke it on ISR.
|
||||||
*/
|
*/
|
||||||
void dfs_lock()
|
void dfs_lock()
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
|
result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
|
||||||
if (result != RT_EOK)
|
if (result != RT_EOK)
|
||||||
{
|
{
|
||||||
RT_ASSERT(0);
|
RT_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will lock device file system.
|
* this function will lock device file system.
|
||||||
*
|
*
|
||||||
* @note please don't invoke it on ISR.
|
* @note please don't invoke it on ISR.
|
||||||
*/
|
*/
|
||||||
void dfs_unlock()
|
void dfs_unlock()
|
||||||
{
|
{
|
||||||
rt_mutex_release(&fslock);
|
rt_mutex_release(&fslock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup Fd
|
* @ingroup Fd
|
||||||
* This function will allocate a file descriptor.
|
* This function will allocate a file descriptor.
|
||||||
*
|
*
|
||||||
* @return -1 on failed or the allocated file descriptor.
|
* @return -1 on failed or the allocated file descriptor.
|
||||||
*/
|
*/
|
||||||
int fd_new(void)
|
int fd_new(void)
|
||||||
{
|
{
|
||||||
struct dfs_fd* d;
|
struct dfs_fd* d;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
|
|
||||||
/* find an empty fd entry */
|
/* find an empty fd entry */
|
||||||
#ifdef DFS_USING_STDIO
|
#ifdef DFS_USING_STDIO
|
||||||
for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++);
|
for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++);
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
/* can't find an empty fd entry */
|
/* can't find an empty fd entry */
|
||||||
#ifdef DFS_USING_STDIO
|
#ifdef DFS_USING_STDIO
|
||||||
if (idx == DFS_FD_MAX + 3)
|
if (idx == DFS_FD_MAX + 3)
|
||||||
#else
|
#else
|
||||||
if (idx == DFS_FD_MAX)
|
if (idx == DFS_FD_MAX)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
idx = -1;
|
idx = -1;
|
||||||
goto __result;
|
goto __result;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = &(fd_table[idx]);
|
d = &(fd_table[idx]);
|
||||||
d->ref_count = 1;
|
d->ref_count = 1;
|
||||||
|
|
||||||
__result:
|
__result:
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup Fd
|
* @ingroup Fd
|
||||||
*
|
*
|
||||||
* This function will return a file descriptor structure according to file
|
* This function will return a file descriptor structure according to file
|
||||||
* descriptor.
|
* descriptor.
|
||||||
*
|
*
|
||||||
* @return NULL on on this file descriptor or the file descriptor structure
|
* @return NULL on on this file descriptor or the file descriptor structure
|
||||||
* pointer.
|
* pointer.
|
||||||
*/
|
*/
|
||||||
struct dfs_fd* fd_get(int fd)
|
struct dfs_fd* fd_get(int fd)
|
||||||
{
|
{
|
||||||
struct dfs_fd* d;
|
struct dfs_fd* d;
|
||||||
|
|
||||||
#ifdef DFS_USING_STDIO
|
#ifdef DFS_USING_STDIO
|
||||||
if ( fd < 3 || fd > DFS_FD_MAX + 3) return RT_NULL;
|
if ( fd < 3 || fd > DFS_FD_MAX + 3) return RT_NULL;
|
||||||
#else
|
#else
|
||||||
if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL;
|
if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
d = &fd_table[fd];
|
d = &fd_table[fd];
|
||||||
|
|
||||||
/* increase the reference count */
|
/* increase the reference count */
|
||||||
d->ref_count ++;
|
d->ref_count ++;
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup Fd
|
* @ingroup Fd
|
||||||
*
|
*
|
||||||
* This function will put the file descriptor.
|
* This function will put the file descriptor.
|
||||||
*/
|
*/
|
||||||
void fd_put(struct dfs_fd* fd)
|
void fd_put(struct dfs_fd* fd)
|
||||||
{
|
{
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
fd->ref_count --;
|
fd->ref_count --;
|
||||||
|
|
||||||
/* 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));
|
rt_memset(fd, 0, sizeof(struct dfs_fd));
|
||||||
}
|
}
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup Fd
|
* @ingroup Fd
|
||||||
*
|
*
|
||||||
* This function will return whether this file has been opend.
|
* This function will return whether this file has been opend.
|
||||||
*
|
*
|
||||||
* @param pathname the file path name.
|
* @param pathname the file path name.
|
||||||
*
|
*
|
||||||
* @return 0 on file has been open successfully, -1 on open failed.
|
* @return 0 on file has been open successfully, -1 on open failed.
|
||||||
*/
|
*/
|
||||||
int fd_is_open(const char* pathname)
|
int fd_is_open(const char* pathname)
|
||||||
{
|
{
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
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(RT_NULL, pathname);
|
||||||
if (fullpath != RT_NULL)
|
if (fullpath != RT_NULL)
|
||||||
{
|
{
|
||||||
char *mountpath;
|
char *mountpath;
|
||||||
fs = dfs_filesystem_lookup(fullpath);
|
fs = dfs_filesystem_lookup(fullpath);
|
||||||
if (fs == RT_NULL)
|
if (fs == RT_NULL)
|
||||||
{
|
{
|
||||||
/* can't find mounted file system */
|
/* can't find mounted file system */
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get file path name under mounted file system */
|
/* get file path name under mounted file system */
|
||||||
if (fs->path[0] == '/' && fs->path[1] == '\0')
|
if (fs->path[0] == '/' && fs->path[1] == '\0')
|
||||||
mountpath = fullpath;
|
mountpath = fullpath;
|
||||||
else mountpath = fullpath + strlen(fs->path);
|
else mountpath = fullpath + strlen(fs->path);
|
||||||
|
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
for (index = 0; index < DFS_FD_MAX; index++)
|
for (index = 0; index < DFS_FD_MAX; index++)
|
||||||
{
|
{
|
||||||
fd = &(fd_table[index]);
|
fd = &(fd_table[index]);
|
||||||
if (fd->fs == RT_NULL) continue;
|
if (fd->fs == RT_NULL) continue;
|
||||||
|
|
||||||
if (fd->fs == fs &&
|
if (fd->fs == fs &&
|
||||||
strcmp(fd->path, mountpath) == 0)
|
strcmp(fd->path, mountpath) == 0)
|
||||||
{
|
{
|
||||||
/* found file in file descriptor table */
|
/* found file in file descriptor table */
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will return a sub-path name under directory.
|
* this function will return a sub-path name under directory.
|
||||||
*
|
*
|
||||||
* @param directory the parent directory.
|
* @param directory the parent directory.
|
||||||
* @param filename the filename.
|
* @param filename the filename.
|
||||||
*
|
*
|
||||||
* @return the subdir pointer in filename
|
* @return the subdir pointer in filename
|
||||||
*/
|
*/
|
||||||
const char* dfs_subdir(const char* directory, const char* filename)
|
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 RT_NULL;
|
||||||
|
|
||||||
dir = filename + strlen(directory);
|
dir = filename + strlen(directory);
|
||||||
if ((*dir != '/') && (dir != filename))
|
if ((*dir != '/') && (dir != filename))
|
||||||
{
|
{
|
||||||
dir --;
|
dir --;
|
||||||
}
|
}
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will normalize a path according to specified parent directory and file name.
|
* this function will normalize a path according to specified parent directory and file name.
|
||||||
*
|
*
|
||||||
* @param directory the parent path
|
* @param directory the parent path
|
||||||
* @param filename the file name
|
* @param filename the file name
|
||||||
*
|
*
|
||||||
* @return the built full file path (absoluted path)
|
* @return the built full file path (absoluted path)
|
||||||
*/
|
*/
|
||||||
char* dfs_normalize_path(const char* directory, const char* filename)
|
char* dfs_normalize_path(const char* directory, const char* filename)
|
||||||
{
|
{
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
char *dst0, *dst, *src;
|
char *dst0, *dst, *src;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
RT_ASSERT(filename != RT_NULL);
|
RT_ASSERT(filename != RT_NULL);
|
||||||
|
|
||||||
#ifdef DFS_USING_WORKDIR
|
#ifdef DFS_USING_WORKDIR
|
||||||
if (directory == NULL) /* shall use working directory */
|
if (directory == NULL) /* shall use working directory */
|
||||||
directory = &working_directory[0];
|
directory = &working_directory[0];
|
||||||
#else
|
#else
|
||||||
if ((directory == NULL) && (filename[0] != '/'))
|
if ((directory == NULL) && (filename[0] != '/'))
|
||||||
{
|
{
|
||||||
rt_kprintf(NO_WORKING_DIR);
|
rt_kprintf(NO_WORKING_DIR);
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (filename[0] != '/') /* it's a absolute path, use it directly */
|
if (filename[0] != '/') /* it's a absolute path, use it directly */
|
||||||
{
|
{
|
||||||
fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
|
fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
|
||||||
|
|
||||||
/* 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,
|
||||||
"%s/%s", directory, filename);
|
"%s/%s", directory, filename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fullpath = rt_strdup(filename); /* copy string */
|
fullpath = rt_strdup(filename); /* copy string */
|
||||||
}
|
}
|
||||||
|
|
||||||
src = fullpath;
|
src = fullpath;
|
||||||
dst = fullpath;
|
dst = fullpath;
|
||||||
|
|
||||||
dst0 = dst;
|
dst0 = dst;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
char c = *src;
|
char c = *src;
|
||||||
|
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
{
|
{
|
||||||
if (!src[1]) src ++; /* '.' and ends */
|
if (!src[1]) src ++; /* '.' and ends */
|
||||||
else if (src[1] == '/')
|
else if (src[1] == '/')
|
||||||
{
|
{
|
||||||
/* './' case */
|
/* './' case */
|
||||||
src += 2;
|
src += 2;
|
||||||
|
|
||||||
while ((*src == '/') && (*src != '\0')) src ++;
|
while ((*src == '/') && (*src != '\0')) src ++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (src[1] == '.')
|
else if (src[1] == '.')
|
||||||
{
|
{
|
||||||
if (!src[2])
|
if (!src[2])
|
||||||
{
|
{
|
||||||
/* '..' and ends case */
|
/* '..' and ends case */
|
||||||
src += 2;
|
src += 2;
|
||||||
goto up_one;
|
goto up_one;
|
||||||
}
|
}
|
||||||
else if (src[2] == '/')
|
else if (src[2] == '/')
|
||||||
{
|
{
|
||||||
/* '../' case */
|
/* '../' case */
|
||||||
src += 3;
|
src += 3;
|
||||||
|
|
||||||
while ((*src == '/') && (*src != '\0')) src ++;
|
while ((*src == '/') && (*src != '\0')) src ++;
|
||||||
goto up_one;
|
goto up_one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy up the next '/' and erase all '/' */
|
/* copy up the next '/' and erase all '/' */
|
||||||
while ((c = *src++) != '\0' && c != '/') *dst ++ = c;
|
while ((c = *src++) != '\0' && c != '/') *dst ++ = c;
|
||||||
|
|
||||||
if (c == '/')
|
if (c == '/')
|
||||||
{
|
{
|
||||||
*dst ++ = '/';
|
*dst ++ = '/';
|
||||||
while (c == '/') c = *src++;
|
while (c == '/') c = *src++;
|
||||||
|
|
||||||
src --;
|
src --;
|
||||||
}
|
}
|
||||||
else if (!c) break;
|
else if (!c) break;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
up_one:
|
up_one:
|
||||||
dst --;
|
dst --;
|
||||||
if (dst < dst0) { rt_free(fullpath); return NULL;}
|
if (dst < dst0) { rt_free(fullpath); return NULL;}
|
||||||
while (dst0 < dst && dst[-1] != '/') dst --;
|
while (dst0 < dst && dst[-1] != '/') dst --;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
|
|
||||||
/* remove '/' in the end of path if exist */
|
/* remove '/' in the end of path if exist */
|
||||||
dst --;
|
dst --;
|
||||||
if ((dst != fullpath) && (*dst == '/')) *dst = '\0';
|
if ((dst != fullpath) && (*dst == '/')) *dst = '\0';
|
||||||
|
|
||||||
return fullpath;
|
return fullpath;
|
||||||
}
|
}
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,460 +1,460 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs_fs.c
|
* File : dfs_fs.c
|
||||||
* This file is part of Device File System in RT-Thread RTOS
|
* This file is part of Device File System in RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
* COPYRIGHT (C) 2004-2010, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rt-thread.org/license/LICENSE.
|
* http://www.rt-thread.org/license/LICENSE.
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2005-02-22 Bernard The first version.
|
* 2005-02-22 Bernard The first version.
|
||||||
* 2010-06-30 Bernard Optimize for RT-Thread RTOS
|
* 2010-06-30 Bernard Optimize for RT-Thread RTOS
|
||||||
* 2011-03-12 Bernard fix the filesystem lookup issue.
|
* 2011-03-12 Bernard fix the filesystem lookup issue.
|
||||||
*/
|
*/
|
||||||
#include <dfs_fs.h>
|
#include <dfs_fs.h>
|
||||||
#include <dfs_file.h>
|
#include <dfs_file.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup FsApi
|
* @addtogroup FsApi
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will register a file system instance to device file system.
|
* this function will register a file system instance to device file system.
|
||||||
*
|
*
|
||||||
* @param ops the file system instance to be registered.
|
* @param ops the file system instance to be registered.
|
||||||
*
|
*
|
||||||
* @return 0 on sucessful, -1 on failed.
|
* @return 0 on sucessful, -1 on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_register(const struct dfs_filesystem_operation* ops)
|
int dfs_register(const struct dfs_filesystem_operation* ops)
|
||||||
{
|
{
|
||||||
int index, result;
|
int index, result;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
|
|
||||||
/* check if this filesystem was already registered */
|
/* check if this filesystem was already registered */
|
||||||
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] != RT_NULL &&
|
||||||
strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
|
strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find out an empty filesystem type entry */
|
/* find out an empty filesystem type entry */
|
||||||
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX && filesystem_operation_table[index] != RT_NULL;
|
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX && filesystem_operation_table[index] != RT_NULL;
|
||||||
index++) ;
|
index++) ;
|
||||||
|
|
||||||
/* filesystem type table full */
|
/* filesystem type table full */
|
||||||
if (index == DFS_FILESYSTEM_TYPES_MAX)
|
if (index == DFS_FILESYSTEM_TYPES_MAX)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the filesystem's operations */
|
/* save the filesystem's operations */
|
||||||
filesystem_operation_table[index] = ops;
|
filesystem_operation_table[index] = ops;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will return the file system mounted on specified path.
|
* this function will return the file system mounted on specified path.
|
||||||
*
|
*
|
||||||
* @param path the specified path string.
|
* @param path the specified path string.
|
||||||
*
|
*
|
||||||
* @return the found file system or NULL if no file system mounted on
|
* @return the found file system or NULL if no file system mounted on
|
||||||
* specified path
|
* specified path
|
||||||
*/
|
*/
|
||||||
struct dfs_filesystem* dfs_filesystem_lookup(const char *path)
|
struct dfs_filesystem* dfs_filesystem_lookup(const char *path)
|
||||||
{
|
{
|
||||||
struct dfs_filesystem* fs;
|
struct dfs_filesystem* fs;
|
||||||
rt_uint32_t index, fspath, prefixlen;
|
rt_uint32_t index, fspath, prefixlen;
|
||||||
|
|
||||||
fs = RT_NULL;
|
fs = RT_NULL;
|
||||||
prefixlen = 0;
|
prefixlen = 0;
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
|
|
||||||
/* lookup it in the filesystem table */
|
/* lookup it in the filesystem table */
|
||||||
for (index = 0; index < DFS_FILESYSTEMS_MAX; index++)
|
for (index = 0; index < DFS_FILESYSTEMS_MAX; index++)
|
||||||
{
|
{
|
||||||
if (filesystem_table[index].path == RT_NULL) continue;
|
if (filesystem_table[index].path == RT_NULL) continue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fspath = strlen(filesystem_table[index].path);
|
fspath = strlen(filesystem_table[index].path);
|
||||||
if (fspath < prefixlen) continue;
|
if (fspath < prefixlen) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((filesystem_table[index].ops != RT_NULL) &&
|
if ((filesystem_table[index].ops != RT_NULL) &&
|
||||||
(strncmp(filesystem_table[index].path, path, fspath) == 0))
|
(strncmp(filesystem_table[index].path, path, fspath) == 0))
|
||||||
{
|
{
|
||||||
/* check next path separator */
|
/* check next path separator */
|
||||||
if ( fspath > 1 && (strlen(path) > fspath) &&
|
if ( fspath > 1 && (strlen(path) > fspath) &&
|
||||||
(path[fspath] != '/')) continue;
|
(path[fspath] != '/')) continue;
|
||||||
|
|
||||||
fs = &filesystem_table[index];
|
fs = &filesystem_table[index];
|
||||||
prefixlen = fspath;
|
prefixlen = fspath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will fetch the partition table on specified buffer.
|
* this function will fetch the partition table on specified buffer.
|
||||||
*
|
*
|
||||||
* @param part the returned partition structure.
|
* @param part the returned partition structure.
|
||||||
* @param buf the buffer contains partition table.
|
* @param buf the buffer contains partition table.
|
||||||
* @param pindex the index of partition table to fetch.
|
* @param pindex the index of partition table to fetch.
|
||||||
*
|
*
|
||||||
* @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, rt_uint8_t* buf, rt_uint32_t pindex)
|
rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_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;
|
rt_uint8_t* dpt;
|
||||||
rt_uint8_t type;
|
rt_uint8_t type;
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
RT_ASSERT(part != RT_NULL);
|
RT_ASSERT(part != RT_NULL);
|
||||||
RT_ASSERT(buf != RT_NULL);
|
RT_ASSERT(buf != RT_NULL);
|
||||||
|
|
||||||
result = RT_EOK;
|
result = RT_EOK;
|
||||||
|
|
||||||
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
|
dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
|
||||||
|
|
||||||
if ((*dpt != 0x80) && (*dpt != 0x00))
|
if ((*dpt != 0x80) && (*dpt != 0x00))
|
||||||
{
|
{
|
||||||
/* which is not a partition table */
|
/* which is not a partition table */
|
||||||
result = -RT_ERROR;
|
result = -RT_ERROR;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get partition type */
|
/* get partition type */
|
||||||
type = *(dpt+4);
|
type = *(dpt+4);
|
||||||
|
|
||||||
if (type != 0)
|
if (type != 0)
|
||||||
{
|
{
|
||||||
/* set partition type */
|
/* set partition type */
|
||||||
part->type = type;
|
part->type = type;
|
||||||
|
|
||||||
/* get partition offset and size */
|
/* get partition offset and size */
|
||||||
part->offset = *(dpt+ 8) | *(dpt+ 9) << 8 |
|
part->offset = *(dpt+ 8) | *(dpt+ 9) << 8 |
|
||||||
*(dpt+10) << 16 | *(dpt+11) << 24;
|
*(dpt+10) << 16 | *(dpt+11) << 24;
|
||||||
part->size = *(dpt+12) | *(dpt+13) << 8 |
|
part->size = *(dpt+12) | *(dpt+13) << 8 |
|
||||||
*(dpt+14) << 16 | *(dpt+15) << 24;
|
*(dpt+14) << 16 | *(dpt+15) << 24;
|
||||||
|
|
||||||
rt_kprintf("found part[%d], begin: %d, size: ",
|
rt_kprintf("found part[%d], begin: %d, size: ",
|
||||||
pindex, part->offset * 512);
|
pindex, part->offset * 512);
|
||||||
if ( (part->size>>11) > 0 ) /* MB */
|
if ( (part->size>>11) > 0 ) /* MB */
|
||||||
{
|
{
|
||||||
unsigned int part_size;
|
unsigned int part_size;
|
||||||
part_size = part->size>>11;/* MB */
|
part_size = part->size>>11;/* MB */
|
||||||
if ( (part_size>>10) > 0) /* GB */
|
if ( (part_size>>10) > 0) /* GB */
|
||||||
{
|
{
|
||||||
rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\r\n");/* GB */
|
rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\r\n");/* GB */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n");/* MB */
|
rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n");/* MB */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_kprintf("%d%s",part->size>>1,"KB\r\n");/* KB */
|
rt_kprintf("%d%s",part->size>>1,"KB\r\n");/* KB */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = -RT_ERROR;
|
result = -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will mount a file system on a specified path.
|
* this function will mount a file system on a specified path.
|
||||||
*
|
*
|
||||||
* @param device_name the name of device which includes a file system.
|
* @param device_name the name of device which includes a file system.
|
||||||
* @param path the path to mount a file system
|
* @param path the path to mount a file system
|
||||||
* @param filesystemtype the file system type
|
* @param filesystemtype the file system type
|
||||||
* @param rwflag the read/write etc. flag.
|
* @param rwflag the read/write etc. flag.
|
||||||
* @param data the private data(parameter) for this file system.
|
* @param data the private data(parameter) for this file system.
|
||||||
*
|
*
|
||||||
* @return 0 on successful or -1 on failed.
|
* @return 0 on successful or -1 on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_mount(const char* device_name, const char* path,
|
int dfs_mount(const char* device_name, const char* path,
|
||||||
const char* filesystemtype, unsigned long rwflag, const
|
const char* filesystemtype, unsigned long rwflag, const
|
||||||
void* data)
|
void* data)
|
||||||
{
|
{
|
||||||
const struct dfs_filesystem_operation* ops;
|
const struct dfs_filesystem_operation* ops;
|
||||||
struct dfs_filesystem* fs;
|
struct dfs_filesystem* fs;
|
||||||
char *fullpath=RT_NULL;
|
char *fullpath=RT_NULL;
|
||||||
rt_device_t dev_id;
|
rt_device_t dev_id;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
/* open specific device */
|
/* open specific device */
|
||||||
if (device_name != RT_NULL)
|
if (device_name != RT_NULL)
|
||||||
{
|
{
|
||||||
dev_id = rt_device_find(device_name);
|
dev_id = rt_device_find(device_name);
|
||||||
if (dev_id == RT_NULL)
|
if (dev_id == RT_NULL)
|
||||||
{
|
{
|
||||||
/* no this device */
|
/* no this device */
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-DFS_STATUS_ENODEV);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* which is a non-device filesystem mount */
|
/* which is a non-device filesystem mount */
|
||||||
dev_id = RT_NULL;
|
dev_id = RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find out specific filesystem */
|
/* find out specific filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
for ( index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++ )
|
for ( index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++ )
|
||||||
{
|
{
|
||||||
if (strcmp(filesystem_operation_table[index]->name, filesystemtype) == 0)break;
|
if (strcmp(filesystem_operation_table[index]->name, filesystemtype) == 0)break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can't find filesystem */
|
/* can't find filesystem */
|
||||||
if ( index == DFS_FILESYSTEM_TYPES_MAX )
|
if ( index == DFS_FILESYSTEM_TYPES_MAX )
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENODEV);
|
rt_set_errno(-DFS_STATUS_ENODEV);
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ops = filesystem_operation_table[index];
|
ops = filesystem_operation_table[index];
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
/* make full path for special file */
|
/* make full path for special file */
|
||||||
fullpath = dfs_normalize_path(RT_NULL, path);
|
fullpath = dfs_normalize_path(RT_NULL, path);
|
||||||
if ( fullpath == RT_NULL) /* not an abstract path */
|
if ( fullpath == RT_NULL) /* not an abstract path */
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the path exists or not, raw APIs call, fixme */
|
/* Check if the path exists or not, raw APIs call, fixme */
|
||||||
if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) )
|
if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) )
|
||||||
{
|
{
|
||||||
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, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0 )
|
||||||
{
|
{
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dfs_file_close(&fd);
|
dfs_file_close(&fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether the file system mounted or not */
|
/* check whether the file system mounted or not */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
for (index =0; index < DFS_FILESYSTEMS_MAX; index++)
|
for (index =0; index < DFS_FILESYSTEMS_MAX; index++)
|
||||||
{
|
{
|
||||||
if ( filesystem_table[index].ops != RT_NULL &&
|
if ( filesystem_table[index].ops != RT_NULL &&
|
||||||
strcmp(filesystem_table[index].path, path) == 0 )
|
strcmp(filesystem_table[index].path, path) == 0 )
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
rt_set_errno(-DFS_STATUS_EINVAL);
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find out en empty filesystem table entry */
|
/* find out en empty filesystem table entry */
|
||||||
for (index = 0; index < DFS_FILESYSTEMS_MAX && filesystem_table[index].ops != RT_NULL;
|
for (index = 0; index < DFS_FILESYSTEMS_MAX && filesystem_table[index].ops != RT_NULL;
|
||||||
index++) ;
|
index++) ;
|
||||||
if ( index == DFS_FILESYSTEMS_MAX ) /* can't find en empty filesystem table entry */
|
if ( index == DFS_FILESYSTEMS_MAX ) /* can't find en empty filesystem table entry */
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOSPC);
|
rt_set_errno(-DFS_STATUS_ENOSPC);
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register file system */
|
/* register file system */
|
||||||
fs = &(filesystem_table[index]);
|
fs = &(filesystem_table[index]);
|
||||||
fs->path = fullpath;
|
fs->path = fullpath;
|
||||||
fs->ops = ops;
|
fs->ops = ops;
|
||||||
fs->dev_id = dev_id;
|
fs->dev_id = dev_id;
|
||||||
/* release filesystem_table lock */
|
/* release filesystem_table lock */
|
||||||
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) rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
|
if (dev_id != RT_NULL) rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
|
||||||
|
|
||||||
if (ops->mount == RT_NULL) /* there is no mount implementation */
|
if (ops->mount == RT_NULL) /* there is no mount implementation */
|
||||||
{
|
{
|
||||||
if (dev_id != RT_NULL) rt_device_close(dev_id);
|
if (dev_id != RT_NULL) rt_device_close(dev_id);
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
/* clear filesystem table entry */
|
/* clear filesystem table entry */
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
rt_set_errno(-DFS_STATUS_ENOSYS);
|
rt_set_errno(-DFS_STATUS_ENOSYS);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* call mount of this filesystem */
|
/* call mount of this filesystem */
|
||||||
else if (ops->mount(fs, rwflag, data) < 0)
|
else if (ops->mount(fs, rwflag, data) < 0)
|
||||||
{
|
{
|
||||||
/* close device */
|
/* close device */
|
||||||
if (dev_id != RT_NULL) rt_device_close(fs->dev_id);
|
if (dev_id != RT_NULL) 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));
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
if (fullpath != RT_NULL) rt_free(fullpath);
|
if (fullpath != RT_NULL) rt_free(fullpath);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will umount a file system on specified path.
|
* this function will umount a file system on specified path.
|
||||||
*
|
*
|
||||||
* @param specialfile the specified path which mounted a file system.
|
* @param specialfile the specified path which mounted a file system.
|
||||||
*
|
*
|
||||||
* @return 0 on successful or -1 on failed.
|
* @return 0 on successful or -1 on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_unmount(const char *specialfile)
|
int dfs_unmount(const char *specialfile)
|
||||||
{
|
{
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
struct dfs_filesystem* fs = RT_NULL;
|
struct dfs_filesystem* fs = RT_NULL;
|
||||||
|
|
||||||
fullpath = dfs_normalize_path(RT_NULL, specialfile);
|
fullpath = dfs_normalize_path(RT_NULL, specialfile);
|
||||||
if (fullpath == RT_NULL)
|
if (fullpath == RT_NULL)
|
||||||
{
|
{
|
||||||
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
rt_set_errno(-DFS_STATUS_ENOTDIR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
|
|
||||||
fs = dfs_filesystem_lookup(fullpath);
|
fs = dfs_filesystem_lookup(fullpath);
|
||||||
if (fs != RT_NULL && fs->ops->unmount != RT_NULL && fs->ops->unmount(fs) < 0)
|
if (fs != RT_NULL && fs->ops->unmount != RT_NULL && 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 != RT_NULL)
|
||||||
rt_device_close(fs->dev_id);
|
rt_device_close(fs->dev_id);
|
||||||
|
|
||||||
/* clear this filesystem table entry */
|
/* clear this filesystem table entry */
|
||||||
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
rt_memset(fs, 0, sizeof(struct dfs_filesystem));
|
||||||
|
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
rt_free(fullpath);
|
rt_free(fullpath);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* make a file system on the special device
|
* make a file system on the special device
|
||||||
*
|
*
|
||||||
* @param fs_name the file system name
|
* @param fs_name the file system name
|
||||||
* @param device_name the special device name
|
* @param device_name the special device name
|
||||||
*
|
*
|
||||||
* @return 0 on successful, otherwise failed.
|
* @return 0 on successful, otherwise failed.
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
/* lock filesystem */
|
/* lock filesystem */
|
||||||
dfs_lock();
|
dfs_lock();
|
||||||
/* 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] != RT_NULL &&
|
||||||
strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
|
strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
|
||||||
{
|
{
|
||||||
/* find file system operation */
|
/* find file system operation */
|
||||||
const struct dfs_filesystem_operation* ops = filesystem_operation_table[index];
|
const struct dfs_filesystem_operation* ops = filesystem_operation_table[index];
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
if (ops->mkfs != RT_NULL)
|
if (ops->mkfs != RT_NULL)
|
||||||
return ops->mkfs(device_name);
|
return ops->mkfs(device_name);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dfs_unlock();
|
dfs_unlock();
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function will return the information about a mounted file system.
|
* this function will return the information about a mounted file system.
|
||||||
*
|
*
|
||||||
* @param path the path which mounted file system.
|
* @param path the path which mounted file system.
|
||||||
* @param buffer the buffer to save the returned information.
|
* @param buffer the buffer to save the returned information.
|
||||||
*
|
*
|
||||||
* @return 0 on successful, others on failed.
|
* @return 0 on successful, others on failed.
|
||||||
*/
|
*/
|
||||||
int dfs_statfs(const char* path, struct statfs* buffer)
|
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 != NULL)
|
if (fs != NULL)
|
||||||
{
|
{
|
||||||
if (fs->ops->statfs!= RT_NULL)
|
if (fs->ops->statfs!= RT_NULL)
|
||||||
return fs->ops->statfs(fs, buffer);
|
return fs->ops->statfs(fs, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RT_USING_FINSH
|
#ifdef RT_USING_FINSH
|
||||||
#include <finsh.h>
|
#include <finsh.h>
|
||||||
void mkfs(const char* fs_name, const char* device_name)
|
void mkfs(const char* fs_name, const char* device_name)
|
||||||
{
|
{
|
||||||
dfs_mkfs(fs_name, device_name);
|
dfs_mkfs(fs_name, device_name);
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(mkfs, make a file system);
|
FINSH_FUNCTION_EXPORT(mkfs, make a file system);
|
||||||
|
|
||||||
void df(const char* path)
|
void df(const char* path)
|
||||||
{
|
{
|
||||||
struct statfs buffer;
|
struct statfs buffer;
|
||||||
|
|
||||||
if (dfs_statfs(path, &buffer) == 0)
|
if (dfs_statfs(path, &buffer) == 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("disk free: %d block[%d bytes per block]\n", buffer.f_bfree, buffer.f_bsize);
|
rt_kprintf("disk free: %d block[%d bytes per block]\n", buffer.f_bfree, buffer.f_bsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FINSH_FUNCTION_EXPORT(df, get disk free);
|
FINSH_FUNCTION_EXPORT(df, get disk free);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue