Skip to content

dfs_win32: add seekdir support, fix #346 #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 2, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 82 additions & 65 deletions bsp/simulator/drivers/dfs_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@

#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.
* google "System Error Codes (Windows)"
* http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms681381(v=vs.85).aspx
Expand Down Expand Up @@ -166,8 +174,8 @@ static int dfs_win32_open(struct dfs_fd *file)
oflag = file->flags;
if (oflag & DFS_O_DIRECTORY) /* operations about dir */
{
struct _finddata_t dir;
int handle;
WINDIR *wdirp;
HANDLE handle;
int len;

file_path = winpath_dirdup(WIN32_DIRDISK_ROOT, file->path);
Expand All @@ -191,14 +199,24 @@ static int dfs_win32_open(struct dfs_fd *file)

strcat(file_path, "*.*");
/* _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);
goto __err;
}

/* save this pointer,will used by dfs_win32_getdents*/
file->data = (void *)handle;
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);

file->data = (void *)wdirp;
rt_free(file_path);
return DFS_STATUS_OK;
}
Expand Down Expand Up @@ -243,25 +261,22 @@ static int dfs_win32_open(struct dfs_fd *file)

static int dfs_win32_close(struct dfs_fd *file)
{
int oflag;

oflag = file->flags;
if (oflag & DFS_O_DIRECTORY)
if (file->flags & DFS_O_DIRECTORY)
{
/* operations about dir */
if (_findclose((intptr_t)file->data) < 0)
goto __err;

return 0;
WINDIR *wdirp = (WINDIR*)(file->data);
RT_ASSERT(wdirp != RT_NULL);
if (_findclose((intptr_t)wdirp->handle) == 0) {
free(wdirp->start); //NOTE: here we don't use rt_free!
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());
}

Expand Down Expand Up @@ -316,16 +331,19 @@ static int dfs_win32_seek(struct dfs_fd *file,
/* set offset as current offset */
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);
if (result >= 0)
return offset;
else
return win32_result_to_dfs(GetLastError());
}

return win32_result_to_dfs(GetLastError());
}

/* return the size of struct dirent*/
Expand All @@ -334,53 +352,52 @@ static int dfs_win32_getdents(
struct dirent *dirp,
rt_uint32_t count)
{
rt_uint32_t index;
struct dirent *d;
struct _finddata_t fileinfo;
int handle;
WINDIR *wdirp;
struct dirent *d = dirp;
int result;

handle = (int)(file->data);
RT_ASSERT(handle != RT_NULL);
/* make integer count */
if (count / sizeof(struct dirent) != 1)
return -DFS_STATUS_EINVAL;

/* round count, count is always 1 */
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
if (count == 0) return -DFS_STATUS_EINVAL;
wdirp = (WINDIR*)(file->data);
RT_ASSERT(wdirp != RT_NULL);
if (wdirp->curr == NULL) //no more entries in this directory
return 0;

index = 0;
/* usually, the while loop should only be looped only once! */
while (1)
/* get the current entry */
if (wdirp->finddata.attrib & _A_SUBDIR)
d->d_type = DFS_DT_DIR;
else
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)
{
d = dirp + index;
if (_findnext(handle, &fileinfo) != 0) //-1 failed
goto __err;

if (fileinfo.attrib & _A_SUBDIR)
d->d_type = DFS_DT_DIR; /* directory */
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
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 ((result = GetLastError()) == ERROR_NO_MORE_FILES)
wdirp->curr = NULL;
else
return win32_result_to_dfs(result);
}
}
if (index == 0)
return 0;

file->pos += index * sizeof(struct dirent);

return index * sizeof(struct dirent);

__err:
if ((result = GetLastError()) == ERROR_NO_MORE_FILES)
return 0;
else
return win32_result_to_dfs(result);
return sizeof(struct dirent);
}

static int dfs_win32_unlink(struct dfs_filesystem *fs, const char *path)
Expand Down