Add FAT rename()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@249 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f0634f5588
commit
2a7e55b1fc
@ -142,6 +142,6 @@
|
||||
|
||||
* Added unlink(), mkdir(), rmdir(), and rename()
|
||||
* Fixed several serious FAT errors with oflags handling (&& instead of &)
|
||||
* Added FAT support for unlink(), mkdir() and rmdir()
|
||||
* Added FAT support for unlink(), mkdir(), rmdir(), and rename
|
||||
* Started m68322
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: May 19, 2007</p>
|
||||
<p>Last Updated: May 21, 2007</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -573,7 +573,7 @@ Other memory:
|
||||
|
||||
* Added unlink(), mkdir(), rmdir(), and rename()
|
||||
* Fixed several serious FAT errors with oflags handling (&& instead of &)
|
||||
* Added FAT support for unlink(), mkdir() and rmdir()
|
||||
* Added FAT support for unlink(), mkdir(), rmdir(), and rename()
|
||||
* Started m68322
|
||||
</pre></ul>
|
||||
|
||||
|
@ -65,10 +65,13 @@ static const char g_target[] = "/mnt/fs";
|
||||
static const char g_filesystemtype[] = "vfat";
|
||||
|
||||
static const char g_testdir1[] = "/mnt/fs/TestDir";
|
||||
static const char g_testdir2[] = "/mnt/fs/NewDir";
|
||||
static const char g_testdir2[] = "/mnt/fs/NewDir1";
|
||||
static const char g_testdir3[] = "/mnt/fs/NewDir2";
|
||||
static const char g_testdir4[] = "/mnt/fs/NewDir3";
|
||||
static const char g_testfile1[] = "/mnt/fs/TestDir/TestFile.txt";
|
||||
static const char g_testfile2[] = "/mnt/fs/TestDir/WritTest.txt";
|
||||
static const char g_testfile3[] = "/mnt/fs/NewDir/WritTest.txt";
|
||||
static const char g_testfile2[] = "/mnt/fs/TestDir/WrTest1.txt";
|
||||
static const char g_testfile3[] = "/mnt/fs/NewDir1/WrTest2.txt";
|
||||
static const char g_testfile4[] = "/mnt/fs/NewDir3/Renamed.txt";
|
||||
static const char g_testmsg[] = "This is a write test";
|
||||
|
||||
static int g_nerrors = 0;
|
||||
@ -315,6 +318,52 @@ static void succeed_unlink(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fail_rename
|
||||
****************************************************************************/
|
||||
|
||||
static void fail_rename(const char *oldpath, const char *newpath, int expectederror)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Try rename() against a file or directory. It should fail with expectederror */
|
||||
|
||||
printf("fail_rename: Try rename(%s->%s)\n", oldpath, newpath);
|
||||
|
||||
ret = rename(oldpath, newpath);
|
||||
if (ret == 0)
|
||||
{
|
||||
printf("fail_rename: ERROR rename(%s->%s) succeeded\n",
|
||||
oldpath, newpath);
|
||||
g_nerrors++;
|
||||
}
|
||||
else if (*get_errno_ptr() != expectederror)
|
||||
{
|
||||
printf("fail_rename: ERROR rename(%s->%s) failed with errno=%d (expected %d)\n",
|
||||
oldpath, newpath, *get_errno_ptr(), expectederror);
|
||||
g_nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: succeed_rename
|
||||
****************************************************************************/
|
||||
|
||||
static void succeed_rename(const char *oldpath, const char *newpath)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printf("succeed_rename: Try rename(%s->%s)\n", oldpath, newpath);
|
||||
|
||||
ret = rename(oldpath, newpath);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf("succeed_rename: ERROR rename(%s->%s) failed with errno=%d\n",
|
||||
oldpath, newpath, *get_errno_ptr());
|
||||
g_nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -413,6 +462,30 @@ int user_start(int argc, char *argv[])
|
||||
|
||||
read_test_file(g_testfile3);
|
||||
|
||||
/* Use mkdir() to create test dir3. It should succeed */
|
||||
|
||||
succeed_mkdir(g_testdir3);
|
||||
|
||||
/* Try rename() on the root directory. Should fail with EXDEV*/
|
||||
|
||||
fail_rename(g_target, g_testdir4, EXDEV);
|
||||
|
||||
/* Try rename() to an existing directory. Should fail with EEXIST */
|
||||
|
||||
fail_rename(g_testdir2, g_testdir3, EEXIST);
|
||||
|
||||
/* Try rename() to a non-existing directory. Should succeed */
|
||||
|
||||
succeed_rename(g_testdir3, g_testdir4);
|
||||
|
||||
/* Try rename() of file. Should work. */
|
||||
|
||||
succeed_rename(g_testfile3, g_testfile4);
|
||||
|
||||
/* Make sure that we can still read the renamed file */
|
||||
|
||||
read_test_file(g_testfile4);
|
||||
|
||||
/* Unmount the file system */
|
||||
|
||||
printf("user_start: Try unmount(%s)\n", g_target);
|
||||
|
112
fs/fs_fat32.c
112
fs/fs_fat32.c
@ -90,8 +90,8 @@ static int fat_unlink(struct inode *mountpt, const char *relpath);
|
||||
static int fat_mkdir(struct inode *mountpt, const char *relpath,
|
||||
mode_t mode);
|
||||
static int fat_rmdir(struct inode *mountpt, const char *relpath);
|
||||
static int fat_rename(struct inode *mountpt, const char *old_relpath,
|
||||
const char *new_relpath);
|
||||
static int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
||||
const char *newrelpath);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
@ -1615,10 +1615,15 @@ int fat_rmdir(struct inode *mountpt, const char *relpath)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int fat_rename(struct inode *mountpt, const char *old_relpath,
|
||||
const char *new_relpath)
|
||||
int fat_rename(struct inode *mountpt, const char *oldrelpath,
|
||||
const char *newrelpath)
|
||||
{
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_dirinfo_s dirinfo;
|
||||
size_t oldsector;
|
||||
ubyte *olddirentry;
|
||||
ubyte *newdirentry;
|
||||
ubyte dirstate[32-11];
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@ -1638,8 +1643,103 @@ int fat_rename(struct inode *mountpt, const char *old_relpath,
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
#warning "fat_rename is not implemented"
|
||||
ret = -ENOSYS;
|
||||
/* Find the directory entry for the oldrelpath */
|
||||
|
||||
ret = fat_finddirentry(fs, &dirinfo, oldrelpath);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* Some error occurred -- probably -ENOENT */
|
||||
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Save the information that will need to recover the
|
||||
* directory sector and directory entry offset to the
|
||||
* old directory.
|
||||
*/
|
||||
|
||||
olddirentry = dirinfo.fd_entry;
|
||||
|
||||
/* One more check: Make sure that the oldrelpath does
|
||||
* not refer to the root directory. We can't rename the
|
||||
* root directory.
|
||||
*/
|
||||
|
||||
if (!olddirentry)
|
||||
{
|
||||
ret = -EXDEV;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
oldsector = fs->fs_currentsector;
|
||||
memcpy(dirstate, &olddirentry[DIR_ATTRIBUTES], 32-11);
|
||||
|
||||
/* No find the directory where we should create the newpath object */
|
||||
|
||||
ret = fat_finddirentry(fs, &dirinfo, newrelpath);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* It is an error if the object at newrelpath already exists */
|
||||
|
||||
ret = -EEXIST;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* What we expect is -ENOENT mean that the full directory path was
|
||||
* followed but that the object does not exists in the terminal directory.
|
||||
*/
|
||||
|
||||
if (ret != -ENOENT)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Reserve a directory entry */
|
||||
|
||||
ret = fat_allocatedirentry(fs, &dirinfo);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Create the new directory entry */
|
||||
|
||||
newdirentry = dirinfo.fd_entry;
|
||||
|
||||
memcpy(&newdirentry[DIR_ATTRIBUTES], dirstate, 32-11);
|
||||
memcpy(&newdirentry[DIR_NAME], dirinfo.fd_name, 8+3);
|
||||
#ifdef CONFIG_FLAT_LCNAMES
|
||||
DIR_PUTNTRES(newdirentry, dirinfo.fd_ntflags);
|
||||
#else
|
||||
DIR_PUTNTRES(newdirentry, 0);
|
||||
#endif
|
||||
fs->fs_dirty = TRUE;
|
||||
|
||||
/* Now flush the new directory entry to disk and read the sector
|
||||
* containing the old directory entry.
|
||||
*/
|
||||
|
||||
ret = fat_fscacheread(fs, oldsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Remove the old entry */
|
||||
|
||||
olddirentry[DIR_NAME] = DIR0_EMPTY;
|
||||
fs->fs_dirty = TRUE;
|
||||
|
||||
/* Write the old entry to disk and update FSINFO if necessary */
|
||||
|
||||
ret = fat_updatefsinfo(fs);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
return OK;
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
|
Loading…
Reference in New Issue
Block a user