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