Merge pull request #424 from prife/master
dfs_win32: add seekdir support, fix #346
This commit is contained in:
commit
1158fba15b
|
@ -50,6 +50,14 @@
|
||||||
|
|
||||||
#define WIN32_DIRDISK_ROOT "." /* "F:\\Project\\svn\\rtt\\trunk\\bsp\\simulator_test" */
|
#define WIN32_DIRDISK_ROOT "." /* "F:\\Project\\svn\\rtt\\trunk\\bsp\\simulator_test" */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE handle;
|
||||||
|
char *start;
|
||||||
|
char *end;
|
||||||
|
char *curr;
|
||||||
|
struct _finddata_t finddata;
|
||||||
|
} WINDIR;
|
||||||
|
|
||||||
/* There are so many error codes in windows, you'd better google for details.
|
/* There are so many error codes in windows, you'd better google for details.
|
||||||
* google "System Error Codes (Windows)"
|
* google "System Error Codes (Windows)"
|
||||||
* http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms681381(v=vs.85).aspx
|
* http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms681381(v=vs.85).aspx
|
||||||
|
@ -166,8 +174,8 @@ static int dfs_win32_open(struct dfs_fd *file)
|
||||||
oflag = file->flags;
|
oflag = file->flags;
|
||||||
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
||||||
{
|
{
|
||||||
struct _finddata_t dir;
|
WINDIR *wdirp;
|
||||||
int handle;
|
HANDLE handle;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
|
file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
|
||||||
|
@ -191,14 +199,24 @@ static int dfs_win32_open(struct dfs_fd *file)
|
||||||
|
|
||||||
strcat(file_path, "*.*");
|
strcat(file_path, "*.*");
|
||||||
/* _findfirst will get '.' */
|
/* _findfirst will get '.' */
|
||||||
if ((handle = _findfirst(file_path, &dir)) == -1)
|
/* save this pointer,will used by dfs_win32_getdents*/
|
||||||
|
wdirp = rt_malloc(sizeof(WINDIR));
|
||||||
|
RT_ASSERT(wdirp != NULL);
|
||||||
|
if ((handle = _findfirst(file_path, &wdirp->finddata)) == -1)
|
||||||
{
|
{
|
||||||
|
rt_free(wdirp);
|
||||||
rt_free(file_path);
|
rt_free(file_path);
|
||||||
goto __err;
|
goto __err;
|
||||||
}
|
}
|
||||||
|
len = strlen(wdirp->finddata.name) + 1;
|
||||||
|
wdirp->handle = handle;
|
||||||
|
//wdirp->nfiles = 1;
|
||||||
|
wdirp->start = malloc(len); //not rt_malloc!
|
||||||
|
wdirp->end = wdirp->curr = wdirp->start;
|
||||||
|
wdirp->end += len;
|
||||||
|
strncpy(wdirp->curr, wdirp->finddata.name, len);
|
||||||
|
|
||||||
/* save this pointer,will used by dfs_win32_getdents*/
|
file->data = (void *)wdirp;
|
||||||
file->data = (void *)handle;
|
|
||||||
rt_free(file_path);
|
rt_free(file_path);
|
||||||
return DFS_STATUS_OK;
|
return DFS_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
@ -243,25 +261,22 @@ __err:
|
||||||
|
|
||||||
static int dfs_win32_close(struct dfs_fd *file)
|
static int dfs_win32_close(struct dfs_fd *file)
|
||||||
{
|
{
|
||||||
int oflag;
|
if (file->flags & DFS_O_DIRECTORY)
|
||||||
|
|
||||||
oflag = file->flags;
|
|
||||||
if (oflag & DFS_O_DIRECTORY)
|
|
||||||
{
|
{
|
||||||
/* operations about dir */
|
WINDIR *wdirp = (WINDIR*)(file->data);
|
||||||
if (_findclose((intptr_t)file->data) < 0)
|
RT_ASSERT(wdirp != RT_NULL);
|
||||||
goto __err;
|
if (_findclose((intptr_t)wdirp->handle) == 0) {
|
||||||
|
free(wdirp->start); //NOTE: here we don't use rt_free!
|
||||||
return 0;
|
rt_free(wdirp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* regular file operations */
|
||||||
|
{
|
||||||
|
if (_close((int)(file->data)) == 0)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* regular file operations */
|
|
||||||
if (_close((int)(file->data)) < 0)
|
|
||||||
goto __err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
__err:
|
|
||||||
return win32_result_to_dfs(GetLastError());
|
return win32_result_to_dfs(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,16 +331,19 @@ static int dfs_win32_seek(struct dfs_fd *file,
|
||||||
/* set offset as current offset */
|
/* set offset as current offset */
|
||||||
if (file->type == FT_DIRECTORY)
|
if (file->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_ENOSYS;
|
WINDIR* wdirp = (WINDIR*)(file->data);
|
||||||
|
RT_ASSERT(wdirp != RT_NULL);
|
||||||
|
wdirp->curr = wdirp->start + offset;
|
||||||
|
return offset;
|
||||||
}
|
}
|
||||||
else if (file->type == FT_REGULAR)
|
else //file->type == FT_REGULAR)
|
||||||
{
|
{
|
||||||
result = _lseek((int)(file->data), offset, SEEK_SET);
|
result = _lseek((int)(file->data), offset, SEEK_SET);
|
||||||
if (result >= 0)
|
if (result >= 0)
|
||||||
return offset;
|
return offset;
|
||||||
|
else
|
||||||
|
return win32_result_to_dfs(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
return win32_result_to_dfs(GetLastError());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the size of struct dirent*/
|
/* return the size of struct dirent*/
|
||||||
|
@ -334,53 +352,52 @@ static int dfs_win32_getdents(
|
||||||
struct dirent *dirp,
|
struct dirent *dirp,
|
||||||
rt_uint32_t count)
|
rt_uint32_t count)
|
||||||
{
|
{
|
||||||
rt_uint32_t index;
|
WINDIR *wdirp;
|
||||||
struct dirent *d;
|
struct dirent *d = dirp;
|
||||||
struct _finddata_t fileinfo;
|
|
||||||
int handle;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
handle = (int)(file->data);
|
/* make integer count */
|
||||||
RT_ASSERT(handle != RT_NULL);
|
if (count / sizeof(struct dirent) != 1)
|
||||||
|
return -DFS_STATUS_EINVAL;
|
||||||
|
|
||||||
/* round count, count is always 1 */
|
wdirp = (WINDIR*)(file->data);
|
||||||
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
RT_ASSERT(wdirp != RT_NULL);
|
||||||
if (count == 0) return -DFS_STATUS_EINVAL;
|
if (wdirp->curr == NULL) //no more entries in this directory
|
||||||
|
|
||||||
index = 0;
|
|
||||||
/* usually, the while loop should only be looped only once! */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
d = dirp + index;
|
|
||||||
if (_findnext(handle, &fileinfo) != 0) //-1 failed
|
|
||||||
goto __err;
|
|
||||||
|
|
||||||
if (fileinfo.attrib & _A_SUBDIR)
|
|
||||||
d->d_type = DFS_DT_DIR; /* directory */
|
|
||||||
else
|
|
||||||
d->d_type = DFS_DT_REG;
|
|
||||||
|
|
||||||
/* write the rest arguments of struct dirent* dirp */
|
|
||||||
d->d_namlen = strlen(fileinfo.name);
|
|
||||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
|
||||||
strcpy(d->d_name, fileinfo.name);
|
|
||||||
|
|
||||||
index ++;
|
|
||||||
if (index * sizeof(struct dirent) >= count)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (index == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
file->pos += index * sizeof(struct dirent);
|
/* get the current entry */
|
||||||
|
if (wdirp->finddata.attrib & _A_SUBDIR)
|
||||||
return index * sizeof(struct dirent);
|
d->d_type = DFS_DT_DIR;
|
||||||
|
|
||||||
__err:
|
|
||||||
if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
|
|
||||||
return 0;
|
|
||||||
else
|
else
|
||||||
return win32_result_to_dfs(result);
|
d->d_type = DFS_DT_REG;
|
||||||
|
d->d_namlen = strlen(wdirp->curr);
|
||||||
|
strncpy(d->d_name, wdirp->curr, DFS_PATH_MAX);
|
||||||
|
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||||
|
wdirp->curr += (strlen(wdirp->curr) + 1);
|
||||||
|
file->pos = wdirp->curr - wdirp->start + sizeof(struct dirent);//NOTE!
|
||||||
|
|
||||||
|
/* now set up for the next call to readdir */
|
||||||
|
if (wdirp->curr >= wdirp->end)
|
||||||
|
{
|
||||||
|
if (_findnext(wdirp->handle, &wdirp->finddata) == 0)
|
||||||
|
{
|
||||||
|
char* old_start = wdirp->start;
|
||||||
|
long name_len = strlen(wdirp->finddata.name) + 1;
|
||||||
|
wdirp->start = realloc(wdirp->start, wdirp->end - wdirp->start + name_len);
|
||||||
|
wdirp->curr = wdirp->start + (wdirp->curr - old_start);
|
||||||
|
wdirp->end = wdirp->curr + name_len;
|
||||||
|
strcpy(wdirp->curr, wdirp->finddata.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
|
||||||
|
wdirp->curr = NULL;
|
||||||
|
else
|
||||||
|
return win32_result_to_dfs(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof(struct dirent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)
|
static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)
|
||||||
|
|
Loading…
Reference in New Issue