9
0
Fork 0

Add FAT rename()

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@249 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2007-05-21 21:04:03 +00:00
parent 4b84f072c9
commit 26d4a9f993
4 changed files with 185 additions and 12 deletions

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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);