summaryrefslogtreecommitdiff
path: root/components/dfs
diff options
context:
space:
mode:
author[email protected] <[email protected]>2011-10-08 14:50:08 +0000
committer[email protected] <[email protected]>2011-10-08 14:50:08 +0000
commitb2f92176865f623129e61a411568ef3b5e361836 (patch)
tree9bed58e4aa1457224d300313614fc58202cc7f19 /components/dfs
parent9278fe2a8c33acf45e85700a9bba982685a58e97 (diff)
change to UNIX end of line.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1746 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/dfs')
-rw-r--r--components/dfs/filesystems/devfs/console.c170
-rw-r--r--components/dfs/filesystems/devfs/devfs.c546
-rw-r--r--components/dfs/filesystems/devfs/devfs.h16
-rw-r--r--components/dfs/filesystems/nfs/rpc/auth.h208
-rw-r--r--components/dfs/filesystems/nfs/rpc/pmap.c120
-rw-r--r--components/dfs/filesystems/nfs/rpc/pmap.h116
-rw-r--r--components/dfs/include/dfs.h74
-rw-r--r--components/dfs/include/dfs_elm.h58
-rw-r--r--components/dfs/include/dfs_file.h70
-rw-r--r--components/dfs/include/dfs_fs.h178
-rw-r--r--components/dfs/include/dfs_init.h84
-rw-r--r--components/dfs/include/dfs_posix.h232
-rw-r--r--components/dfs/src/dfs.c730
-rw-r--r--components/dfs/src/dfs_file.c1178
-rw-r--r--components/dfs/src/dfs_fs.c920
-rw-r--r--components/dfs/src/dfs_posix.c1336
16 files changed, 3018 insertions, 3018 deletions
diff --git a/components/dfs/filesystems/devfs/console.c b/components/dfs/filesystems/devfs/console.c
index 46fc380460..cce707a817 100644
--- a/components/dfs/filesystems/devfs/console.c
+++ b/components/dfs/filesystems/devfs/console.c
@@ -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);
+ }
+}
+
diff --git a/components/dfs/filesystems/devfs/devfs.c b/components/dfs/filesystems/devfs/devfs.c
index 98f2146f6d..2a8e78df5e 100644
--- a/components/dfs/filesystems/devfs/devfs.c
+++ b/components/dfs/filesystems/devfs/devfs.c
@@ -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;
+}
+
diff --git a/components/dfs/filesystems/devfs/devfs.h b/components/dfs/filesystems/devfs/devfs.h
index 90583e979f..248aab91d7 100644
--- a/components/dfs/filesystems/devfs/devfs.h
+++ b/components/dfs/filesystems/devfs/devfs.h
@@ -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
diff --git a/components/dfs/filesystems/nfs/rpc/auth.h b/components/dfs/filesystems/nfs/rpc/auth.h
index e117e7e411..3351fbbf95 100644
--- a/components/dfs/filesystems/nfs/rpc/auth.h
+++ b/components/dfs/filesystems/nfs/rpc/auth.h
@@ -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
diff --git a/components/dfs/filesystems/nfs/rpc/pmap.c b/components/dfs/filesystems/nfs/rpc/pmap.c
index 0a1fb9af89..cbf5add2ab 100644
--- a/components/dfs/filesystems/nfs/rpc/pmap.c
+++ b/components/dfs/filesystems/nfs/rpc/pmap.c
@@ -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, &regs->pm_prog) &&
- xdr_u_long(xdrs, &regs->pm_vers) &&
- xdr_u_long(xdrs, &regs->pm_prot))
- return (xdr_u_long(xdrs, &regs->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, &regs->pm_prog) &&
+ xdr_u_long(xdrs, &regs->pm_vers) &&
+ xdr_u_long(xdrs, &regs->pm_prot))
+ return (xdr_u_long(xdrs, &regs->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);
+}
diff --git a/components/dfs/filesystems/nfs/rpc/pmap.h b/components/dfs/filesystems/nfs/rpc/pmap.h
index 96a67375bb..aaf28a331a 100644
--- a/components/dfs/filesystems/nfs/rpc/pmap.h
+++ b/components/dfs/filesystems/nfs/rpc/pmap.h
@@ -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
diff --git a/components/dfs/include/dfs.h b/components/dfs/include/dfs.h
index dc5d311bc6..04fe678387 100644
--- a/components/dfs/include/dfs.h
+++ b/components/dfs/include/dfs.h
@@ -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
diff --git a/components/dfs/include/dfs_elm.h b/components/dfs/include/dfs_elm.h
index dea7162080..c54ee83c1d 100644
--- a/components/dfs/include/dfs_elm.h
+++ b/components/dfs/include/dfs_elm.h
@@ -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
diff --git a/components/dfs/include/dfs_file.h b/components/dfs/include/dfs_file.h
index ab75916977..3cf6681924 100644
--- a/components/dfs/include/dfs_file.h
+++ b/components/dfs/include/dfs_file.h
@@ -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
+
diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h
index b04de24f0b..fafac355c1 100644
--- a/components/dfs/include/dfs_fs.h
+++ b/components/dfs/include/dfs_fs.h
@@ -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
diff --git a/components/dfs/include/dfs_init.h b/components/dfs/include/dfs_init.h
index 712ce61156..bc4e6faab5 100644
--- a/components/dfs/include/dfs_init.h
+++ b/components/dfs/include/dfs_init.h
@@ -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
diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h
index ad4d3fc167..2eee57a1a8 100644
--- a/components/dfs/include/dfs_posix.h
+++ b/components/dfs/include/dfs_posix.h
@@ -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
+
diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c
index eaf8650310..bf042a1b58 100644
--- a/components/dfs/src/dfs.c
+++ b/components/dfs/src/dfs.c
@@ -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;
+}
+/*@}*/
+
diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c
index 58d57ea3da..f102c15d32 100644
--- a/components/dfs/src/dfs_file.c
+++ b/components/dfs/src/dfs_file.c
@@ -1,589 +1,589 @@
-/*
- * File : dfs_file.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.
- */
-#include <dfs.h>
-#include <dfs_file.h>
-
-/**
- * @addtogroup FileApi
- */
-/*@{*/
-
-/**
- * this function will open a file which specified by path with specified flags.
- *
- * @param fd the file descriptor pointer to return the corresponding result.
- * @param path the spaciefied file path.
- * @param flags the flags for open operator.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_open(struct dfs_fd* fd, const char *path, int flags)
-{
- struct dfs_filesystem* fs;
- char *fullpath;
- int result;
-
- /* parameter check */
- if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;
-
- /* make sure we have an absolute path */
- fullpath = dfs_normalize_path(RT_NULL, path);
- if (fullpath == RT_NULL)
- {
- return -1;
- }
-
- dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
-
- /* find filesystem */
- fs = dfs_filesystem_lookup(fullpath);
- if ( fs == RT_NULL )
- {
- rt_free(fullpath); /* release path */
- return -DFS_STATUS_ENOENT;
- }
-
- dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
- fd->fs = fs;
-
- /* initilize the fd item */
- fd->type = FT_REGULAR;
- fd->flags = flags;
- fd->size = 0;
- fd->pos = 0;
-
- if (dfs_subdir(fs->path, fullpath) == RT_NULL)
- fd->path = rt_strdup("/");
- else
- fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
- rt_free(fullpath);
- dfs_log(DFS_DEBUG_INFO, ("actul file path: %s\n", fd->path));
-
- /* specific file system open routine */
- if (fs->ops->open == RT_NULL)
- {
- /* clear fd */
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(*fd));
-
- return -DFS_STATUS_ENOSYS;
- }
-
- if ((result = fs->ops->open(fd)) < 0)
- {
- /* clear fd */
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(*fd));
-
- dfs_log(DFS_DEBUG_INFO, ("open failed"));
-
- return result;
- }
-
- fd->flags |= DFS_F_OPEN;
- if ( flags & DFS_O_DIRECTORY )
- {
- fd->type = FT_DIRECTORY;
- fd->flags |= DFS_F_DIRECTORY;
- }
-
- dfs_log(DFS_DEBUG_INFO, ("open successful"));
- return 0;
-}
-
-/**
- * this function will close a file descriptor.
- *
- * @param fd the file descriptor to be closed.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_close(struct dfs_fd* fd)
-{
- int result = 0;
-
- if (fd != RT_NULL && fd->fs->ops->close != RT_NULL) result = fd->fs->ops->close(fd);
-
- /* close fd error, return */
- if ( result < 0 ) return result;
-
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(struct dfs_fd));
-
- return result;
-}
-
-/**
- * this function will perform a io control on a file descriptor.
- *
- * @param fd the file descriptor.
- * @param cmd the command to send to file descriptor.
- * @param args the argument to send to file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_ioctl(struct dfs_fd* fd, int cmd, void *args)
-{
- struct dfs_filesystem* fs;
-
- if (fd == RT_NULL || fd->type != FT_REGULAR) return -DFS_STATUS_EINVAL;
-
- fs = fd->fs;
- if (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args);
-
- return -DFS_STATUS_ENOSYS;
-}
-
-/**
- * this function will read specified length data from a file descriptor to a buffer.
- *
- * @param fd the file descriptor.
- * @param buf the buffer to save the read data.
- * @param len the length of data buffer to be read.
- *
- * @return the actual read data bytes or 0 on end of file or failed.
- */
-int dfs_file_read(struct dfs_fd* fd, void *buf, rt_size_t len)
-{
- struct dfs_filesystem* fs;
- int result = 0;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = (struct dfs_filesystem*) fd->fs;
- if (fs->ops->read == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- if ( (result = fs->ops->read(fd, buf, len)) < 0 ) fd->flags |= DFS_F_EOF;
-
- return result;
-}
-
-/**
- * this function will fetch directory entries from a directory descriptor.
- *
- * @param fd the directory decriptor.
- * @param dirp the dirent buffer to save result.
- * @param nbytes the aviable room in the buffer.
- *
- * @return the read dirent, others on failed.
- */
-int dfs_file_getdents(struct dfs_fd* fd, struct dirent* dirp, rt_size_t nbytes)
-{
- struct dfs_filesystem* fs;
-
- /* parameter check */
- if (fd == RT_NULL || fd->type != FT_DIRECTORY) return -DFS_STATUS_EINVAL;
-
- fs = (struct dfs_filesystem*) fd->fs;
- if (fs->ops->getdents != RT_NULL) return fs->ops->getdents(fd, dirp, nbytes);
-
- return -DFS_STATUS_ENOSYS;
-}
-
-/**
- * this function will unlink (remove) a specified path file from file system.
- *
- * @param path the specified path file to be unlinked.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_unlink(const char *path)
-{
- int result;
- char *fullpath;
- struct dfs_filesystem* fs;
-
- result = DFS_STATUS_OK;
-
- /* Make sure we have an absolute path */
- fullpath = dfs_normalize_path(RT_NULL, path);
- if ( fullpath == RT_NULL)
- {
- return -DFS_STATUS_EINVAL;
- }
-
- /* get filesystem */
- if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- /* Check whether file is already open */
- if (fd_is_open(fullpath) == 0)
- {
- result = -DFS_STATUS_EBUSY;
- goto __exit;
- }
-
- if (fs->ops->unlink != RT_NULL)
- {
- if (dfs_subdir(fs->path, fullpath) == RT_NULL)
- result = fs->ops->unlink(fs, "/");
- else
- result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
- }
- else result = -DFS_STATUS_ENOSYS;
-
-__exit:
- rt_free(fullpath);
- return result;
-}
-
-/**
- * this function will write some specified length data to file system.
- *
- * @param fd the file descriptor.
- * @param buf the data buffer to be written.
- * @param len the data buffer length
- *
- * @return the actual written data length.
- */
-int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len)
-{
- struct dfs_filesystem* fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = fd->fs;
- if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- return fs->ops->write(fd, buf, len);
-}
-
-/**
- * this function will flush buffer on a file descriptor.
- *
- * @param fd the file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_flush(struct dfs_fd* fd)
-{
- struct dfs_filesystem* fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = fd->fs;
- if (fs->ops->flush == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- return fs->ops->flush(fd);
-}
-
-/**
- * this function will seek the offset for specified file descriptor.
- *
- * @param fd the file descriptor.
- * @param offset the offset to be seeked.
- *
- * @return the current position after seek.
- */
-int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset)
-{
- int result;
- struct dfs_filesystem* fs = fd->fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
- if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- result = fs->ops->lseek(fd, offset);
-
- /* update current position */
- if (result >= 0)
- fd->pos = result;
-
- return result;
-}
-
-/**
- * this function will get file information.
- *
- * @param path the file path.
- * @param buf the data buffer to save stat description.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_stat(const char *path, struct stat *buf)
-{
- int result;
- char* fullpath;
- struct dfs_filesystem* fs;
-
- fullpath = dfs_normalize_path(RT_NULL, path);
- if ( fullpath == RT_NULL )
- {
- return -1;
- }
-
- if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
- {
- dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
- rt_free(fullpath);
- return -DFS_STATUS_ENOENT;
- }
-
- if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
- (dfs_subdir(fs->path, fullpath) == RT_NULL))
- {
- /* it's the root directory */
- buf->st_dev = 0;
-
- buf->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
- buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
-
- buf->st_size = 0;
- buf->st_mtime = 0;
- buf->st_blksize = 512;
-
- /* release full path */
- rt_free(fullpath);
-
- return DFS_STATUS_OK;
- }
- else
- {
- if (fs->ops->stat == RT_NULL)
- {
- rt_free(fullpath);
- dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
- return -DFS_STATUS_ENOSYS;
- }
-
- /* get the real file path and get file stat */
- result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf);
- }
-
- rt_free(fullpath);
-
- return result;
-}
-
-/**
- * this funciton will rename an old path name to a new path name.
- *
- * @param oldpath the old path name.
- * @param newpath the new path name.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_rename(const char* oldpath, const char* newpath)
-{
- int result;
- struct dfs_filesystem *oldfs, *newfs;
- char *oldfullpath, *newfullpath;
-
- result = DFS_STATUS_OK;
- newfullpath = RT_NULL;
-
- oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
- if ( oldfullpath == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- newfullpath = dfs_normalize_path(RT_NULL, newpath);
- if ( newfullpath == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( oldfs == newfs )
- {
- if ( oldfs->ops->rename == RT_NULL )
- {
- result = -DFS_STATUS_ENOSYS;
- goto __exit;
- }
-
- result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
- goto __exit;
- }
-
- result = -DFS_STATUS_EXDEV;
-
-__exit:
- rt_free(oldfullpath);
- rt_free(newfullpath);
-
- /* not at same file system, return EXDEV */
- return result;
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-
-static struct dfs_fd fd;
-static struct dirent dirent;
-void ls(const char* pathname)
-{
- struct stat stat;
- int length;
- char *fullpath, *path;
-
- fullpath = RT_NULL;
- if (pathname == RT_NULL)
- {
-#ifdef DFS_USING_WORKDIR
- /* open current working directory */
- path = rt_strdup(working_directory);
-#else
- path = rt_strdup("/");
-#endif
- if (path == RT_NULL) return ; /* out of memory */
- }
- else
- {
- path = (char*)pathname;
- }
-
- /* list directory */
- if ( dfs_file_open(&fd, path, DFS_O_DIRECTORY) == 0 )
- {
- rt_kprintf("Directory %s:\n", path);
- do
- {
- rt_memset(&dirent, 0, sizeof(struct dirent));
- length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
- if ( length > 0 )
- {
- rt_memset(&stat, 0, sizeof(struct stat));
-
- /* build full path for each file */
- fullpath = dfs_normalize_path(path, dirent.d_name);
- if (fullpath == RT_NULL) break;
-
- if (dfs_file_stat(fullpath, &stat) == 0)
- {
- rt_kprintf("%-20s", dirent.d_name);
- if ( DFS_S_ISDIR(stat.st_mode))
- {
- rt_kprintf("%-25s\n", "<DIR>");
- }
- else
- {
- rt_kprintf("%-25lu\n", stat.st_size);
- }
- }
- else
- rt_kprintf("BAD file: %s\n", dirent.d_name);
- rt_free(fullpath);
- }
- }while(length > 0);
-
- dfs_file_close(&fd);
- }
- else
- {
- rt_kprintf("No such directory\n");
- }
- if (pathname == RT_NULL) rt_free(path);
-}
-FINSH_FUNCTION_EXPORT(ls, list directory contents)
-
-void rm(const char* filename)
-{
- if (dfs_file_unlink(filename) < 0)
- {
- rt_kprintf("Delete %s failed\n", filename);
- }
-}
-FINSH_FUNCTION_EXPORT(rm, remove files or directories)
-
-void cat(const char* filename)
-{
- rt_uint32_t length;
- char buffer[81];
-
- if (dfs_file_open(&fd, filename, DFS_O_RDONLY) < 0)
- {
- rt_kprintf("Open %s failed\n", filename);
- return;
- }
-
- do
- {
- rt_memset(buffer, 0, sizeof(buffer));
- length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 );
- if (length > 0)
- {
- rt_kprintf("%s", buffer);
- }
- }while (length > 0);
-
- dfs_file_close(&fd);
-}
-FINSH_FUNCTION_EXPORT(cat, print file)
-
-#define BUF_SZ 4096
-void copy(const char* src, const char* dst)
-{
- struct dfs_fd src_fd;
- rt_uint8_t *block_ptr;
- rt_uint32_t read_bytes;
-
- block_ptr = rt_malloc(BUF_SZ);
- if (block_ptr == RT_NULL)
- {
- rt_kprintf("out of memory\n");
- return;
- }
-
- if (dfs_file_open(&src_fd, src, DFS_O_RDONLY) < 0)
- {
- rt_free(block_ptr);
- rt_kprintf("Read %s failed\n", src);
- return;
- }
- if (dfs_file_open(&fd, dst, DFS_O_WRONLY | DFS_O_CREAT) < 0)
- {
- rt_free(block_ptr);
- dfs_file_close(&src_fd);
-
- rt_kprintf("Write %s failed\n", dst);
- return;
- }
-
- do
- {
- read_bytes = dfs_file_read(&src_fd, block_ptr, BUF_SZ);
- if (read_bytes > 0)
- {
- dfs_file_write(&fd, block_ptr, read_bytes);
- }
- } while (read_bytes > 0);
-
- dfs_file_close(&src_fd);
- dfs_file_close(&fd);
- rt_free(block_ptr);
-}
-FINSH_FUNCTION_EXPORT(copy, copy source file to destination file)
-
-#endif
-/* @} */
-
+/*
+ * File : dfs_file.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.
+ */
+#include <dfs.h>
+#include <dfs_file.h>
+
+/**
+ * @addtogroup FileApi
+ */
+/*@{*/
+
+/**
+ * this function will open a file which specified by path with specified flags.
+ *
+ * @param fd the file descriptor pointer to return the corresponding result.
+ * @param path the spaciefied file path.
+ * @param flags the flags for open operator.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_open(struct dfs_fd* fd, const char *path, int flags)
+{
+ struct dfs_filesystem* fs;
+ char *fullpath;
+ int result;
+
+ /* parameter check */
+ if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;
+
+ /* make sure we have an absolute path */
+ fullpath = dfs_normalize_path(RT_NULL, path);
+ if (fullpath == RT_NULL)
+ {
+ return -1;
+ }
+
+ dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
+
+ /* find filesystem */
+ fs = dfs_filesystem_lookup(fullpath);
+ if ( fs == RT_NULL )
+ {
+ rt_free(fullpath); /* release path */
+ return -DFS_STATUS_ENOENT;
+ }
+
+ dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
+ fd->fs = fs;
+
+ /* initilize the fd item */
+ fd->type = FT_REGULAR;
+ fd->flags = flags;
+ fd->size = 0;
+ fd->pos = 0;
+
+ if (dfs_subdir(fs->path, fullpath) == RT_NULL)
+ fd->path = rt_strdup("/");
+ else
+ fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
+ rt_free(fullpath);
+ dfs_log(DFS_DEBUG_INFO, ("actul file path: %s\n", fd->path));
+
+ /* specific file system open routine */
+ if (fs->ops->open == RT_NULL)
+ {
+ /* clear fd */
+ rt_free(fd->path);
+ rt_memset(fd, 0, sizeof(*fd));
+
+ return -DFS_STATUS_ENOSYS;
+ }
+
+ if ((result = fs->ops->open(fd)) < 0)
+ {
+ /* clear fd */
+ rt_free(fd->path);
+ rt_memset(fd, 0, sizeof(*fd));
+
+ dfs_log(DFS_DEBUG_INFO, ("open failed"));
+
+ return result;
+ }
+
+ fd->flags |= DFS_F_OPEN;
+ if ( flags & DFS_O_DIRECTORY )
+ {
+ fd->type = FT_DIRECTORY;
+ fd->flags |= DFS_F_DIRECTORY;
+ }
+
+ dfs_log(DFS_DEBUG_INFO, ("open successful"));
+ return 0;
+}
+
+/**
+ * this function will close a file descriptor.
+ *
+ * @param fd the file descriptor to be closed.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_close(struct dfs_fd* fd)
+{
+ int result = 0;
+
+ if (fd != RT_NULL && fd->fs->ops->close != RT_NULL) result = fd->fs->ops->close(fd);
+
+ /* close fd error, return */
+ if ( result < 0 ) return result;
+
+ rt_free(fd->path);
+ rt_memset(fd, 0, sizeof(struct dfs_fd));
+
+ return result;
+}
+
+/**
+ * this function will perform a io control on a file descriptor.
+ *
+ * @param fd the file descriptor.
+ * @param cmd the command to send to file descriptor.
+ * @param args the argument to send to file descriptor.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_ioctl(struct dfs_fd* fd, int cmd, void *args)
+{
+ struct dfs_filesystem* fs;
+
+ if (fd == RT_NULL || fd->type != FT_REGULAR) return -DFS_STATUS_EINVAL;
+
+ fs = fd->fs;
+ if (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args);
+
+ return -DFS_STATUS_ENOSYS;
+}
+
+/**
+ * this function will read specified length data from a file descriptor to a buffer.
+ *
+ * @param fd the file descriptor.
+ * @param buf the buffer to save the read data.
+ * @param len the length of data buffer to be read.
+ *
+ * @return the actual read data bytes or 0 on end of file or failed.
+ */
+int dfs_file_read(struct dfs_fd* fd, void *buf, rt_size_t len)
+{
+ struct dfs_filesystem* fs;
+ int result = 0;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ fs = (struct dfs_filesystem*) fd->fs;
+ if (fs->ops->read == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ if ( (result = fs->ops->read(fd, buf, len)) < 0 ) fd->flags |= DFS_F_EOF;
+
+ return result;
+}
+
+/**
+ * this function will fetch directory entries from a directory descriptor.
+ *
+ * @param fd the directory decriptor.
+ * @param dirp the dirent buffer to save result.
+ * @param nbytes the aviable room in the buffer.
+ *
+ * @return the read dirent, others on failed.
+ */
+int dfs_file_getdents(struct dfs_fd* fd, struct dirent* dirp, rt_size_t nbytes)
+{
+ struct dfs_filesystem* fs;
+
+ /* parameter check */
+ if (fd == RT_NULL || fd->type != FT_DIRECTORY) return -DFS_STATUS_EINVAL;
+
+ fs = (struct dfs_filesystem*) fd->fs;
+ if (fs->ops->getdents != RT_NULL) return fs->ops->getdents(fd, dirp, nbytes);
+
+ return -DFS_STATUS_ENOSYS;
+}
+
+/**
+ * this function will unlink (remove) a specified path file from file system.
+ *
+ * @param path the specified path file to be unlinked.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_unlink(const char *path)
+{
+ int result;
+ char *fullpath;
+ struct dfs_filesystem* fs;
+
+ result = DFS_STATUS_OK;
+
+ /* Make sure we have an absolute path */
+ fullpath = dfs_normalize_path(RT_NULL, path);
+ if ( fullpath == RT_NULL)
+ {
+ return -DFS_STATUS_EINVAL;
+ }
+
+ /* get filesystem */
+ if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
+ {
+ result = -DFS_STATUS_ENOENT;
+ goto __exit;
+ }
+
+ /* Check whether file is already open */
+ if (fd_is_open(fullpath) == 0)
+ {
+ result = -DFS_STATUS_EBUSY;
+ goto __exit;
+ }
+
+ if (fs->ops->unlink != RT_NULL)
+ {
+ if (dfs_subdir(fs->path, fullpath) == RT_NULL)
+ result = fs->ops->unlink(fs, "/");
+ else
+ result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
+ }
+ else result = -DFS_STATUS_ENOSYS;
+
+__exit:
+ rt_free(fullpath);
+ return result;
+}
+
+/**
+ * this function will write some specified length data to file system.
+ *
+ * @param fd the file descriptor.
+ * @param buf the data buffer to be written.
+ * @param len the data buffer length
+ *
+ * @return the actual written data length.
+ */
+int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len)
+{
+ struct dfs_filesystem* fs;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ fs = fd->fs;
+ if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ return fs->ops->write(fd, buf, len);
+}
+
+/**
+ * this function will flush buffer on a file descriptor.
+ *
+ * @param fd the file descriptor.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_flush(struct dfs_fd* fd)
+{
+ struct dfs_filesystem* fs;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ fs = fd->fs;
+ if (fs->ops->flush == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ return fs->ops->flush(fd);
+}
+
+/**
+ * this function will seek the offset for specified file descriptor.
+ *
+ * @param fd the file descriptor.
+ * @param offset the offset to be seeked.
+ *
+ * @return the current position after seek.
+ */
+int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset)
+{
+ int result;
+ struct dfs_filesystem* fs = fd->fs;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+ if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ result = fs->ops->lseek(fd, offset);
+
+ /* update current position */
+ if (result >= 0)
+ fd->pos = result;
+
+ return result;
+}
+
+/**
+ * this function will get file information.
+ *
+ * @param path the file path.
+ * @param buf the data buffer to save stat description.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_stat(const char *path, struct stat *buf)
+{
+ int result;
+ char* fullpath;
+ struct dfs_filesystem* fs;
+
+ fullpath = dfs_normalize_path(RT_NULL, path);
+ if ( fullpath == RT_NULL )
+ {
+ return -1;
+ }
+
+ if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
+ {
+ dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
+ rt_free(fullpath);
+ return -DFS_STATUS_ENOENT;
+ }
+
+ if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
+ (dfs_subdir(fs->path, fullpath) == RT_NULL))
+ {
+ /* it's the root directory */
+ buf->st_dev = 0;
+
+ buf->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
+ DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
+ buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
+
+ buf->st_size = 0;
+ buf->st_mtime = 0;
+ buf->st_blksize = 512;
+
+ /* release full path */
+ rt_free(fullpath);
+
+ return DFS_STATUS_OK;
+ }
+ else
+ {
+ if (fs->ops->stat == RT_NULL)
+ {
+ rt_free(fullpath);
+ dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
+ return -DFS_STATUS_ENOSYS;
+ }
+
+ /* get the real file path and get file stat */
+ result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf);
+ }
+
+ rt_free(fullpath);
+
+ return result;
+}
+
+/**
+ * this funciton will rename an old path name to a new path name.
+ *
+ * @param oldpath the old path name.
+ * @param newpath the new path name.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int dfs_file_rename(const char* oldpath, const char* newpath)
+{
+ int result;
+ struct dfs_filesystem *oldfs, *newfs;
+ char *oldfullpath, *newfullpath;
+
+ result = DFS_STATUS_OK;
+ newfullpath = RT_NULL;
+
+ oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
+ if ( oldfullpath == RT_NULL )
+ {
+ result = -DFS_STATUS_ENOENT;
+ goto __exit;
+ }
+
+ newfullpath = dfs_normalize_path(RT_NULL, newpath);
+ if ( newfullpath == RT_NULL )
+ {
+ result = -DFS_STATUS_ENOENT;
+ goto __exit;
+ }
+
+ if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
+ {
+ result = -DFS_STATUS_ENOENT;
+ goto __exit;
+ }
+
+ if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
+ {
+ result = -DFS_STATUS_ENOENT;
+ goto __exit;
+ }
+
+ if ( oldfs == newfs )
+ {
+ if ( oldfs->ops->rename == RT_NULL )
+ {
+ result = -DFS_STATUS_ENOSYS;
+ goto __exit;
+ }
+
+ result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
+ goto __exit;
+ }
+
+ result = -DFS_STATUS_EXDEV;
+
+__exit:
+ rt_free(oldfullpath);
+ rt_free(newfullpath);
+
+ /* not at same file system, return EXDEV */
+ return result;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+static struct dfs_fd fd;
+static struct dirent dirent;
+void ls(const char* pathname)
+{
+ struct stat stat;
+ int length;
+ char *fullpath, *path;
+
+ fullpath = RT_NULL;
+ if (pathname == RT_NULL)
+ {
+#ifdef DFS_USING_WORKDIR
+ /* open current working directory */
+ path = rt_strdup(working_directory);
+#else
+ path = rt_strdup("/");
+#endif
+ if (path == RT_NULL) return ; /* out of memory */
+ }
+ else
+ {
+ path = (char*)pathname;
+ }
+
+ /* list directory */
+ if ( dfs_file_open(&fd, path, DFS_O_DIRECTORY) == 0 )
+ {
+ rt_kprintf("Directory %s:\n", path);
+ do
+ {
+ rt_memset(&dirent, 0, sizeof(struct dirent));
+ length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
+ if ( length > 0 )
+ {
+ rt_memset(&stat, 0, sizeof(struct stat));
+
+ /* build full path for each file */
+ fullpath = dfs_normalize_path(path, dirent.d_name);
+ if (fullpath == RT_NULL) break;
+
+ if (dfs_file_stat(fullpath, &stat) == 0)
+ {
+ rt_kprintf("%-20s", dirent.d_name);
+ if ( DFS_S_ISDIR(stat.st_mode))
+ {
+ rt_kprintf("%-25s\n", "<DIR>");
+ }
+ else
+ {
+ rt_kprintf("%-25lu\n", stat.st_size);
+ }
+ }
+ else
+ rt_kprintf("BAD file: %s\n", dirent.d_name);
+ rt_free(fullpath);
+ }
+ }while(length > 0);
+
+ dfs_file_close(&fd);
+ }
+ else
+ {
+ rt_kprintf("No such directory\n");
+ }
+ if (pathname == RT_NULL) rt_free(path);
+}
+FINSH_FUNCTION_EXPORT(ls, list directory contents)
+
+void rm(const char* filename)
+{
+ if (dfs_file_unlink(filename) < 0)
+ {
+ rt_kprintf("Delete %s failed\n", filename);
+ }
+}
+FINSH_FUNCTION_EXPORT(rm, remove files or directories)
+
+void cat(const char* filename)
+{
+ rt_uint32_t length;
+ char buffer[81];
+
+ if (dfs_file_open(&fd, filename, DFS_O_RDONLY) < 0)
+ {
+ rt_kprintf("Open %s failed\n", filename);
+ return;
+ }
+
+ do
+ {
+ rt_memset(buffer, 0, sizeof(buffer));
+ length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 );
+ if (length > 0)
+ {
+ rt_kprintf("%s", buffer);
+ }
+ }while (length > 0);
+
+ dfs_file_close(&fd);
+}
+FINSH_FUNCTION_EXPORT(cat, print file)
+
+#define BUF_SZ 4096
+void copy(const char* src, const char* dst)
+{
+ struct dfs_fd src_fd;
+ rt_uint8_t *block_ptr;
+ rt_uint32_t read_bytes;
+
+ block_ptr = rt_malloc(BUF_SZ);
+ if (block_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory\n");
+ return;
+ }
+
+ if (dfs_file_open(&src_fd, src, DFS_O_RDONLY) < 0)
+ {
+ rt_free(block_ptr);
+ rt_kprintf("Read %s failed\n", src);
+ return;
+ }
+ if (dfs_file_open(&fd, dst, DFS_O_WRONLY | DFS_O_CREAT) < 0)
+ {
+ rt_free(block_ptr);
+ dfs_file_close(&src_fd);
+
+ rt_kprintf("Write %s failed\n", dst);
+ return;
+ }
+
+ do
+ {
+ read_bytes = dfs_file_read(&src_fd, block_ptr, BUF_SZ);
+ if (read_bytes > 0)
+ {
+ dfs_file_write(&fd, block_ptr, read_bytes);
+ }
+ } while (read_bytes > 0);
+
+ dfs_file_close(&src_fd);
+ dfs_file_close(&fd);
+ rt_free(block_ptr);
+}
+FINSH_FUNCTION_EXPORT(copy, copy source file to destination file)
+
+#endif
+/* @} */
+
diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c
index 3a04a05f28..da1e456c7b 100644
--- a/components/dfs/src/dfs_fs.c
+++ b/components/dfs/src/dfs_fs.c
@@ -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
+
+/* @} */
diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c
index c1e80a3d9d..f3e6a3edfd 100644
--- a/components/dfs/src/dfs_posix.c
+++ b/components/dfs/src/dfs_posix.c
@@ -1,668 +1,668 @@
-/*
- * File : dfs_posix.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
- * 2009-05-27 Yi.qiu The first version
- */
-
-#include <dfs.h>
-#include <dfs_posix.h>
-
-/**
- * @addtogroup FsPosixApi
- */
-/*@{*/
-
-/**
- * this function is a POSIX compliant version, which will open a file and return
- * a file descriptor.
- *
- * @param file the path name of file.
- * @param flags the file open flags.
- * @param mode
- *
- * @return the non-negative integer on successful open, others for failed.
- */
-int open(const char *file, int flags, int mode)
-{
- int fd, result;
- struct dfs_fd* d;
-
- /* allocate a fd */
- fd = fd_new();
- if (fd < 0) return -1;
- d = fd_get(fd);
-
- result = dfs_file_open(d, file, flags);
- if (result < 0)
- {
- rt_set_errno(result);
-
- /* release the ref-count of fd */
- fd_put(d);
- fd_put(d);
-
- return -1;
- }
-
- /* release the ref-count of fd */
- fd_put(d);
- return fd;
-}
-
-/**
- * this function is a POSIX compliant version, which will close the open
- * file descriptor.
- *
- * @param fd the file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-int close(int fd)
-{
- int result;
- struct dfs_fd* d;
-
- d = fd_get(fd);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- result = dfs_file_close(d);
- fd_put(d);
-
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- fd_put(d);
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will read specified data buffer
- * length for an open file descriptor.
- *
- * @param fd the file descriptor.
- * @param buf the buffer to save the read data.
- * @param len the maximal length of data buffer
- *
- * @return the actual read data buffer length
- */
-int read(int fd, void *buf, size_t len)
-{
- int result;
- struct dfs_fd* d;
-
- /* get the fd */
- d = fd_get(fd);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- result = dfs_file_read(d, buf, len);
- if (result < 0)
- {
- rt_set_errno(result);
- fd_put(d);
-
- return -1;
- }
-
- /* release the ref-count of fd */
- fd_put(d);
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will write pecified data buffer
- * length for an open file descriptor.
- *
- * @param fd the file descriptor
- * @param buf the data buffer to be written.
- * @param len the data buffer length.
- *
- * @return the actual written data buffer length.
- */
-int write(int fd, const void *buf, size_t len)
-{
- int result;
- struct dfs_fd* d;
-
- /* get the fd */
- d = fd_get(fd);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- result = dfs_file_write(d, buf, len);
- if (result < 0)
- {
- rt_set_errno(result);
- fd_put(d);
-
- return -1;
- }
-
- /* release the ref-count of fd */
- fd_put(d);
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will seek the offset for an
- * open file descriptor.
- *
- * @param fd the file descriptor.
- * @param offset the offset to be seeked.
- * @param whence the directory of seek.
- *
- * @return the current file position, or -1 on failed.
- */
-off_t lseek(int fd, off_t offset, int whence)
-{
- int result;
- struct dfs_fd* d;
-
- d = fd_get(fd);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- switch (whence)
- {
- case DFS_SEEK_SET:
- break;
-
- case DFS_SEEK_CUR:
- offset += d->pos;
- break;
-
- case DFS_SEEK_END:
- offset += d->size;
- break;
- }
-
- result = dfs_file_lseek(d, offset);
- if (result < 0)
- {
- rt_set_errno(result);
- fd_put(d);
- return -1;
- }
-
- /* release the ref-count of fd */
- fd_put(d);
- return offset;
-}
-
-/**
- * this function is a POSIX compliant version, which will rename old file name to
- * new file name.
- *
- * @param old the old file name.
- * @param new the new file name.
- *
- * @return 0 on successful, -1 on failed.
- *
- * note: the old and new file name must be belong to a same file system.
- */
-int rename(const char* old, const char* new)
-{
- int result;
-
- result = dfs_file_rename(old, new);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will unlink (remove) a
- * specified path file from file system.
- *
- * @param pathname the specified path name to be unlinked.
- *
- * @return 0 on successful, -1 on failed.
- */
-int unlink(const char *pathname)
-{
- int result;
-
- result = dfs_file_unlink(pathname);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will get file information.
- *
- * @param file the file name
- * @param buf the data buffer to save stat description.
- *
- * @return 0 on successful, -1 on failed.
- */
-int stat(const char *file, struct stat *buf)
-{
- int result;
-
- result = dfs_file_stat(file, buf);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will get file status.
- *
- * @param fildes the file description
- * @param buf the data buffer to save stat description.
- */
-int fstat(int fildes, struct stat *buf)
-{
- struct dfs_fd* d;
-
- /* get the fd */
- d = fd_get(fildes);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- /* it's the root directory */
- buf->st_dev = 0;
-
- buf->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
- if (d->type == FT_DIRECTORY)
- {
- buf->st_mode &= ~DFS_S_IFREG;
- buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
- }
-
- buf->st_size = d->size;
- buf->st_mtime = 0;
- buf->st_blksize = 512;
-
- fd_put(d);
-
- return DFS_STATUS_OK;
-}
-
-/**
- * this function is a POSIX compliant version, which will return the
- * information about a mounted file system.
- *
- * @param path the path which mounted file system.
- * @param buf the buffer to save the returned information.
- *
- * @return 0 on successful, others on failed.
- */
-int statfs(const char *path, struct statfs *buf)
-{
- int result;
-
- result = dfs_statfs(path, buf);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will make a directory
- *
- * @param path the directory path to be made.
- * @param mode
- *
- * @return 0 on successful, others on failed.
- */
-int mkdir (const char *path, mode_t mode)
-{
- int fd;
- struct dfs_fd* d;
- int result;
-
- fd = fd_new();
- if (fd == -1) { rt_kprintf("no fd\n"); return -1; }
-
- d = fd_get(fd);
-
- result = dfs_file_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT);
-
- if (result < 0)
- {
- rt_set_errno(result);
- fd_put(d);
- return -1;
- }
-
- dfs_file_close(d);
- fd_put(d);
- return 0;
-}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT(mkdir, create a directory);
-#endif
-
-/**
- * this function is a POSIX compliant version, which will remove a directory.
- *
- * @param pathname the path name to be removed.
- *
- * @return 0 on sucessfull, others on failed.
- */
-int rmdir(const char *pathname)
-{
- int result;
-
- result = dfs_file_unlink(pathname);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will open a directory.
- *
- * @param name the path name to be open.
- *
- * @return the DIR pointer of directory, NULL on open failed.
- */
-DIR* opendir(const char* name)
-{
- struct dfs_fd* d;
- int fd, result;
- DIR* t;
-
- t = RT_NULL;
-
- /* allocate a fd */
- fd = fd_new();
- if (fd == -1) { rt_kprintf("no fd\n"); return RT_NULL; }
- d = fd_get(fd);
-
- result = dfs_file_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY);
- if (result >= 0)
- {
- /* open successfully */
- t = (DIR *) rt_malloc (sizeof(DIR));
- if (t == RT_NULL)
- {
- dfs_file_close(d);
- fd_put(d);
- }
- else
- {
- rt_memset(t, 0, sizeof(DIR));
- t->fd = fd;
- }
- fd_put(d);
- return t;
- }
-
- /* open failed */
- fd_put(d);
- fd_put(d);
- rt_set_errno(result);
-
- return RT_NULL;
-}
-
-/**
- * this function is a POSIX compliant version, which will return a pointer
- * to a dirent structure representing the next directory entry in the
- * directory stream.
- *
- * @param d the directory stream pointer.
- *
- * @return the next directory entry, NULL on the end of directory or failed.
- */
-struct dirent* readdir(DIR *d)
-{
- int result;
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return RT_NULL;
- }
-
- if (!d->num || (d->cur += ((struct dirent*)(d->buf + d->cur))->d_reclen) >= d->num)
- {
- /* get a new entry */
- result = dfs_file_getdents(fd, (struct dirent*)d->buf, sizeof(d->buf) - 1);
- if (result <= 0)
- {
- rt_set_errno(result);
- fd_put(fd);
-
- return RT_NULL;
- }
-
- d->num = result;
- d->cur = 0; /* current entry index */
- }
-
- fd_put(fd);
- return (struct dirent*)(d->buf+d->cur);
-}
-
-/**
- * this function is a POSIX compliant version, which will return current
- * location in directory stream.
- *
- * @param d the directory stream pointer.
- *
- * @return the current location in directory stream.
- */
-long telldir(DIR *d)
-{
- struct dfs_fd* fd;
- long result;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return 0;
- }
-
- result = fd->pos - d->num + d->cur;
- fd_put(fd);
-
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will set position of
- * next directory structure in the directory stream.
- *
- * @param d the directory stream.
- * @param offset the offset in directory stream.
- */
-void seekdir(DIR *d, off_t offset)
-{
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return ;
- }
-
- /* seek to the offset position of directory */
- if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0;
- fd_put(fd);
-}
-
-/**
- * this function is a POSIX compliant version, which will reset directory stream.
- *
- * @param d the directory stream.
- */
-void rewinddir(DIR *d)
-{
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return ;
- }
-
- /* seek to the beginning of directory */
- if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0;
- fd_put(fd);
-}
-
-/**
- * this function is a POSIX compliant version, which will close a directory
- * stream.
- *
- * @param d the directory stream.
- *
- * @return 0 on successful, -1 on failed.
- */
-int closedir(DIR* d)
-{
- int result;
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- result = dfs_file_close(fd);
- fd_put(fd);
-
- fd_put(fd);
- rt_free(d);
-
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- else return 0;
-}
-
-#ifdef DFS_USING_WORKDIR
-/**
- * this function is a POSIX compliant version, which will change working directory.
- *
- * @param path the path name to be changed to.
- *
- * @return 0 on successful, -1 on failed.
- */
-int chdir(const char *path)
-{
- char* fullpath;
- DIR* d;
-
- if(path == RT_NULL)
- {
- dfs_lock();
- rt_kprintf("%s\n", working_directory);
- dfs_unlock();
- return 0;
- }
-
- if (rt_strlen(path) > DFS_PATH_MAX)
- return -1;
-
- fullpath = dfs_normalize_path(NULL, path);
- if (fullpath == RT_NULL)
- return -1; /* build path failed */
-
- dfs_lock();
- d = opendir(fullpath);
- if (d == RT_NULL)
- {
- rt_free(fullpath);
- /* this is a not exist directory */
- dfs_unlock();
- return -1;
- }
-
- /* close directory stream */
- closedir(d);
-
- /* copy full path to working directory */
- strncpy(working_directory, fullpath, DFS_PATH_MAX);
- rt_free(fullpath); /* release normalize directory path name */
-
- dfs_unlock();
-
- return 0;
-}
-#ifdef RT_USING_FINSH
-FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory);
-#endif
-#endif
-
-/**
- * this function is a POSIX compliant version, which will return current
- * working directory.
- *
- * @param buf the returned current directory.
- * @param size the buffer size.
- *
- * @return the returned current directory.
- */
-char *getcwd(char *buf, size_t size)
-{
-#ifdef DFS_USING_WORKDIR
- rt_enter_critical();
- rt_strncpy(buf, working_directory, size);
- rt_exit_critical();
-#else
- rt_kprintf("WARNING: not support working directory\n");
-#endif
- return buf;
-}
-
-/* @} */
+/*
+ * File : dfs_posix.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
+ * 2009-05-27 Yi.qiu The first version
+ */
+
+#include <dfs.h>
+#include <dfs_posix.h>
+
+/**
+ * @addtogroup FsPosixApi
+ */
+/*@{*/
+
+/**
+ * this function is a POSIX compliant version, which will open a file and return
+ * a file descriptor.
+ *
+ * @param file the path name of file.
+ * @param flags the file open flags.
+ * @param mode
+ *
+ * @return the non-negative integer on successful open, others for failed.
+ */
+int open(const char *file, int flags, int mode)
+{
+ int fd, result;
+ struct dfs_fd* d;
+
+ /* allocate a fd */
+ fd = fd_new();
+ if (fd < 0) return -1;
+ d = fd_get(fd);
+
+ result = dfs_file_open(d, file, flags);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return fd;
+}
+
+/**
+ * this function is a POSIX compliant version, which will close the open
+ * file descriptor.
+ *
+ * @param fd the file descriptor.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int close(int fd)
+{
+ int result;
+ struct dfs_fd* d;
+
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfs_file_close(d);
+ fd_put(d);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+
+ fd_put(d);
+ return 0;
+}
+
+/**
+ * this function is a POSIX compliant version, which will read specified data buffer
+ * length for an open file descriptor.
+ *
+ * @param fd the file descriptor.
+ * @param buf the buffer to save the read data.
+ * @param len the maximal length of data buffer
+ *
+ * @return the actual read data buffer length
+ */
+int read(int fd, void *buf, size_t len)
+{
+ int result;
+ struct dfs_fd* d;
+
+ /* get the fd */
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfs_file_read(d, buf, len);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return result;
+}
+
+/**
+ * this function is a POSIX compliant version, which will write pecified data buffer
+ * length for an open file descriptor.
+ *
+ * @param fd the file descriptor
+ * @param buf the data buffer to be written.
+ * @param len the data buffer length.
+ *
+ * @return the actual written data buffer length.
+ */
+int write(int fd, const void *buf, size_t len)
+{
+ int result;
+ struct dfs_fd* d;
+
+ /* get the fd */
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfs_file_write(d, buf, len);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return result;
+}
+
+/**
+ * this function is a POSIX compliant version, which will seek the offset for an
+ * open file descriptor.
+ *
+ * @param fd the file descriptor.
+ * @param offset the offset to be seeked.
+ * @param whence the directory of seek.
+ *
+ * @return the current file position, or -1 on failed.
+ */
+off_t lseek(int fd, off_t offset, int whence)
+{
+ int result;
+ struct dfs_fd* d;
+
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ switch (whence)
+ {
+ case DFS_SEEK_SET:
+ break;
+
+ case DFS_SEEK_CUR:
+ offset += d->pos;
+ break;
+
+ case DFS_SEEK_END:
+ offset += d->size;
+ break;
+ }
+
+ result = dfs_file_lseek(d, offset);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return offset;
+}
+
+/**
+ * this function is a POSIX compliant version, which will rename old file name to
+ * new file name.
+ *
+ * @param old the old file name.
+ * @param new the new file name.
+ *
+ * @return 0 on successful, -1 on failed.
+ *
+ * note: the old and new file name must be belong to a same file system.
+ */
+int rename(const char* old, const char* new)
+{
+ int result;
+
+ result = dfs_file_rename(old, new);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * this function is a POSIX compliant version, which will unlink (remove) a
+ * specified path file from file system.
+ *
+ * @param pathname the specified path name to be unlinked.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int unlink(const char *pathname)
+{
+ int result;
+
+ result = dfs_file_unlink(pathname);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * this function is a POSIX compliant version, which will get file information.
+ *
+ * @param file the file name
+ * @param buf the data buffer to save stat description.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int stat(const char *file, struct stat *buf)
+{
+ int result;
+
+ result = dfs_file_stat(file, buf);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return result;
+}
+
+/**
+ * this function is a POSIX compliant version, which will get file status.
+ *
+ * @param fildes the file description
+ * @param buf the data buffer to save stat description.
+ */
+int fstat(int fildes, struct stat *buf)
+{
+ struct dfs_fd* d;
+
+ /* get the fd */
+ d = fd_get(fildes);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ /* it's the root directory */
+ buf->st_dev = 0;
+
+ buf->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
+ DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
+ if (d->type == FT_DIRECTORY)
+ {
+ buf->st_mode &= ~DFS_S_IFREG;
+ buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
+ }
+
+ buf->st_size = d->size;
+ buf->st_mtime = 0;
+ buf->st_blksize = 512;
+
+ fd_put(d);
+
+ return DFS_STATUS_OK;
+}
+
+/**
+ * this function is a POSIX compliant version, which will return the
+ * information about a mounted file system.
+ *
+ * @param path the path which mounted file system.
+ * @param buf the buffer to save the returned information.
+ *
+ * @return 0 on successful, others on failed.
+ */
+int statfs(const char *path, struct statfs *buf)
+{
+ int result;
+
+ result = dfs_statfs(path, buf);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+
+ return result;
+}
+
+/**
+ * this function is a POSIX compliant version, which will make a directory
+ *
+ * @param path the directory path to be made.
+ * @param mode
+ *
+ * @return 0 on successful, others on failed.
+ */
+int mkdir (const char *path, mode_t mode)
+{
+ int fd;
+ struct dfs_fd* d;
+ int result;
+
+ fd = fd_new();
+ if (fd == -1) { rt_kprintf("no fd\n"); return -1; }
+
+ d = fd_get(fd);
+
+ result = dfs_file_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+ return -1;
+ }
+
+ dfs_file_close(d);
+ fd_put(d);
+ return 0;
+}
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(mkdir, create a directory);
+#endif
+
+/**
+ * this function is a POSIX compliant version, which will remove a directory.
+ *
+ * @param pathname the path name to be removed.
+ *
+ * @return 0 on sucessfull, others on failed.
+ */
+int rmdir(const char *pathname)
+{
+ int result;
+
+ result = dfs_file_unlink(pathname);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * this function is a POSIX compliant version, which will open a directory.
+ *
+ * @param name the path name to be open.
+ *
+ * @return the DIR pointer of directory, NULL on open failed.
+ */
+DIR* opendir(const char* name)
+{
+ struct dfs_fd* d;
+ int fd, result;
+ DIR* t;
+
+ t = RT_NULL;
+
+ /* allocate a fd */
+ fd = fd_new();
+ if (fd == -1) { rt_kprintf("no fd\n"); return RT_NULL; }
+ d = fd_get(fd);
+
+ result = dfs_file_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY);
+ if (result >= 0)
+ {
+ /* open successfully */
+ t = (DIR *) rt_malloc (sizeof(DIR));
+ if (t == RT_NULL)
+ {
+ dfs_file_close(d);
+ fd_put(d);
+ }
+ else
+ {
+ rt_memset(t, 0, sizeof(DIR));
+ t->fd = fd;
+ }
+ fd_put(d);
+ return t;
+ }
+
+ /* open failed */
+ fd_put(d);
+ fd_put(d);
+ rt_set_errno(result);
+
+ return RT_NULL;
+}
+
+/**
+ * this function is a POSIX compliant version, which will return a pointer
+ * to a dirent structure representing the next directory entry in the
+ * directory stream.
+ *
+ * @param d the directory stream pointer.
+ *
+ * @return the next directory entry, NULL on the end of directory or failed.
+ */
+struct dirent* readdir(DIR *d)
+{
+ int result;
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return RT_NULL;
+ }
+
+ if (!d->num || (d->cur += ((struct dirent*)(d->buf + d->cur))->d_reclen) >= d->num)
+ {
+ /* get a new entry */
+ result = dfs_file_getdents(fd, (struct dirent*)d->buf, sizeof(d->buf) - 1);
+ if (result <= 0)
+ {
+ rt_set_errno(result);
+ fd_put(fd);
+
+ return RT_NULL;
+ }
+
+ d->num = result;
+ d->cur = 0; /* current entry index */
+ }
+
+ fd_put(fd);
+ return (struct dirent*)(d->buf+d->cur);
+}
+
+/**
+ * this function is a POSIX compliant version, which will return current
+ * location in directory stream.
+ *
+ * @param d the directory stream pointer.
+ *
+ * @return the current location in directory stream.
+ */
+long telldir(DIR *d)
+{
+ struct dfs_fd* fd;
+ long result;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return 0;
+ }
+
+ result = fd->pos - d->num + d->cur;
+ fd_put(fd);
+
+ return result;
+}
+
+/**
+ * this function is a POSIX compliant version, which will set position of
+ * next directory structure in the directory stream.
+ *
+ * @param d the directory stream.
+ * @param offset the offset in directory stream.
+ */
+void seekdir(DIR *d, off_t offset)
+{
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return ;
+ }
+
+ /* seek to the offset position of directory */
+ if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0;
+ fd_put(fd);
+}
+
+/**
+ * this function is a POSIX compliant version, which will reset directory stream.
+ *
+ * @param d the directory stream.
+ */
+void rewinddir(DIR *d)
+{
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return ;
+ }
+
+ /* seek to the beginning of directory */
+ if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0;
+ fd_put(fd);
+}
+
+/**
+ * this function is a POSIX compliant version, which will close a directory
+ * stream.
+ *
+ * @param d the directory stream.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int closedir(DIR* d)
+{
+ int result;
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfs_file_close(fd);
+ fd_put(fd);
+
+ fd_put(fd);
+ rt_free(d);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ else return 0;
+}
+
+#ifdef DFS_USING_WORKDIR
+/**
+ * this function is a POSIX compliant version, which will change working directory.
+ *
+ * @param path the path name to be changed to.
+ *
+ * @return 0 on successful, -1 on failed.
+ */
+int chdir(const char *path)
+{
+ char* fullpath;
+ DIR* d;
+
+ if(path == RT_NULL)
+ {
+ dfs_lock();
+ rt_kprintf("%s\n", working_directory);
+ dfs_unlock();
+ return 0;
+ }
+
+ if (rt_strlen(path) > DFS_PATH_MAX)
+ return -1;
+
+ fullpath = dfs_normalize_path(NULL, path);
+ if (fullpath == RT_NULL)
+ return -1; /* build path failed */
+
+ dfs_lock();
+ d = opendir(fullpath);
+ if (d == RT_NULL)
+ {
+ rt_free(fullpath);
+ /* this is a not exist directory */
+ dfs_unlock();
+ return -1;
+ }
+
+ /* close directory stream */
+ closedir(d);
+
+ /* copy full path to working directory */
+ strncpy(working_directory, fullpath, DFS_PATH_MAX);
+ rt_free(fullpath); /* release normalize directory path name */
+
+ dfs_unlock();
+
+ return 0;
+}
+#ifdef RT_USING_FINSH
+FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory);
+#endif
+#endif
+
+/**
+ * this function is a POSIX compliant version, which will return current
+ * working directory.
+ *
+ * @param buf the returned current directory.
+ * @param size the buffer size.
+ *
+ * @return the returned current directory.
+ */
+char *getcwd(char *buf, size_t size)
+{
+#ifdef DFS_USING_WORKDIR
+ rt_enter_critical();
+ rt_strncpy(buf, working_directory, size);
+ rt_exit_critical();
+#else
+ rt_kprintf("WARNING: not support working directory\n");
+#endif
+ return buf;
+}
+
+/* @} */