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