summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-21 21:04:03 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-21 21:04:03 +0000
commitd88d061f01f4238008e4f24910820b63e5bd7c82 (patch)
treea7bce1326ade43e916fd1eb8d0dbf097e9dc727b
parent3306f330105dafeb0423943fe21fc4a4a30eedc2 (diff)
downloadnuttx-d88d061f01f4238008e4f24910820b63e5bd7c82.tar.gz
nuttx-d88d061f01f4238008e4f24910820b63e5bd7c82.tar.bz2
nuttx-d88d061f01f4238008e4f24910820b63e5bd7c82.zip
Add FAT rename()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@249 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/Documentation/NuttX.html4
-rw-r--r--nuttx/examples/mount/mount_main.c79
-rw-r--r--nuttx/fs/fs_fat32.c112
4 files changed, 185 insertions, 12 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index eaf9de128..1579ded46 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -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
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index e16071e1a..50ba2f76a 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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>
diff --git a/nuttx/examples/mount/mount_main.c b/nuttx/examples/mount/mount_main.c
index ef12c4bb5..0656951d7 100644
--- a/nuttx/examples/mount/mount_main.c
+++ b/nuttx/examples/mount/mount_main.c
@@ -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;
@@ -316,6 +319,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);
diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index 1307520b2..3f2974109 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/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);