Files
rtems/testsuites/fstests/fsdosfsname01/init.c
Sebastian Huber a0b1b5edb8 Delete CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
This define was superfluous, undocumented and used inconsistently.
2014-12-16 11:34:38 +01:00

1332 lines
34 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2012, 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@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.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "tmacros.h"
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <bsp.h>
#include <rtems/io.h>
#include <rtems/libio.h>
#include <rtems/dosfs.h>
#include <rtems/ramdisk.h>
#include <rtems/libcsupport.h>
#include "image.h"
#include "image_bin_le_singlebyte.h"
#include "image_bin_le_multibyte.h"
#include "files.h"
#include <errno.h>
const char rtems_test_name[] = "FSDOSFSNAME 1";
#define PRINT_DISK_IMAGE 0
#define MOUNT_DIR "/mnt"
#define MOUNT_DIR_SIZE 4
#define START_DIR_SIZE 4
#define RAMDISK_PATH "/dev/rda"
#define BLOCK_NUM 47
#define BLOCK_SIZE 512
#define NUMBER_OF_DIRECTORIES 8
#define NUMBER_OF_FILES 13
#define NUMBER_OF_DIRECTORIES_INVALID 25
#define NUMBER_OF_DIRECTORIES_DUPLICATED 2
#define NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED 2
#define NUMBER_OF_FILES_DUPLICATED 2
#define NUMBER_OF_NAMES_MULTIBYTE 10
#define MAX_NAME_LENGTH ( 255 + 1 )
#define MAX_NAME_LENGTH_INVALID ( 255 + 2 )
#define MAX_DUPLICATES_PER_NAME 3
static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
#define UTF8_BOM_SIZE 3 /* Size of the UTF-8 byte-order-mark */
#define BLOCK_SIZE 512
#define BLOCK_COUNT ( sizeof( image_bin ) / BLOCK_SIZE )
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 rtems_resource_snapshot before_mount;
static const msdos_format_request_param_t rqdata = {
.OEMName = "RTEMS",
.VolLabel = "RTEMSDisk",
.sectors_per_cluster = 2,
.fat_num = 0,
.files_per_root_dir = 0,
.media = 0,
.quick_format = true,
.skip_alignment = 0,
.info_level = 0
};
static const char DIRECTORY_NAMES[NUMBER_OF_DIRECTORIES]
[MAX_NAME_LENGTH] = {
"a dir",
"Shortdir",
"shrtdir",
"shrt.dir",
"long_conventional_dir",
"long_conventional.dir",
"LongConventionalDir",
"This is a directory name with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx"
};
static const char DIRECTORY_NAMES_INVALID[
NUMBER_OF_DIRECTORIES_INVALID][MAX_NAME_LENGTH_INVALID] = {
"This is a directory name with with 256 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxxx",
".",
"..",
"...",
" ",
"... ...",
" ... ",
"",
"*",
"/",
":",
"<",
">",
"?",
"\\",
"|",
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31},
{127},
"э*_то длинное имя",
"э:_то длинное имя",
"э<_то длинное имя",
"э>_то длинное имя",
"э?_то длинное имя",
"э|_то длинное имя"
};
static const char NAMES_MULTIBYTE[
NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
"đây là một tên tập tin dài",
"Bu uzun bir dosya adı",
"هذا هو اسم ملف طويل",
"αυτό είναι ένα μεγάλο όνομα αρχείου",
"это длинное имя",
"гэта доўгае імя",
"това е дълго име на файла",
"这是一个长文件名",
"shrtname",
"long_conventional_name"
};
static const char NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[
NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
"_\2030005~1._t",
"bu0008~1.bir",
"__000b~1.__",
"__000f~1.__",
"__0012~1.___",
"__0015~1.___",
"__0018~1.___",
"__001a~1",
"shrtname",
"long_conventional_name"
};
static const char FILE_NAMES[NUMBER_OF_FILES][
MAX_NAME_LENGTH] = {
"a file",
"shrtfile",
"ShrtFle",
"The quick brown.fox",
"long_conventional_file",
"This is a filename with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xx140xxxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx",
"+",
",",
"a.a",
";",
"=",
"[",
"]"
};
typedef struct {
char name[MAX_NAME_LENGTH];
unsigned int number_of_duplicates;
char name_duplicates[MAX_DUPLICATES_PER_NAME][MAX_NAME_LENGTH];
} name_duplicates;
static const name_duplicates DIRECTORY_DUPLICATES[
NUMBER_OF_DIRECTORIES_DUPLICATED] = {
{
"shrtdir",
3,
{
"shrtdir",
"SHRTDIR",
"Shrtdir"
}
},
{
"long_conventional_dir",
3,
{
"long_conventional_dir",
"LONG_CONVENTIONAL_DIR",
"Long_conventional_dir"
}
}
};
static const name_duplicates MULTIBYTE_DUPLICATES[
NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED] = {
{
/* The angstroem encoded differently. These encodings might become short entries */
{0xc3, 0x85}, /* '̊A' */
2,
{
{0xc3, 0x85}, /* '̊A' */
{0xe2, 0x84, 0xab} /* 'Å' */
}
},
/* Again the angstroem encoded differently,
* but this time with additional characters in order to enforce a long entry. */
{
{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
0x85},
2,
{
{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
0x85},
{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xe2,
0x84, 0xab}
}
}
};
static const name_duplicates FILES_DUPLICATES[NUMBER_OF_FILES_DUPLICATED] = {
{
"shrtfile",
3,
{
"shrtfile",
"SHRTFILE",
"Shrtfile"
}
},
{
"long_conventional_file",
3,
{
"long_conventional_file",
"LONG_CONVENTIONAL_FILE",
"Long_conventional_file"
}
}
};
static int path_is_directory( const char *path )
{
struct stat s_buf;
if ( stat( path, &s_buf ) )
return 0;
return S_ISDIR( s_buf.st_mode );
}
static void delete_folder_tree( const char *directory_name )
{
DIR *dp;
struct dirent *ep;
char p_buf[1024] = {0};
int rc = 0;
dp = opendir( directory_name );
rtems_test_assert( dp != NULL );
while ( ( ep = readdir( dp ) ) != NULL && rc == 0 ) {
if ( 0 != strcmp( ".", ep->d_name )
&& 0 != strcmp( "..", ep->d_name ) ) {
snprintf( p_buf, sizeof( p_buf ), "%s/%s", directory_name, ep->d_name );
if ( path_is_directory( p_buf ) ) {
delete_folder_tree( p_buf );
rc = rmdir( p_buf );
rtems_test_assert( rc == 0 );
rewinddir( dp );
} else {
rc = unlink( p_buf );
rtems_test_assert( rc == 0 );
rewinddir( dp );
}
}
}
rc = closedir( dp );
rtems_test_assert( rc == 0 );
}
static void mount_device( const char *start_dir,
const rtems_dosfs_mount_options *mount_opts )
{
int rc;
rc = mount(
RAMDISK_PATH,
MOUNT_DIR,
"dosfs",
RTEMS_FILESYSTEM_READ_WRITE,
mount_opts );
rtems_test_assert( rc == 0 );
rc = mkdir( start_dir, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == 0 || ( rc == -1 && errno == EEXIST ) );
}
static void mount_device_with_defaults( const char *start_dir )
{
int rc;
rc = msdos_format( RAMDISK_PATH, &rqdata );
rtems_test_assert( rc == 0 );
rtems_resource_snapshot_take( &before_mount );
mount_device( start_dir, NULL );
}
static void mount_device_with_iconv(
const char *start_dir,
rtems_dosfs_mount_options *mount_opts
)
{
int rc;
rc = msdos_format( RAMDISK_PATH, &rqdata );
rtems_test_assert( rc == 0 );
rtems_resource_snapshot_take( &before_mount );
mount_opts->converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts->converter != NULL );
mount_device( start_dir, mount_opts );
}
static void unmount_and_close_device( void )
{
int rc;
rtems_resource_snapshot now;
bool are_resources_freed;
delete_folder_tree( MOUNT_DIR );
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
are_resources_freed = rtems_resource_snapshot_check( &before_mount );
if ( !are_resources_freed )
rtems_resource_snapshot_take( &now );
rtems_test_assert( are_resources_freed );
}
/*
* Simply create a few directories. These tests should all succeed
*/
static void test_creating_directories(
const char *start_dir,
const char *directories,
const unsigned int number_of_directories )
{
unsigned int index;
int rc;
char dirname[MAX_NAME_LENGTH + strlen( start_dir ) + 1];
DIR *dirp;
struct dirent *dp;
for ( index = 0; index < number_of_directories; ++index ) {
snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir, directories
+ ( index * MAX_NAME_LENGTH ) );
rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == 0 );
}
dirp = opendir( start_dir );
rtems_test_assert( NULL != dirp );
index = 0;
dp = readdir( dirp );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
dp = readdir( dirp );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
dp = readdir( dirp );
rtems_test_assert( dp != NULL );
while ( dp != NULL ) {
rtems_test_assert( 0
== strcmp( directories + ( index * MAX_NAME_LENGTH ),
dp->d_name ) );
++index;
dp = readdir( dirp );
}
rtems_test_assert( number_of_directories == index );
rc = closedir( dirp );
rtems_test_assert( rc == 0 );
}
/*
* Try creating directories with invalid names.
*/
static void test_creating_invalid_directories( void )
{
unsigned int index;
int rc;
char dirname[MAX_NAME_LENGTH_INVALID + MOUNT_DIR_SIZE + 1];
for ( index = 0; index < NUMBER_OF_DIRECTORIES_INVALID; ++index ) {
snprintf( dirname,
sizeof( dirname ),
"%s/%s",
MOUNT_DIR,
DIRECTORY_NAMES_INVALID[index] );
rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == -1 );
}
}
/*
* Try creating directories which do already exist
* (although names may have different capitalization/encoding)
*/
static void test_creating_duplicate_directories(
const char *start_dir,
const name_duplicates *duplicates,
const unsigned int number_of_duplicates )
{
unsigned int index_dir;
unsigned int index_duplicate;
int rc;
char dirname[MAX_NAME_LENGTH + MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
for ( index_dir = 0; index_dir < number_of_duplicates; ++index_dir ) {
snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
duplicates[index_dir].name );
rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == 0 );
for ( index_duplicate = 0;
index_duplicate < duplicates[index_dir].number_of_duplicates;
++index_duplicate ) {
snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
duplicates[index_dir].name_duplicates[index_duplicate] );
errno = 0;
rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == -1 );
rtems_test_assert( errno == EEXIST );
}
}
}
/*
* Try creating and opening files with valid names
*/
static void test_handling_files(
const char *dirname,
const char *file_names,
const unsigned int number_of_files )
{
unsigned int index;
int rc;
char filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE + START_DIR_SIZE
+ 4];
int fd;
for ( index = 0; index < number_of_files; ++index ) {
snprintf(
filename,
sizeof( filename ) - 1,
"%s/%s",
dirname,
file_names + index * MAX_NAME_LENGTH );
fd = open( filename,
O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
rtems_test_assert( fd >= 0 );
rc = close( fd );
rtems_test_assert( rc == 0 );
/* See if the file still exists and can be found */
fd = open( filename, O_RDWR );
rtems_test_assert( fd >= 0 );
rc = close( fd );
rtems_test_assert( rc == 0 );
}
}
/*
* Try to find (and open) all of the file names from an
* array in a given directory
*/
static void test_finding_files(
const char *dirname,
const char *file_names,
const unsigned int number_of_files )
{
int rc;
DIR *dir_stream;
struct dirent *dp;
int fd;
unsigned int index_file;
char filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE
+ START_DIR_SIZE + 4];
dir_stream = opendir( dirname );
rtems_test_assert( dir_stream != NULL );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
index_file = 0;
while ( dp != NULL ) {
rtems_test_assert( 0 == strcmp(
file_names + index_file * MAX_NAME_LENGTH,
dp->d_name ) );
snprintf(
filename,
sizeof( filename ) - 1,
"%s/%s",
dirname,
file_names + index_file * MAX_NAME_LENGTH );
/* See if the file still exists and can be found */
fd = open( filename, O_RDWR );
rtems_test_assert( fd >= 0 );
rc = close( fd );
rtems_test_assert( rc == 0 );
++index_file;
dp = readdir( dir_stream );
}
rtems_test_assert( number_of_files == index_file );
rc = closedir( dir_stream );
rtems_test_assert( rc == 0 );
}
/*
* Try opening files which do already exist (with different capitalization in their names)
*/
static void test_duplicated_files( const char *dirname,
const name_duplicates *files_duplicated,
const unsigned int number_of_files_duplicated )
{
unsigned int index_file;
unsigned int index_duplicate;
int rc;
char filename[MAX_NAME_LENGTH + strlen( dirname ) + 1];
int fd;
for ( index_file = 0; index_file < number_of_files_duplicated;
++index_file ) {
snprintf( filename,
sizeof( filename ) - 1,
"%s/%s",
dirname,
files_duplicated[index_file].name );
fd = open( filename,
O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
rtems_test_assert( fd >= 0 );
rc = close( fd );
rtems_test_assert( rc == 0 );
for ( index_duplicate = 0;
index_duplicate < files_duplicated[index_file].number_of_duplicates;
++index_duplicate ) {
snprintf( filename,
sizeof( filename ) - 1,
"%s/%s",
dirname,
files_duplicated[index_file].name_duplicates[index_duplicate] );
fd = open( filename, O_RDWR );
rtems_test_assert( fd >= 0 );
rc = close( fd );
rtems_test_assert( rc == 0 );
errno = 0;
fd = open( filename, O_RDWR | O_CREAT | O_EXCL );
rtems_test_assert( fd == -1 );
rtems_test_assert( errno == EEXIST );
}
rc = remove( filename );
rtems_test_assert( rc == 0 );
}
}
/*
* Open and read existing valid directories
*/
static void test_handling_directories(
const char *start_dir,
const char *directory_names,
const unsigned int number_of_directories,
const char *file_names,
const unsigned int number_of_files )
{
unsigned int index_directory;
unsigned int index_file;
int rc;
DIR *dir_stream;
char dirname[MAX_NAME_LENGTH * 2];
struct dirent *dp;
for ( index_directory = 0;
index_directory < number_of_directories;
++index_directory ) {
snprintf(
dirname,
sizeof( dirname ) - 1,
"%s/%s",
start_dir,
directory_names + index_directory * MAX_NAME_LENGTH );
test_handling_files(
dirname,
file_names,
number_of_files );
dir_stream = opendir( dirname );
rtems_test_assert( dir_stream != NULL );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
index_file = 0;
while ( dp != NULL ) {
rtems_test_assert( 0 == strcmp(
file_names + index_file * MAX_NAME_LENGTH,
dp->d_name ) );
++index_file;
dp = readdir( dir_stream );
}
rtems_test_assert( number_of_files == index_file );
rc = closedir( dir_stream );
rtems_test_assert( rc == 0 );
}
}
/*
* Try to find all sub-directories from an array
* in a given start directory.
* In addition try to find and open files
* in these sub-directories.
*/
static void test_finding_directories(
const char *start_dir,
const char *directory_names,
const unsigned int number_of_directories,
const char *file_names,
const unsigned int number_of_files )
{
unsigned int index_directory;
int rc;
DIR *dir_stream;
struct dirent *dp;
char dirname[MAX_NAME_LENGTH * 2];
dir_stream = opendir( start_dir );
rtems_test_assert( dir_stream != NULL );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
index_directory = 0;
while ( dp != NULL ) {
rtems_test_assert( 0 == strcmp(
directory_names + index_directory * MAX_NAME_LENGTH,
dp->d_name ) );
snprintf(
dirname,
sizeof( dirname ) - 1,
"%s/%s",
start_dir,
directory_names + index_directory * MAX_NAME_LENGTH );
test_finding_files(
dirname,
file_names,
number_of_files );
++index_directory;
dp = readdir( dir_stream );
}
rtems_test_assert( number_of_directories == index_directory );
rc = closedir( dir_stream );
rtems_test_assert( rc == 0 );
}
#if (PRINT_DISK_IMAGE != 0)
static void print_image(
const char* include_guard,
const char* image_name
)
{
#define BYTES_PER_ROW 8
int rc;
int fd;
ssize_t bytes_read;
uint8_t buf[BLOCK_SIZE];
unsigned int index_block;
unsigned int index_row;
unsigned int index_column;
unsigned int index_buf;
#ifdef SHOW_LINE_NUMBERS
size_t index_row_start = 1;
#endif /* SWOW_LINE_NUMBERS */
size_t bytes_written = 0;
const size_t DISK_SIZE = BLOCK_SIZE * BLOCK_NUM;
const unsigned int ROWS_PER_BLOCK = BLOCK_SIZE / BYTES_PER_ROW;
printf ("/*\n"
" * Declarations for C structure representing a disk image\n"
" *\n"
" * WARNING: Automatically generated by init.c -- do not edit!\n"
" */\n"
"#ifndef %s\n"
"#define %s\n"
"\n"
"#include <sys/types.h>\n"
"\n"
"#ifdef __cplusplus\n"
"extern \"C\" {\n"
"#endif /* __cplusplus */\n"
"\n"
"static unsigned char %s[] = {\n",
include_guard,
include_guard,
image_name);
fd = open( RAMDISK_PATH, O_RDWR );
rtems_test_assert( fd >= 0 );
for ( index_block = 0; index_block < BLOCK_NUM; ++index_block )
{
bytes_read = read( fd, &buf[0], BLOCK_SIZE );
rtems_test_assert( bytes_read = BLOCK_SIZE );
index_buf = 0;
for ( index_row = 0; index_row < ROWS_PER_BLOCK; ++index_row )
{
printf( " " );
for ( index_column = 0;
index_column < BYTES_PER_ROW;
++index_column ) {
printf("0x%02x", buf[index_buf]);
++bytes_written;
++index_buf;
if ( bytes_written < DISK_SIZE ) {
printf (", ");
} else {
printf (" ");
}
}
#ifdef SHOW_LINE_NUMBERS
printf( "/* %6u - %6u */", index_row_start, bytes_written );
index_row_start = bytes_written + 1;
#endif /* SWOW_LINE_NUMBERS */
printf( "\n" );
}
}
rc = close( fd );
rtems_test_assert( rc == 0 );
printf ("};\n"
"#ifdef __cplusplus\n"
"}\n"
"#endif /* __cplusplus */\n"
"\n"
"#endif /* %s */\n",
include_guard);
}
#else /* PRINT_DISK_IMAGE */
static void print_image(
const char* include_guard,
const char* image_name
)
{
/* Nothing to be done */
}
#endif /* PRINT_DISK_IMAGE */
static void compare_files(
const char *file0,
const char *file1
)
{
struct stat stat_buf[2];
int fd[2];
unsigned int index;
uint8_t buf[2];
ssize_t bytes_read;
int rc;
rc = stat( file0 , &stat_buf[0] );
rtems_test_assert( rc == 0 );
rc = stat( file1 , &stat_buf[1] );
rtems_test_assert( rc == 0 );
rtems_test_assert( stat_buf[0].st_size == stat_buf[1].st_size );
fd[0] = open( file0, O_RDONLY );
rtems_test_assert( fd[0] > 0 );
fd[1] = open( file1, O_RDONLY );
rtems_test_assert( fd[1] > 0 );
for ( index = 0; index < stat_buf[0].st_size; ++index ) {
bytes_read = read( fd[0], &buf[0], 1 );
rtems_test_assert( bytes_read == 1 );
bytes_read = read( fd[1], &buf[1], 1 );
rtems_test_assert( bytes_read == 1 );
rtems_test_assert( buf[0] == buf[1] );
}
rc = close( fd[0] );
rtems_test_assert( rc == 0 );
rc = close( fd[1] );
rtems_test_assert( rc == 0 );
}
static void compare_directories(
const char *dir0,
const char *dir1)
{
int rc;
DIR *dir_stream[2];
struct dirent *dp;
struct stat stat_buf[2];
char *path[2];
const unsigned int PATH_LENGTH = 1024;
path[0] = calloc( PATH_LENGTH, sizeof(char) );
rtems_test_assert( path[0] != NULL );
path[1] = calloc( PATH_LENGTH, sizeof(char) );
rtems_test_assert( path[1] != NULL );
dir_stream[0] = opendir( dir0 );
rtems_test_assert( dir_stream[0] != NULL );
dir_stream[1] = opendir( dir1 );
rtems_test_assert( dir_stream[1] != NULL );
dp = readdir( dir_stream[0] );
rtems_test_assert( dp != NULL );
while ( dp != NULL ) {
rc = snprintf(path[0], PATH_LENGTH, "%s/%s", dir0, dp->d_name);
rtems_test_assert( rc < PATH_LENGTH );
rtems_test_assert( rc >= 0 );
rc = snprintf(path[1], PATH_LENGTH, "%s/%s", dir1, dp->d_name);
rtems_test_assert( rc < PATH_LENGTH );
rtems_test_assert( rc >= 0 );
rc = stat( path[0] , &stat_buf[0] );
rtems_test_assert( rc == 0 );
if ( ( strcmp( dp->d_name, "." ) != 0)
&& ( strcmp( dp->d_name, ".." ) != 0) ) {
if ( S_ISDIR( stat_buf[0].st_mode ) ) {
compare_directories( path[0], path[1] );
} else {
compare_files( path[0], path[1] );
}
}
dp = readdir( dir_stream[0] );
}
rc = closedir( dir_stream[0] );
rtems_test_assert( rc == 0 );
rc = closedir( dir_stream[1] );
rtems_test_assert( rc == 0 );
free (path[0]);
free (path[1]);
}
static void compare_image(
const char *mount_dir,
const char *dev,
const rtems_dosfs_mount_options *mount_opts )
{
#define MOUNT_DIR2 "/mnt2"
int rc;
rc = mount_and_make_target_path(
dev,
MOUNT_DIR2,
RTEMS_FILESYSTEM_TYPE_DOSFS,
RTEMS_FILESYSTEM_READ_WRITE,
mount_opts );
rtems_test_assert( rc == 0 );
compare_directories(mount_dir, MOUNT_DIR2);
rc = unmount( MOUNT_DIR2 );
rtems_test_assert( rc == 0 );
rc = rmdir( MOUNT_DIR2 );
rtems_test_assert( rc == 0 );
}
/*
* Test the compatibility with a genuine MS Windows FAT file system.
*/
static void test_compatibility( void )
{
int rc;
rtems_status_code sc;
dev_t dev;
char diskpath[] = "/dev/ramdisk1";
rtems_dosfs_mount_options mount_opts;
rtems_device_major_number major;
FILE *fp;
int buffer;
unsigned int index_file = 0;
unsigned int index_char;
unsigned int offset;
char content_buf[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
+ 1];
char file_path[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
+ 1];
DIR *dir_stream;
struct dirent *dp;
mount_opts.converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts.converter != NULL );
sc = rtems_io_register_driver( 0, &ramdisk_ops, &major );
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
dev = rtems_filesystem_make_dev_t( major, 1 );
sc = rtems_disk_create_phys(
dev,
BLOCK_SIZE,
BLOCK_COUNT,
ramdisk_ioctl,
&disk_image,
diskpath );
rtems_test_assert( sc == RTEMS_SUCCESSFUL );
rc = mount_and_make_target_path(
diskpath,
MOUNT_DIR,
RTEMS_FILESYSTEM_TYPE_DOSFS,
RTEMS_FILESYSTEM_READ_WRITE,
&mount_opts );
rtems_test_assert( rc == 0 );
dir_stream = opendir( MOUNT_DIR );
rtems_test_assert( dir_stream != NULL );
dp = readdir( dir_stream );
rtems_test_assert( dp != NULL );
while ( dp != NULL ) {
index_char = 0;
size_t len = strlen( filenames[index_file] );
if ( filenames[index_file][len - 1] == '.' )
rtems_test_assert( ( len - 1 ) == dp->d_namlen );
else
rtems_test_assert( len == dp->d_namlen );
rtems_test_assert( 0
== memcmp( &filenames[index_file][0], &dp->d_name[0],
dp->d_namlen ) );
snprintf( file_path, sizeof( file_path ), "%s/%s", MOUNT_DIR,
filenames[index_file] );
fp = fopen( file_path, "r" );
rtems_test_assert( fp != NULL );
/* These files should contain their own file names. */
while ( ( buffer = fgetc( fp ) ) != EOF ) {
content_buf[index_char] = buffer;
++index_char;
}
if ( 0 == strncmp( content_buf, UTF8_BOM, UTF8_BOM_SIZE ) )
offset = UTF8_BOM_SIZE;
else
offset = 0;
rtems_test_assert( 0
== memcmp( filenames[index_file],
&content_buf[offset],
index_char - offset ) );
rc = fclose( fp );
rtems_test_assert( rc == 0 );
++index_file;
dp = readdir( dir_stream );
}
rtems_test_assert( index_file == FILES_FILENAMES_NUMBER_OF );
rc = closedir( dir_stream );
rtems_test_assert( rc == 0 );
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
}
/*
* Main test method
*/
static void test( void )
{
int rc;
char start_dir[MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
rtems_dosfs_mount_options mount_opts[2];
rc = mkdir( MOUNT_DIR, S_IRWXU | S_IRWXG | S_IRWXO );
rtems_test_assert( rc == 0 );
snprintf( start_dir, sizeof( start_dir ), "%s/%s", MOUNT_DIR, "strt" );
/*
* Tests with code page 850 compatible directory and file names
* and the code page 850 backwards compatible default mode mode of the
* FAT file system
*/
mount_device_with_defaults( start_dir );
test_creating_duplicate_directories(
&start_dir[0],
&DIRECTORY_DUPLICATES[0],
NUMBER_OF_DIRECTORIES_DUPLICATED );
unmount_and_close_device();
mount_device_with_defaults( start_dir );
test_duplicated_files(
MOUNT_DIR,
FILES_DUPLICATES,
NUMBER_OF_FILES_DUPLICATED );
unmount_and_close_device();
mount_device_with_defaults( start_dir );
test_creating_invalid_directories();
test_creating_directories(
&start_dir[0],
&DIRECTORY_NAMES[0][0],
NUMBER_OF_DIRECTORIES );
test_handling_directories(
&start_dir[0],
&DIRECTORY_NAMES[0][0],
NUMBER_OF_DIRECTORIES,
&FILE_NAMES[0][0],
NUMBER_OF_FILES );
compare_image(
MOUNT_DIR,
"/dev/rdb",
NULL);
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
/*
* Again tests with code page 850 compatible directory and file names
* but with multibyte string compatible conversion methods which use
* iconv and utf8proc
*/
mount_opts[0].converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts[0].converter != NULL );
rc = mount(
RAMDISK_PATH,
MOUNT_DIR,
"dosfs",
RTEMS_FILESYSTEM_READ_WRITE,
&mount_opts );
rtems_test_assert( rc == 0 );
test_finding_directories(
&start_dir[0],
&DIRECTORY_NAMES[0][0],
NUMBER_OF_DIRECTORIES,
&FILE_NAMES[0][0],
NUMBER_OF_FILES );
unmount_and_close_device();
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_creating_invalid_directories();
test_creating_duplicate_directories(
&start_dir[0],
&DIRECTORY_DUPLICATES[0],
NUMBER_OF_DIRECTORIES_DUPLICATED );
unmount_and_close_device();
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_duplicated_files(
MOUNT_DIR,
FILES_DUPLICATES,
NUMBER_OF_FILES_DUPLICATED );
unmount_and_close_device();
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_creating_directories(
&start_dir[0],
&DIRECTORY_NAMES[0][0],
NUMBER_OF_DIRECTORIES );
test_handling_directories(
&start_dir[0],
&DIRECTORY_NAMES[0][0],
NUMBER_OF_DIRECTORIES,
&FILE_NAMES[0][0],
NUMBER_OF_FILES );
mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts[1].converter != NULL );
compare_image(
MOUNT_DIR,
"/dev/rdb",
&mount_opts[1]);
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
print_image(
"IMAGE_BIN_LE_SINGLEBYTE_H_",
"IMAGE_BIN_LE_SINGLEBYTE");
rc = mount(
RAMDISK_PATH,
MOUNT_DIR,
"dosfs",
RTEMS_FILESYSTEM_READ_WRITE,
NULL );
rtems_test_assert( rc == 0 );
unmount_and_close_device();
/*
* Tests with multibyte directory and file names and
* with multibyte string compatible conversion methods which use
* iconv and utf8proc
*/
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_creating_duplicate_directories(
&start_dir[0],
&MULTIBYTE_DUPLICATES[0],
NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
unmount_and_close_device();
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_duplicated_files(
MOUNT_DIR,
&MULTIBYTE_DUPLICATES[0],
NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
unmount_and_close_device();
mount_device_with_iconv( start_dir, &mount_opts[0] );
test_creating_directories(
&start_dir[0],
&NAMES_MULTIBYTE[0][0],
NUMBER_OF_NAMES_MULTIBYTE );
test_handling_directories(
&start_dir[0],
&NAMES_MULTIBYTE[0][0],
NUMBER_OF_NAMES_MULTIBYTE,
&NAMES_MULTIBYTE[0][0],
NUMBER_OF_NAMES_MULTIBYTE );
mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
rtems_test_assert( mount_opts[1].converter != NULL );
compare_image(
MOUNT_DIR,
"/dev/rdc",
&mount_opts[1]);
rc = unmount( MOUNT_DIR );
rtems_test_assert( rc == 0 );
print_image(
"IMAGE_BIN_LE_MULTIBYTE_H_",
"IMAGE_BIN_LE_MULTIBYTE");
rc = mount(
RAMDISK_PATH,
MOUNT_DIR,
"dosfs",
RTEMS_FILESYSTEM_READ_WRITE,
NULL );
rtems_test_assert( rc == 0 );
test_finding_directories(
&start_dir[0],
&NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
NUMBER_OF_NAMES_MULTIBYTE,
&NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
NUMBER_OF_NAMES_MULTIBYTE );
unmount_and_close_device();
test_compatibility();
}
static void Init( rtems_task_argument arg )
{
TEST_BEGIN();
test();
TEST_END();
rtems_test_exit( 0 );
}
rtems_ramdisk_config rtems_ramdisk_configuration [] = {
{ .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM },
{ .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_SINGLEBYTE[0] },
{ .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_MULTIBYTE[0] }
};
size_t rtems_ramdisk_configuration_size = RTEMS_ARRAY_SIZE(rtems_ramdisk_configuration);
#define CONFIGURE_INIT_TASK_STACK_SIZE ( 1024 * 64 )
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MAXIMUM_DRIVERS 4
#define CONFIGURE_MAXIMUM_SEMAPHORES (2 * RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE)
#define CONFIGURE_APPLICATION_EXTRA_DRIVERS RAMDISK_DRIVER_TABLE_ENTRY
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
#define CONFIGURE_FILESYSTEM_DOSFS
/* 2 RAM disk device files + 2 mount_dir + stdin + stdout + stderr +
* 2 for open directories/files + 4 * 2 for recursive tree compares*/
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS ( 7 + 2 + ( 4 * 2 ) )
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>