# HG changeset patch # User asl # Date 1210701455 0 # Node ID 3071a60a92da267486e1ea2dc3ed7154ed3b89c0 # Parent 872815d742eeca1387f62d24c7e294023c2167dd * src/fatfs.c: Fix handling of '.' and '..' nodes in dirsearch. diff --git a/packages/fs/fat/current/ChangeLog b/packages/fs/fat/current/ChangeLog --- a/packages/fs/fat/current/ChangeLog +++ b/packages/fs/fat/current/ChangeLog @@ -1,3 +1,7 @@ +2008-05-13 Savin Zlobec + + * src/fatfs.c: Fix handling of '.' and '..' nodes in dirsearch. + 2008-04-02 Xinghua Yang Andrew Lunn Taiyun Wang diff --git a/packages/fs/fat/current/src/fatfs.c b/packages/fs/fat/current/src/fatfs.c --- a/packages/fs/fat/current/src/fatfs.c +++ b/packages/fs/fat/current/src/fatfs.c @@ -309,7 +309,15 @@ find_direntry(fatfs_dirsearch_t *ds) CYG_TRACE1(TFS, "searching for dir entry '%s'", ds->name); - // First check the cache + // Check for '.' + + if (!strncmp(".", ds->name, ds->namelen)) + { + ds->node = ds->dir; + return ENOERR; + } + + // Check the cache ds->node = fatfs_node_find(ds->disk, ds->name, @@ -339,15 +347,53 @@ find_direntry(fatfs_dirsearch_t *ds) return (err == EEOF ? ENOERR : err); // Compare filenames - + if ('\0' == dentry.filename[ds->namelen] && 0 == strncasecmp(dentry.filename, ds->name, ds->namelen)) { // Dir entry found - allocate new node and return CYG_TRACE0(TFS, "dir entry found"); + + if (0 == strncmp(ds->name, "..", ds->namelen)) + { + fatfs_dir_entry_t _dentry; + fatfs_data_pos_t _pos; + + if (0 == dentry.cluster) + { + ds->node = ds->disk->root; + return ENOERR; + } + + fatfs_initpos(ds->disk, &dentry, &_pos); + while (true) + { + err = fatfs_read_dir_entry(ds->disk, &dentry, &_pos, &_dentry); + if (err != ENOERR) + return err; + if (0 == strcmp(".", _dentry.filename)) + break; + } + + ds->node = fatfs_node_find(ds->disk, + _dentry.filename, + strlen(_dentry.filename), + _dentry.parent_cluster); + + if (NULL != ds->node) + fatfs_node_touch(ds->disk, ds->node); + else + ds->node = fatfs_node_alloc(ds->disk, &_dentry); + + if (NULL == ds->node) + return EMFILE; + + return ENOERR; + } + else + ds->node = fatfs_node_alloc(ds->disk, &dentry); - ds->node = fatfs_node_alloc(ds->disk, &dentry); if (NULL == ds->node) return EMFILE; diff --git a/packages/fs/fat/current/src/fatfs_supp.c b/packages/fs/fat/current/src/fatfs_supp.c --- a/packages/fs/fat/current/src/fatfs_supp.c +++ b/packages/fs/fat/current/src/fatfs_supp.c @@ -2378,11 +2378,11 @@ fatfs_rename_file(fatfs_disk_t *dis CYG_TRACE0(TDE, "different dirs"); - // Moveing around in different dirs + // Moving around in different dirs fatfs_initpos(disk, dir2, &new_pos); - CYG_TRACE0(TDE, "writting to new dir"); + CYG_TRACE0(TDE, "writing to new dir"); // Get free dir entry in target dir @@ -2399,7 +2399,7 @@ fatfs_rename_file(fatfs_disk_t *dis CYG_TRACE0(TDE, "deleting from old dir"); - // Deleate dentry at old location + // Delete dentry at old location raw_dentry_set_deleted(disk, &raw_dentry); raw_dentry.size = 0;