123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681 |
- /*
- +------------------------------------------------------------------------------
- | Project : Device Filesystem
- +------------------------------------------------------------------------------
- | Copyright 2004, 2005 www.fayfayspace.org.
- | All rights reserved.
- |------------------------------------------------------------------------------
- | File : dfs_raw.c, the raw APIs of Device FileSystem
- |------------------------------------------------------------------------------
- | Chang Logs:
- | Date Author Notes
- | 2005-02-22 ffxz The first version.
- +------------------------------------------------------------------------------
- */
- #include <dfs_raw.h>
- #include <dfs_util.h>
- #include <string.h>
- extern struct dfs_fd fd_table[];
- /*
- +------------------------------------------------------------------------------
- | Function : fd_new
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int fd_new(void)
- {
- struct dfs_fd* d;
- int idx;
- /* lock filesystem */
- dfs_lock();
- /* find an empty fd entry */
- #ifdef DFS_USING_STDIO
- for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++);
- #else
- for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
- #endif
- /* can't find an empty fd entry */
- #ifdef DFS_USING_STDIO
- if (idx == DFS_FD_MAX + 3)
- #else
- if (idx == DFS_FD_MAX)
- #endif
- {
- idx = -1;
- goto __result;
- }
- d = &(fd_table[idx]);
- d->ref_count = 1;
- __result:
- dfs_unlock();
- return idx;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : fd_get
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- struct dfs_fd* fd_get(int fd)
- {
- struct dfs_fd* d;
- #ifdef DFS_USING_STDIO
- if ( fd < 3 || fd > DFS_FD_MAX + 3) return RT_NULL;
- #else
- if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL;
- #endif
- d = &fd_table[fd];
- dfs_lock();
- d->ref_count ++;
- dfs_unlock();
- return d;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : fd_put
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- void fd_put(struct dfs_fd* fd)
- {
- dfs_lock();
- fd->ref_count --;
- /* clear this fd entry */
- if ( fd->ref_count == 0 )
- {
- rt_memset(fd, 0, sizeof(struct dfs_fd));
- }
- dfs_unlock();
- };
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_open
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_open(struct dfs_fd* fd, const char *path, int flags)
- {
- struct dfs_filesystem* fs;
- char *fullpath;
- #ifdef DFS_USING_WORKDIR
- char full_path[DFS_PATH_MAX + 1];
- #endif
- int fspathlen, result;
- /* parameter check */
- if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;
- /* make sure we have an absolute path */
- fullpath = (char*)path;
- if ( fullpath[0] != '/')
- {
- #ifdef DFS_USING_WORKDIR
- /* build full path */
- fullpath = &full_path[0];
- dfs_lock();
- build_fullpath(working_directory, path, fullpath);
- dfs_unlock();
- #else
- #ifdef RT_USING_FINSH
- rt_kprintf("bad filename");
- #endif
- return -1;
- #endif
- }
- dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
- /* find filesystem */
- fs = dfs_filesystem_lookup(fullpath);
- if ( fs == RT_NULL ) return -DFS_STATUS_ENOENT;
- dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
- fd->fs = fs;
- /* initilize the fd item */
- fd->type = FT_REGULAR;
- //fd->ref_count = 1;
- fd->flags = flags;
- fd->size = 0;
- fd->pos = 0;
- fspathlen = strlen(fs->path);
- rt_memset(fd->path, 0, DFS_PATH_MAX + 1);
- if (*(fullpath + fspathlen) != '/') strcpy(fd->path, "/");
- strcat(fd->path, fullpath + fspathlen);
- /* specific file system open routine */
- if (fs->ops->open == RT_NULL)
- {
- /* clear fd */
- rt_memset(fd->path, 0, DFS_PATH_MAX + 1);
- fd->type = FT_REGULAR;
- fd->ref_count = 0;
- fd->fs = RT_NULL;
- fd->flags = 0;
- fd->size = 0;
- fd->pos = 0;
- fd->data = RT_NULL;
- return -DFS_STATUS_ENOSYS;
- }
- if ((result = fs->ops->open(fd)) < 0)
- {
- /* clear fd */
- fd->fs = RT_NULL;
- fd->flags = 0;
- fd->data = RT_NULL;
- dfs_log(DFS_DEBUG_INFO, ("open failed"));
- return result;
- }
- fd->flags |= DFS_F_OPEN;
- if ( flags & DFS_O_DIRECTORY )
- {
- fd->type = FT_DIRECTORY;
- fd->flags |= DFS_F_DIRECTORY;
- }
- dfs_log(DFS_DEBUG_INFO, ("open successful"));
- return 0;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_close
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_close(struct dfs_fd* fd)
- {
- int result = 0;
- if (fd != RT_NULL && fd->fs->ops->close != RT_NULL) result = fd->fs->ops->close(fd);
- /* close fd error, return */
- if ( result < 0 ) return result;
- fd->flags &= ~DFS_F_OPEN;
- return result;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_ioctl
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_ioctl(struct dfs_fd* fd, int cmd, void *args)
- {
- struct dfs_filesystem* fs;
- if (fd == RT_NULL || fd->type != FT_REGULAR) return -DFS_STATUS_EINVAL;
- fs = fd->fs;
- #if 0 /* not support right now */
- if (cmd == FILEGETSIZE)
- {
- if (args == RT_NULL) return -DFS_STATUS_EINVAL;
- *((rt_uint32_t *) args) = fd->size;
- return 0;
- }
- else if (cmd == FILEGETPOS)
- {
- if (args == RT_NULL) return -DFS_STATUS_EINVAL;
- *((rt_uint32_t *) args) = fd->pos;
- return 0;
- }
- #endif
- if (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args);
- return -DFS_STATUS_ENOSYS;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_read
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_read(struct dfs_fd* fd, void *buf, rt_size_t len)
- {
- struct dfs_filesystem* fs;
- int result = 0;
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = (struct dfs_filesystem*) fd->fs;
- if (fs->ops->read == RT_NULL) return -DFS_STATUS_ENOSYS;
- if ( (result = fs->ops->read(fd, buf, len)) < 0 ) fd->flags |= DFS_F_EOF;
- return result;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_getdents
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_getdents(struct dfs_fd* fd, struct dfs_dirent* dirp, rt_size_t nbytes)
- {
- struct dfs_filesystem* fs;
- /* parameter check */
- if (fd == RT_NULL || fd->type != FT_DIRECTORY) return -DFS_STATUS_EINVAL;
- fs = (struct dfs_filesystem*) fd->fs;
- if (fs->ops->getdents != RT_NULL) return fs->ops->getdents(fd, dirp, nbytes);
- return -DFS_STATUS_ENOSYS;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_unlink
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_unlink(const char *path)
- {
- struct dfs_filesystem* fs;
- char *fullpath, *real_path, search_path[DFS_PATH_MAX + 1];
- #ifdef DFS_USING_WORKDIR
- char full_path[DFS_PATH_MAX+1];
- #endif
- struct dfs_fd* fd;
- int index, fspathlen;
- /* Make sure we have an absolute path */
- fullpath = (char*)path;
- if ( fullpath[0] != '/')
- {
- #ifdef DFS_USING_WORKDIR
- /* build full path */
- fullpath = full_path;
- dfs_lock();
- build_fullpath(working_directory, path, fullpath);
- dfs_unlock();
- #else
- #ifdef RT_USING_FINSH
- rt_kprintf("bad filename");
- #endif
- return -1;
- #endif
- }
- if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) return -DFS_STATUS_ENOENT;
- /* Check whether file is already open */
- dfs_lock();
- for (index = 0; index < DFS_FD_MAX; index++)
- {
- fd = &(fd_table[index]);
- if (fd->fs == RT_NULL) continue;
- build_fullpath(fd->fs->path, fd->path, search_path);
- if (strcmp(fullpath, search_path) == 0)
- {
- dfs_unlock();
- return -DFS_STATUS_EEXIST;
- }
- }
- dfs_unlock();
- fspathlen = strlen(fs->path);
- real_path = search_path;
- rt_memset( real_path, 0, sizeof( real_path ) );
- if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/");
- strcat(real_path, fullpath + fspathlen);
- if (fs->ops->unlink != RT_NULL) return fs->ops->unlink(fs, real_path);
- return -DFS_STATUS_ENOSYS;
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_write
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_write(struct dfs_fd* fd, const void *buf, rt_size_t len)
- {
- struct dfs_filesystem* fs = fd->fs;
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
- if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS;
- return fs->ops->write(fd, buf, len);
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_lseek
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_lseek(struct dfs_fd* fd, rt_off_t offset)
- {
- struct dfs_filesystem* fs = fd->fs;
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
- if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS;
- return fs->ops->lseek(fd, offset);
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_stat
- +------------------------------------------------------------------------------
- | Description : get the file or directory stat description
- |
- | Parameters : path, the file or directory path
- | buf, the stat description will be saved in it
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_stat(const char *path, struct dfs_stat *buf)
- {
- struct dfs_filesystem* fs;
- char* fullpath, real_path[DFS_PATH_MAX + 1];
- #ifdef DFS_USING_WORKDIR
- char full_path[DFS_PATH_MAX + 1];
- #endif
- int fspathlen;
- fullpath = (char*)path;
- if ( fullpath[0] != '/' )
- {
- #ifdef DFS_USING_WORKDIR
- /* build full path */
- fullpath = full_path;
- dfs_lock();
- build_fullpath(working_directory, path, fullpath);
- dfs_unlock();
- #else
- #ifdef RT_USING_FINSH
- rt_kprintf("not support working directory, bad filename\n");
- #endif
- return -1;
- #endif
- }
- if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL )
- {
- dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
- return -DFS_STATUS_ENOENT;
- }
- fspathlen = strlen(fs->path);
- rt_memset(real_path, 0, sizeof(real_path));
- if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/");
- strcat(real_path, fullpath + fspathlen);
- if (fs->ops->stat == RT_NULL)
- {
- dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
- return -DFS_STATUS_ENOSYS;
- }
- return fs->ops->stat(fs, real_path, buf);
- }
- /*
- +------------------------------------------------------------------------------
- | Function : dfile_raw_rename
- +------------------------------------------------------------------------------
- | Description :
- |
- | Parameters :
- | Returns :
- |
- +------------------------------------------------------------------------------
- */
- int dfile_raw_rename(const char* oldpath, const char* newpath)
- {
- struct dfs_filesystem *oldfs, *newfs;
- char *oldfullpath, *newfullpath;
- #ifdef DFS_USING_WORKDIR
- /* Change DFS_PATH_MAX to DFS_PATH_MAX + 1, yi.qiu@2008.09.23*/
- char old_realpath[DFS_PATH_MAX + 1], new_realpath[DFS_PATH_MAX + 1];
- #endif
- oldfullpath = (char*)oldpath;
- newfullpath = (char*)newpath;
- if ( oldfullpath[0] != '/' )
- {
- #ifdef DFS_USING_WORKDIR
- /* build full path */
- oldfullpath = old_realpath;
- dfs_lock();
- build_fullpath(working_directory, oldpath, oldfullpath);
- dfs_unlock();
- #else
- rt_kprintf("bad filename\n");
- return -1;
- #endif
- }
- if ( newfullpath[0] != '/' )
- {
- #ifdef DFS_USING_WORKDIR
- /* build full path */
- newfullpath = new_realpath;
- dfs_lock();
- build_fullpath(working_directory, newpath, newfullpath);
- dfs_unlock();
- #else
- rt_kprintf("bad filename");
- return -1;
- #endif
- }
- if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
- {
- return -DFS_STATUS_ENOENT;
- }
- if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
- {
- return -DFS_STATUS_ENOENT;
- }
- if ( oldfs == newfs )
- {
- if ( oldfs->ops->rename == RT_NULL ) return -DFS_STATUS_ENOSYS;
-
- return oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
- }
- /* not at same file system, return EXDEV */
- return -DFS_STATUS_EXDEV;
- }
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- static char fullpath[256 + 1];
- static struct dfs_fd fd;
- static struct dfs_dirent dirent;
- void __ls(const char* pathname)
- {
- struct dfs_stat stat;
- int length;
- /* list directory */
- if ( dfile_raw_open(&fd, pathname, DFS_O_DIRECTORY) == 0 )
- {
- rt_kprintf("Directory %s:\n", pathname);
- do
- {
- rt_memset(&dirent, 0, sizeof(struct dfs_dirent));
- length = dfile_raw_getdents(&fd, &dirent, sizeof(struct dfs_dirent));
- if ( length > 0 )
- {
- rt_memset(&stat, 0, sizeof(struct dfs_stat));
-
- /* build full path for each file */
- strncpy(fullpath, pathname, 256);
- strcat(fullpath, "/");
- strcat(fullpath, dirent.d_name);
-
- dfile_raw_stat(fullpath, &stat);
- if ( stat.st_mode & DFS_S_IFDIR )
- {
- rt_kprintf("%s\t\t<DIR>\n", dirent.d_name);
- }
- else
- {
- rt_kprintf("%s\t\t%lu\n", dirent.d_name, stat.st_size);
- }
- }
- }while(length > 0);
- dfile_raw_close(&fd);
- }
- else
- {
- rt_kprintf("No such directory\n");
- }
- }
- FINSH_FUNCTION_EXPORT(__ls, list directory contents)
- void __mkdir(const char* pathname)
- {
- /* make a new directory */
- if (dfile_raw_open(&fd, pathname, DFS_O_DIRECTORY | DFS_O_CREAT) == 0)
- {
- dfile_raw_close(&fd);
- }
- else rt_kprintf("Can't mkdir %s\n", pathname);
- }
- FINSH_FUNCTION_EXPORT(__mkdir, make a directory)
- void __rm(const char* filename)
- {
- if (dfile_raw_unlink(filename) < 0)
- {
- rt_kprintf("Delete %s failed\n", filename);
- }
- }
- FINSH_FUNCTION_EXPORT(__rm, remove files or directories)
- void __cat(const char* filename)
- {
- rt_uint32_t length;
- char buffer[81];
-
- if (dfile_raw_open(&fd, filename, DFS_O_RDONLY) < 0)
- {
- rt_kprintf("Open %s failed\n", filename);
- return;
- }
-
- do
- {
- rt_memset(buffer, 0, sizeof(buffer));
- length = dfile_raw_read(&fd, buffer, 81);
- if (length > 0)
- {
- rt_kprintf("%s", buffer);
- }
- }while (length > 0);
-
- dfile_raw_close(&fd);
- }
- FINSH_FUNCTION_EXPORT(__cat, print file)
- #ifndef FINSH_USING_SYMTAB
- void dfs_export_finsh(void)
- {
- finsh_syscall_append("ls", (syscall_func)__ls);
- finsh_syscall_append("mkdir", (syscall_func)__mkdir);
- finsh_syscall_append("rm", (syscall_func)__rm);
- finsh_syscall_append("cat", (syscall_func)__cat);
- }
- #endif
- #endif
|