[PATCH] dosfs: Improved UTF-16 handling
sebastian.huber at embedded-brains.de
sebastian.huber at embedded-brains.de
Mon Jun 18 15:11:51 UTC 2012
From: Sebastian Huber <sebastian.huber at embedded-brains.de>
Characters of long file names are encoded in UTF-16. In order to avoid
UTF-16 to UTF-8 conversions the short file name is returned in case a
UTF-16 character with a code point value greater than 255 is found in a
long file name.
---
cpukit/libfs/src/dosfs/msdos_conv.c | 66 +-
cpukit/libfs/src/dosfs/msdos_dir.c | 10 +
testsuites/fstests/Makefile.am | 1 +
testsuites/fstests/configure.ac | 1 +
testsuites/fstests/fsdosfsimage01/Makefile.am | 19 +
.../fstests/fsdosfsimage01/fsdosfsimage01.doc | 11 +
.../fstests/fsdosfsimage01/fsdosfsimage01.scn | 15 +
testsuites/fstests/fsdosfsimage01/image.h | 5474 ++++++++++++++++++++
testsuites/fstests/fsdosfsimage01/init.c | 195 +
9 files changed, 5742 insertions(+), 50 deletions(-)
create mode 100644 testsuites/fstests/fsdosfsimage01/Makefile.am
create mode 100644 testsuites/fstests/fsdosfsimage01/fsdosfsimage01.doc
create mode 100644 testsuites/fstests/fsdosfsimage01/fsdosfsimage01.scn
create mode 100644 testsuites/fstests/fsdosfsimage01/image.h
create mode 100644 testsuites/fstests/fsdosfsimage01/init.c
diff --git a/cpukit/libfs/src/dosfs/msdos_conv.c b/cpukit/libfs/src/dosfs/msdos_conv.c
index 95b2581..e75d3ec 100644
--- a/cpukit/libfs/src/dosfs/msdos_conv.c
+++ b/cpukit/libfs/src/dosfs/msdos_conv.c
@@ -185,56 +185,22 @@ static const uint8_t msdos_map[] = {
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 68-6f */
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 70-77 */
'X', 'Y', 'Z', '{', 0, '}', '~', 0, /* 78-7f */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 80-87 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 88-8f */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 90-97 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 98-9f */
- 0, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* a0-a7 */
- 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* a8-af */
- 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* b0-b7 */
- 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* b8-bf */
- 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* c0-c7 */
- 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* c8-cf */
- 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* d0-d7 */
- 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* d8-df */
- 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* e0-e7 */
- 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* e8-ef */
- 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xf6, /* f0-f7 */
- 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0x98, /* f8-ff */
-#if OLD_TABLE
-/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 20 */ 0x00, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, /* !"#$%&' */
-/* 28 */ 0x28, 0x29, 0x00, 0x00, 0x00, 0x2D, 0x2E, 0x00, /* ()*+,-./ */
-/* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */
-/* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
-/* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* @ABCDEFG */
-/* 48 */ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* HIJKLMNO */
-/* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* PQRSTUVW */
-/* 58 */ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* XYZ[\]^_ */
-/* 60 */ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* `abcdefg */
-/* 68 */ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, /* hijklmno */
-/* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* pqrstuvw */
-/* 78 */ 0x58, 0x59, 0x5A, 0x5B, 0x7C, 0x00, 0x7E, 0x00, /* xyz{|}~ */
-/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* B0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* B8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* C0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* C8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* D0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* D8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-#endif
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 80-87 */
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 88-8f */
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 90-97 */
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 98-9f */
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* a0-a7 */
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* a8-af */
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* b0-b7 */
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* b8-bf */
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* c0-c7 */
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* c8-cf */
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* d0-d7 */
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* d8-df */
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* e0-e7 */
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* e8-ef */
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* f0-f7 */
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff /* f8-ff */
};
/*
* Convert a unix filename to a DOS filename. Return -1 if wrong name is
diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c
index 8175614..9d43bf8 100644
--- a/cpukit/libfs/src/dosfs/msdos_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_dir.c
@@ -278,6 +278,16 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
if (*p == '\0')
break;
+ /*
+ * If we have a real 16-bit char, then return the short
+ * name.
+ */
+ if (*(p + 1) != 0)
+ {
+ lfn_start = FAT_FILE_SHORT_NAME;
+ break;
+ }
+
switch (q)
{
case 4:
diff --git a/testsuites/fstests/Makefile.am b/testsuites/fstests/Makefile.am
index 79aef75..6a8f646 100644
--- a/testsuites/fstests/Makefile.am
+++ b/testsuites/fstests/Makefile.am
@@ -1,6 +1,7 @@
ACLOCAL_AMFLAGS = -I ../aclocal
SUBDIRS =
+SUBDIRS += fsdosfsimage01
SUBDIRS += fsdosfssync01
SUBDIRS += imfs_fserror
SUBDIRS += imfs_fslink
diff --git a/testsuites/fstests/configure.ac b/testsuites/fstests/configure.ac
index 81967a9..2fb5c1a 100644
--- a/testsuites/fstests/configure.ac
+++ b/testsuites/fstests/configure.ac
@@ -77,6 +77,7 @@ AC_CHECK_SIZEOF([blkcnt_t])
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
+fsdosfsimage01/Makefile
fsdosfssync01/Makefile
imfs_fserror/Makefile
imfs_fslink/Makefile
diff --git a/testsuites/fstests/fsdosfsimage01/Makefile.am b/testsuites/fstests/fsdosfsimage01/Makefile.am
new file mode 100644
index 0000000..8e1892c
--- /dev/null
+++ b/testsuites/fstests/fsdosfsimage01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = fsdosfsimage01
+fsdosfsimage01_SOURCES = init.c
+
+dist_rtems_tests_DATA = fsdosfsimage01.scn fsdosfsimage01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(fsdosfsimage01_OBJECTS)
+LINK_LIBS = $(fsdosfsimage01_LDLIBS)
+
+fsdosfsimage01$(EXEEXT): $(fsdosfsimage01_OBJECTS) $(fsdosfsimage01_DEPENDENCIES)
+ @rm -f fsdosfsimage01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.doc b/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.doc
new file mode 100644
index 0000000..573a343
--- /dev/null
+++ b/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.doc
@@ -0,0 +1,11 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: fsdosfsimage01
+
+directives:
+
+ TBD
+
+concepts:
+
+ - Ensure that dosfs can somehow cope with real UTF-16 file names
diff --git a/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.scn b/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.scn
new file mode 100644
index 0000000..2a493dd
--- /dev/null
+++ b/testsuites/fstests/fsdosfsimage01/fsdosfsimage01.scn
@@ -0,0 +1,15 @@
+*** TEST DOSFS IMAGE 1 ***
+dir: directory
+copying: file
+______~1: directory
+.: directory
+..: directory
+empty file: file
+.: directory
+..: directory
+__~1: directory
+__~2: file
+.: directory
+..: directory
+pr�zdn� soubor: file
+*** END OF TEST DOSFS IMAGE 1 ***
diff --git a/testsuites/fstests/fsdosfsimage01/image.h b/testsuites/fstests/fsdosfsimage01/image.h
new file mode 100644
index 0000000..e10a635
--- /dev/null
+++ b/testsuites/fstests/fsdosfsimage01/image.h
@@ -0,0 +1,5474 @@
+/*
+ * Declarations for C structure representing binary file image.bin
+ *
+ * WARNING: Automatically generated -- do not edit!
+ */
+
+#include <sys/types.h>
+
+static unsigned char image_bin[] = {
[... REMOVED ...]
+};
+
+static const size_t image_bin_size = sizeof(image_bin);
diff --git a/testsuites/fstests/fsdosfsimage01/init.c b/testsuites/fstests/fsdosfsimage01/init.c
new file mode 100644
index 0000000..d4e0155
--- /dev/null
+++ b/testsuites/fstests/fsdosfsimage01/init.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <info at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include <rtems/libio.h>
+#include <rtems/blkdev.h>
+#include <rtems/dosfs.h>
+#include <rtems/bdbuf.h>
+#include <rtems/ramdisk.h>
+
+#include "image.h"
+
+#define BLOCK_SIZE 512
+
+#define BLOCK_COUNT (sizeof(image_bin) / BLOCK_SIZE)
+
+typedef struct {
+ const char *name;
+ bool is_dir;
+} dir_entry;
+
+static ramdisk disk_image = {
+ .block_size = BLOCK_SIZE,
+ .block_num = BLOCK_COUNT,
+ .area = &image_bin [0],
+ .initialized = true,
+ .malloced = false,
+ .trace = false,
+ .free_at_delete_request = false
+};
+
+static size_t list_directory(const dir_entry *entries, size_t entry)
+{
+ DIR *dir;
+ struct dirent *de;
+ int rv;
+
+ dir = opendir(".");
+ rtems_test_assert(dir != NULL);
+
+ while ((de = readdir(dir)) != NULL) {
+ const char *name = de->d_name;
+ int fd;
+ struct stat st;
+ bool is_dir;
+
+ fd = open(name, O_RDONLY);
+ rtems_test_assert(fd >= 0);
+
+ rv = fstat(fd, &st);
+ rtems_test_assert(rv == 0);
+
+ is_dir = S_ISDIR(st.st_mode);
+
+ printf("%s: %s\n", name, is_dir ? "directory" : "file");
+
+ rtems_test_assert(S_ISDIR(st.st_mode) || S_ISREG(st.st_mode));
+ rtems_test_assert(is_dir == entries [entry].is_dir);
+ rtems_test_assert(strcmp(name, entries [entry].name) == 0);
+
+ ++entry;
+
+ rv = close(fd);
+ rtems_test_assert(rv == 0);
+ }
+
+ rv = closedir(dir);
+ rtems_test_assert(rv == 0);
+
+ return entry;
+}
+
+static void Init(rtems_task_argument arg)
+{
+ const char *disk = "/dev/rda";
+ const char *mnt = "/mnt";
+ const char *const dirs [] = {
+ "/mnt",
+ "/mnt/dir",
+ "/mnt/______~1",
+ "/mnt/______~1/__~1"
+ };
+ const dir_entry entries [] = {
+ { "dir", true },
+ { "copying", false },
+ { "______~1", true },
+ { ".", true },
+ { "..", true },
+ { "empty file", false },
+ { ".", true },
+ { "..", true },
+ { "__~1", true },
+ { "__~2", false },
+ { ".", true },
+ { "..", true },
+ { "pr\341zdn\375 soubor", false }
+ };
+ rtems_status_code sc;
+ rtems_device_major_number major;
+ dev_t dev;
+ int rv;
+ size_t dir;
+ size_t entry = 0;
+
+ puts("\n\n*** TEST DOSFS IMAGE 1 ***");
+
+ sc = rtems_disk_io_initialize();
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_io_register_driver(0, &ramdisk_ops, &major);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ dev = rtems_filesystem_make_dev_t(major, 0);
+
+ sc = rtems_disk_create_phys(
+ dev,
+ BLOCK_SIZE,
+ BLOCK_COUNT,
+ ramdisk_ioctl,
+ &disk_image,
+ disk
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ rv = mount_and_make_target_path(
+ disk,
+ mnt,
+ RTEMS_FILESYSTEM_TYPE_DOSFS,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ NULL
+ );
+ rtems_test_assert(rv == 0);
+
+ for (dir = 0; dir < sizeof(dirs) / sizeof(dirs [0]); ++dir) {
+ rv = chdir(dirs [dir]);
+ rtems_test_assert(rv == 0);
+
+ entry = list_directory(entries, entry);
+ }
+
+ rv = chdir("/");
+ rtems_test_assert(rv == 0);
+
+ rv = unmount(mnt);
+ rtems_test_assert(rv == 0);
+
+ puts("*** END OF TEST DOSFS IMAGE 1 ***");
+
+ exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 6
+
+#define CONFIGURE_MAXIMUM_DRIVERS 3
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_FILESYSTEM_DOSFS
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
--
1.6.4.2
More information about the devel
mailing list