source: rtems/testsuites/fstests/fsdosfsname01/init.c @ 892abd53

4.115
Last change on this file since 892abd53 was a45b2ac9, checked in by Ralf Kirchner <ralf.kirchner@…>, on 11/15/13 at 12:45:01

fsdosfsname01: Improve test for duplicate names

  • Property mode set to 100644
File size: 33.6 KB
Line 
1/*
2 * Copyright (c) 2012, 2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19
20#include "tmacros.h"
21
22#include <errno.h>
23#include <fcntl.h>
24#include <dirent.h>
25
26#include <bsp.h>
27#include <rtems/io.h>
28#include <rtems/libio.h>
29#include <rtems/dosfs.h>
30#include <rtems/ramdisk.h>
31#include <rtems/libcsupport.h>
32#include "image.h"
33#include "image_bin_le_singlebyte.h"
34#include "image_bin_le_multibyte.h"
35#include "files.h"
36
37#include <errno.h>
38
39#define PRINT_DISK_IMAGE 0
40
41#define MOUNT_DIR "/mnt"
42#define MOUNT_DIR_SIZE 4
43#define START_DIR_SIZE 4
44#define RAMDISK_PATH "/dev/rda"
45#define BLOCK_NUM 47
46#define BLOCK_SIZE 512
47
48#define NUMBER_OF_DIRECTORIES 8
49#define NUMBER_OF_FILES 13
50#define NUMBER_OF_DIRECTORIES_INVALID 25
51#define NUMBER_OF_DIRECTORIES_DUPLICATED 2
52#define NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED 2
53#define NUMBER_OF_FILES_DUPLICATED 2
54#define NUMBER_OF_NAMES_MULTIBYTE 10
55#define MAX_NAME_LENGTH ( 255 + 1 )
56#define MAX_NAME_LENGTH_INVALID ( 255 + 2 )
57#define MAX_DUPLICATES_PER_NAME 3
58static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
59#define UTF8_BOM_SIZE 3 /* Size of the UTF-8 byte-order-mark */
60
61#define BLOCK_SIZE 512
62
63#define BLOCK_COUNT ( sizeof( image_bin ) / BLOCK_SIZE )
64
65static ramdisk                            disk_image = {
66  .block_size             = BLOCK_SIZE,
67  .block_num              = BLOCK_COUNT,
68  .area                   = &image_bin[0],
69  .initialized            = true,
70  .malloced               = false,
71  .trace                  = false,
72  .free_at_delete_request = false
73};
74
75static rtems_resource_snapshot            before_mount;
76
77static const msdos_format_request_param_t rqdata = {
78  .OEMName             = "RTEMS",
79  .VolLabel            = "RTEMSDisk",
80  .sectors_per_cluster = 2,
81  .fat_num             = 0,
82  .files_per_root_dir  = 0,
83  .media               = 0,
84  .quick_format        = true,
85  .skip_alignment      = 0,
86  .info_level          = 0
87};
88
89static const char                         DIRECTORY_NAMES[NUMBER_OF_DIRECTORIES]
90[MAX_NAME_LENGTH] = {
91  "a dir",
92  "Shortdir",
93  "shrtdir",
94  "shrt.dir",
95  "long_conventional_dir",
96  "long_conventional.dir",
97  "LongConventionalDir",
98  "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"
99};
100
101static const char DIRECTORY_NAMES_INVALID[
102  NUMBER_OF_DIRECTORIES_INVALID][MAX_NAME_LENGTH_INVALID] = {
103  "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",
104  ".",
105  "..",
106  "...",
107  " ",
108  "... ...",
109  " ... ",
110  "",
111  "*",
112  "/",
113  ":",
114  "<",
115  ">",
116  "?",
117  "\\",
118  "|",
119  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
120    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
121    20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31},
122  {127},
123  "э*_тП ЎлОММПе ОЌя",
124  "э:_тП ЎлОММПе ОЌя",
125  "э<_тП ЎлОММПе ОЌя",
126  "э>_тП ЎлОММПе ОЌя",
127  "э?_тП ЎлОММПе ОЌя",
128  "э|_тП ЎлОММПе ОЌя"
129};
130
131static const char NAMES_MULTIBYTE[
132  NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
133  "đây là một tên tập tin dài",
134  "Bu uzun bir dosya adı",
135  "هذا هو اسم Ù…لف طويل",
136  "αυτό είΜαι έΜα Όεγάλο όΜοΌα αρχείου",
137  "этП ЎлОММПе ОЌя",
138  "гэта ЎПўгае іЌя",
139  "тПва е ЎългП ОЌе Ма файла",
140  "这是䞀䞪长文件名",
141  "shrtname",
142  "long_conventional_name"
143};
144
145static const char NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[
146  NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
147  "_\2030005~1._t",
148  "bu0008~1.bir",
149  "__000b~1.__",
150  "__000f~1.__",
151  "__0012~1.___",
152  "__0015~1.___",
153  "__0018~1.___",
154  "__001a~1",
155  "shrtname",
156  "long_conventional_name"
157};
158
159static const char FILE_NAMES[NUMBER_OF_FILES][
160  MAX_NAME_LENGTH] = {
161  "a file",
162  "shrtfile",
163  "ShrtFle",
164  "The quick brown.fox",
165  "long_conventional_file",
166  "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",
167  "+",
168  ",",
169  "a.a",
170  ";",
171  "=",
172  "[",
173  "]"
174};
175
176typedef struct {
177  char name[MAX_NAME_LENGTH];
178  unsigned int number_of_duplicates;
179  char name_duplicates[MAX_DUPLICATES_PER_NAME][MAX_NAME_LENGTH];
180} name_duplicates;
181
182static const name_duplicates DIRECTORY_DUPLICATES[
183  NUMBER_OF_DIRECTORIES_DUPLICATED] = {
184  {
185    "shrtdir",
186    3,
187    {
188      "shrtdir",
189      "SHRTDIR",
190      "Shrtdir"
191    }
192  },
193  {
194    "long_conventional_dir",
195    3,
196    {
197      "long_conventional_dir",
198      "LONG_CONVENTIONAL_DIR",
199      "Long_conventional_dir"
200    }
201  }
202};
203
204static const name_duplicates MULTIBYTE_DUPLICATES[
205  NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED] = {
206  {
207    /* The angstroem encoded differently. These encodings might become short entries */
208    {0xc3, 0x85}, /* '̊A' */
209    2,
210    {
211      {0xc3, 0x85}, /* '̊A' */
212      {0xe2, 0x84, 0xab} /* 'Å' */
213    }
214  },
215
216  /* Again the angstroem encoded differently,
217   * but this time with additional characters in order to enforce a long entry. */
218  {
219    {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
220     0x85},
221    2,
222    {
223      {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
224       0x85},
225      {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xe2,
226       0x84, 0xab}
227    }
228  }
229};
230
231
232static const name_duplicates FILES_DUPLICATES[NUMBER_OF_FILES_DUPLICATED] = {
233  {
234    "shrtfile",
235    3,
236    {
237      "shrtfile",
238      "SHRTFILE",
239      "Shrtfile"
240    }
241  },
242  {
243    "long_conventional_file",
244    3,
245    {
246      "long_conventional_file",
247      "LONG_CONVENTIONAL_FILE",
248      "Long_conventional_file"
249    }
250  }
251};
252
253static int path_is_directory( const char *path )
254{
255  struct stat s_buf;
256
257
258  if ( stat( path, &s_buf ) )
259    return 0;
260
261  return S_ISDIR( s_buf.st_mode );
262}
263
264static void delete_folder_tree( const char *directory_name )
265{
266  DIR           *dp;
267  struct dirent *ep;
268  char           p_buf[1024] = {0};
269  int            rc          = 0;
270
271
272  dp = opendir( directory_name );
273  rtems_test_assert( dp != NULL );
274
275  while ( ( ep = readdir( dp ) ) != NULL && rc == 0 ) {
276    if ( 0 != strcmp( ".", ep->d_name )
277         && 0 != strcmp( "..", ep->d_name ) ) {
278      snprintf( p_buf, sizeof( p_buf ), "%s/%s", directory_name, ep->d_name );
279
280      if ( path_is_directory( p_buf ) ) {
281        delete_folder_tree( p_buf );
282        rc = rmdir( p_buf );
283        rtems_test_assert( rc == 0 );
284        rewinddir( dp );
285      } else {
286        rc = unlink( p_buf );
287        rtems_test_assert( rc == 0 );
288        rewinddir( dp );
289      }
290    }
291  }
292
293  rc = closedir( dp );
294  rtems_test_assert( rc == 0 );
295}
296
297static void mount_device( const char *start_dir,
298  const rtems_dosfs_mount_options    *mount_opts )
299{
300  int rc;
301
302  rc = mount(
303    RAMDISK_PATH,
304    MOUNT_DIR,
305    "dosfs",
306    RTEMS_FILESYSTEM_READ_WRITE,
307    mount_opts );
308  rtems_test_assert( rc == 0 );
309
310  rc = mkdir( start_dir, S_IRWXU | S_IRWXG | S_IRWXO );
311  rtems_test_assert( rc == 0 || ( rc == -1 && errno == EEXIST ) );
312}
313
314static void mount_device_with_defaults( const char *start_dir )
315{
316  int rc;
317
318
319  rc = msdos_format( RAMDISK_PATH, &rqdata );
320  rtems_test_assert( rc == 0 );
321
322  rtems_resource_snapshot_take( &before_mount );
323
324  mount_device( start_dir, NULL );
325}
326
327static void mount_device_with_iconv(
328  const char                *start_dir,
329  rtems_dosfs_mount_options *mount_opts
330)
331{
332  int                       rc;
333
334  rc = msdos_format( RAMDISK_PATH, &rqdata );
335  rtems_test_assert( rc == 0 );
336
337  rtems_resource_snapshot_take( &before_mount );
338
339  mount_opts->converter = rtems_dosfs_create_utf8_converter( "CP850" );
340  rtems_test_assert( mount_opts->converter != NULL );
341
342  mount_device( start_dir, mount_opts );
343}
344
345static void unmount_and_close_device( void )
346{
347  int                     rc;
348  rtems_resource_snapshot now;
349  bool                    are_resources_freed;
350
351
352  delete_folder_tree( MOUNT_DIR );
353
354  rc = unmount( MOUNT_DIR );
355  rtems_test_assert( rc == 0 );
356
357  are_resources_freed = rtems_resource_snapshot_check( &before_mount );
358
359  if ( !are_resources_freed )
360    rtems_resource_snapshot_take( &now );
361
362  rtems_test_assert( are_resources_freed );
363}
364
365/*
366 * Simply create a few directories. These tests should all succeed
367 */
368static void test_creating_directories(
369  const char        *start_dir,
370  const char        *directories,
371  const unsigned int number_of_directories )
372{
373  unsigned int   index;
374  int            rc;
375  char           dirname[MAX_NAME_LENGTH + strlen( start_dir ) + 1];
376  DIR           *dirp;
377  struct dirent *dp;
378
379
380  for ( index = 0; index < number_of_directories; ++index ) {
381    snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir, directories
382              + ( index * MAX_NAME_LENGTH ) );
383    rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
384    rtems_test_assert( rc == 0 );
385  }
386
387  dirp = opendir( start_dir );
388  rtems_test_assert( NULL != dirp );
389
390  index = 0;
391  dp    = readdir( dirp );
392  rtems_test_assert( dp != NULL );
393  rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
394
395  dp = readdir( dirp );
396  rtems_test_assert( dp != NULL );
397  rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
398
399  dp = readdir( dirp );
400  rtems_test_assert( dp != NULL );
401
402  while ( dp != NULL ) {
403    rtems_test_assert( 0
404                       == strcmp( directories + ( index * MAX_NAME_LENGTH ),
405                                  dp->d_name ) );
406    ++index;
407    dp = readdir( dirp );
408  }
409
410  rtems_test_assert( number_of_directories == index );
411
412  rc = closedir( dirp );
413  rtems_test_assert( rc == 0 );
414}
415
416/*
417 * Try creating directories with invalid names.
418 */
419static void test_creating_invalid_directories( void )
420{
421  unsigned int index;
422  int          rc;
423  char         dirname[MAX_NAME_LENGTH_INVALID + MOUNT_DIR_SIZE + 1];
424
425
426  for ( index = 0; index < NUMBER_OF_DIRECTORIES_INVALID; ++index ) {
427    snprintf( dirname,
428              sizeof( dirname ),
429              "%s/%s",
430              MOUNT_DIR,
431              DIRECTORY_NAMES_INVALID[index] );
432    rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
433    rtems_test_assert( rc == -1 );
434  }
435}
436
437/*
438 * Try creating directories which do already exist
439 * (although names may have different capitalization/encoding)
440 */
441static void test_creating_duplicate_directories(
442  const char            *start_dir,
443  const name_duplicates *duplicates,
444  const unsigned int     number_of_duplicates )
445{
446  unsigned int index_dir;
447  unsigned int index_duplicate;
448  int          rc;
449  char         dirname[MAX_NAME_LENGTH + MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
450
451
452  for ( index_dir = 0; index_dir < number_of_duplicates; ++index_dir ) {
453    snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
454              duplicates[index_dir].name );
455    rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
456    rtems_test_assert( rc == 0 );
457
458    for ( index_duplicate = 0;
459          index_duplicate < duplicates[index_dir].number_of_duplicates;
460          ++index_duplicate ) {
461      snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
462                duplicates[index_dir].name_duplicates[index_duplicate] );
463      errno = 0;
464      rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
465      rtems_test_assert( rc == -1 );
466      rtems_test_assert( errno == EEXIST );
467    }
468  }
469}
470
471/*
472 * Try creating and opening files with valid names
473 */
474static void test_handling_files(
475  const char        *dirname,
476  const char        *file_names,
477  const unsigned int number_of_files )
478{
479  unsigned int index;
480  int          rc;
481  char         filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE + START_DIR_SIZE
482                        + 4];
483  int          fd;
484
485
486  for ( index = 0; index < number_of_files; ++index ) {
487    snprintf(
488      filename,
489      sizeof( filename ) - 1,
490      "%s/%s",
491      dirname,
492      file_names + index * MAX_NAME_LENGTH );
493    fd = open( filename,
494               O_RDWR | O_CREAT,
495               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
496    rtems_test_assert( fd >= 0 );
497
498    rc = close( fd );
499    rtems_test_assert( rc == 0 );
500
501    /* See if the file still exists and can be found */
502    fd = open( filename, O_RDWR );
503    rtems_test_assert( fd >= 0 );
504
505    rc = close( fd );
506    rtems_test_assert( rc == 0 );
507  }
508}
509
510/*
511 * Try to find (and open) all of the file names from an
512 * array in a given directory
513 */
514static void test_finding_files(
515  const char        *dirname,
516  const char        *file_names,
517  const unsigned int number_of_files )
518{
519  int            rc;
520  DIR           *dir_stream;
521  struct dirent *dp;
522  int            fd;
523  unsigned int   index_file;
524  char           filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE
525                          + START_DIR_SIZE + 4];
526
527
528  dir_stream = opendir( dirname );
529  rtems_test_assert( dir_stream != NULL );
530
531  dp = readdir( dir_stream );
532  rtems_test_assert( dp != NULL );
533  rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
534
535  dp = readdir( dir_stream );
536  rtems_test_assert( dp != NULL );
537  rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
538
539  dp         = readdir( dir_stream );
540  rtems_test_assert( dp != NULL );
541  index_file = 0;
542
543  while ( dp != NULL ) {
544    rtems_test_assert( 0 == strcmp(
545                         file_names + index_file * MAX_NAME_LENGTH,
546                         dp->d_name ) );
547
548    snprintf(
549      filename,
550      sizeof( filename ) - 1,
551      "%s/%s",
552      dirname,
553      file_names + index_file * MAX_NAME_LENGTH );
554
555    /* See if the file still exists and can be found */
556    fd = open( filename, O_RDWR );
557    rtems_test_assert( fd >= 0 );
558
559    rc = close( fd );
560    rtems_test_assert( rc == 0 );
561
562    ++index_file;
563    dp = readdir( dir_stream );
564  }
565
566  rtems_test_assert( number_of_files == index_file );
567
568  rc = closedir( dir_stream );
569  rtems_test_assert( rc == 0 );
570}
571
572/*
573 * Try opening files which do already exist (with different capitalization in their names)
574 */
575static void test_duplicated_files( const char *dirname,
576  const name_duplicates                       *files_duplicated,
577  const unsigned int                           number_of_files_duplicated )
578{
579  unsigned int index_file;
580  unsigned int index_duplicate;
581  int          rc;
582  char         filename[MAX_NAME_LENGTH + strlen( dirname ) + 1];
583  int          fd;
584
585
586  for ( index_file = 0; index_file < number_of_files_duplicated;
587        ++index_file ) {
588    snprintf( filename,
589              sizeof( filename ) - 1,
590              "%s/%s",
591              dirname,
592              files_duplicated[index_file].name );
593    fd = open( filename,
594               O_RDWR | O_CREAT,
595               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
596    rtems_test_assert( fd >= 0 );
597
598    rc = close( fd );
599    rtems_test_assert( rc == 0 );
600
601    for ( index_duplicate = 0;
602          index_duplicate < files_duplicated[index_file].number_of_duplicates;
603          ++index_duplicate ) {
604      snprintf( filename,
605                sizeof( filename ) - 1,
606                "%s/%s",
607                dirname,
608                files_duplicated[index_file].name_duplicates[index_duplicate] );
609      fd = open( filename, O_RDWR );
610      rtems_test_assert( fd >= 0 );
611
612      rc = close( fd );
613      rtems_test_assert( rc == 0 );
614
615      errno = 0;
616      fd = open( filename, O_RDWR | O_CREAT | O_EXCL );
617      rtems_test_assert( fd == -1 );
618      rtems_test_assert( errno == EEXIST );
619    }
620
621    rc = remove( filename );
622    rtems_test_assert( rc == 0 );
623  }
624}
625
626/*
627 * Open and read existing valid directories
628 */
629static void test_handling_directories(
630  const char        *start_dir,
631  const char        *directory_names,
632  const unsigned int number_of_directories,
633  const char        *file_names,
634  const unsigned int number_of_files )
635{
636  unsigned int   index_directory;
637  unsigned int   index_file;
638  int            rc;
639  DIR           *dir_stream;
640  char           dirname[MAX_NAME_LENGTH * 2];
641  struct dirent *dp;
642
643
644  for ( index_directory = 0;
645        index_directory < number_of_directories;
646        ++index_directory ) {
647    snprintf(
648      dirname,
649      sizeof( dirname ) - 1,
650      "%s/%s",
651      start_dir,
652      directory_names + index_directory * MAX_NAME_LENGTH );
653
654    test_handling_files(
655      dirname,
656      file_names,
657      number_of_files );
658
659    dir_stream = opendir( dirname );
660    rtems_test_assert( dir_stream != NULL );
661
662    dp = readdir( dir_stream );
663    rtems_test_assert( dp != NULL );
664    rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
665
666    dp = readdir( dir_stream );
667    rtems_test_assert( dp != NULL );
668    rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
669
670    dp         = readdir( dir_stream );
671    rtems_test_assert( dp != NULL );
672    index_file = 0;
673
674    while ( dp != NULL ) {
675      rtems_test_assert( 0 == strcmp(
676                           file_names + index_file * MAX_NAME_LENGTH,
677                           dp->d_name ) );
678      ++index_file;
679      dp = readdir( dir_stream );
680    }
681
682    rtems_test_assert( number_of_files == index_file );
683
684    rc = closedir( dir_stream );
685    rtems_test_assert( rc == 0 );
686  }
687}
688
689/*
690 * Try to find all sub-directories from an array
691 * in a given start directory.
692 * In addition try to find and open files
693 * in these sub-directories.
694 */
695static void test_finding_directories(
696  const char        *start_dir,
697  const char        *directory_names,
698  const unsigned int number_of_directories,
699  const char        *file_names,
700  const unsigned int number_of_files )
701{
702  unsigned int   index_directory;
703  int            rc;
704  DIR           *dir_stream;
705  struct dirent *dp;
706  char           dirname[MAX_NAME_LENGTH * 2];
707
708
709  dir_stream = opendir( start_dir );
710  rtems_test_assert( dir_stream != NULL );
711
712  dp = readdir( dir_stream );
713  rtems_test_assert( dp != NULL );
714  rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
715
716  dp = readdir( dir_stream );
717  rtems_test_assert( dp != NULL );
718  rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
719
720  dp              = readdir( dir_stream );
721  rtems_test_assert( dp != NULL );
722  index_directory = 0;
723
724  while ( dp != NULL ) {
725    rtems_test_assert( 0 == strcmp(
726                         directory_names + index_directory * MAX_NAME_LENGTH,
727                         dp->d_name ) );
728
729    snprintf(
730      dirname,
731      sizeof( dirname ) - 1,
732      "%s/%s",
733      start_dir,
734      directory_names + index_directory * MAX_NAME_LENGTH );
735
736    test_finding_files(
737      dirname,
738      file_names,
739      number_of_files );
740
741    ++index_directory;
742    dp = readdir( dir_stream );
743  }
744
745  rtems_test_assert( number_of_directories == index_directory );
746
747  rc = closedir( dir_stream );
748  rtems_test_assert( rc == 0 );
749}
750
751#if (PRINT_DISK_IMAGE != 0)
752static void print_image(
753  const char* include_guard,
754  const char* image_name
755)
756{
757  #define                   BYTES_PER_ROW     8
758  int                       rc;
759  int                       fd;
760  ssize_t                   bytes_read;
761  uint8_t                   buf[BLOCK_SIZE];
762  unsigned int              index_block;
763  unsigned int              index_row;
764  unsigned int              index_column;
765  unsigned int              index_buf;
766#ifdef SHOW_LINE_NUMBERS
767  size_t                    index_row_start = 1;
768#endif /* SWOW_LINE_NUMBERS */
769  size_t                    bytes_written   = 0;
770  const size_t              DISK_SIZE       = BLOCK_SIZE * BLOCK_NUM;
771  const unsigned int        ROWS_PER_BLOCK  = BLOCK_SIZE / BYTES_PER_ROW;
772
773  printf ("/*\n"
774          " *  Declarations for C structure representing a disk image\n"
775          " *\n"
776          " *  WARNING: Automatically generated by init.c -- do not edit!\n"
777          " */\n"
778          "#ifndef %s\n"
779          "#define %s\n"
780          "\n"
781          "#include <sys/types.h>\n"
782          "\n"
783          "#ifdef __cplusplus\n"
784          "extern \"C\" {\n"
785          "#endif /* __cplusplus */\n"
786          "\n"
787          "static unsigned char %s[] = {\n",
788          include_guard,
789          include_guard,
790          image_name);
791  fd = open( RAMDISK_PATH, O_RDWR );
792  rtems_test_assert( fd >= 0 );
793
794  for ( index_block = 0; index_block < BLOCK_NUM; ++index_block )
795  {
796    bytes_read = read( fd, &buf[0], BLOCK_SIZE );
797    rtems_test_assert( bytes_read = BLOCK_SIZE );
798
799    index_buf = 0;
800
801    for ( index_row = 0; index_row < ROWS_PER_BLOCK; ++index_row )
802    {
803      printf( "  " );
804      for ( index_column = 0;
805            index_column < BYTES_PER_ROW;
806            ++index_column ) {
807        printf("0x%02x", buf[index_buf]);
808        ++bytes_written;
809        ++index_buf;
810        if ( bytes_written < DISK_SIZE ) {
811          printf (", ");
812        } else {
813          printf ("  ");
814        }
815      }
816#ifdef SHOW_LINE_NUMBERS
817      printf( "/* %6u - %6u */", index_row_start, bytes_written );
818      index_row_start = bytes_written + 1;
819#endif /* SWOW_LINE_NUMBERS */
820      printf( "\n" );
821    }
822  }
823
824  rc = close( fd );
825  rtems_test_assert( rc == 0 );
826
827  printf ("};\n"
828          "#ifdef __cplusplus\n"
829          "}\n"
830          "#endif /* __cplusplus */\n"
831          "\n"
832          "#endif /* %s */\n",
833          include_guard);
834}
835#else /* PRINT_DISK_IMAGE */
836static void print_image(
837  const char* include_guard,
838  const char* image_name
839)
840{
841  /* Nothing to be done */
842}
843#endif /* PRINT_DISK_IMAGE */
844
845
846static void compare_files(
847  const char *file0,
848  const char *file1
849)
850{
851  struct stat  stat_buf[2];
852  int          fd[2];
853  unsigned int index;
854  uint8_t      buf[2];
855  ssize_t      bytes_read;
856  int          rc;
857
858  rc = stat( file0 , &stat_buf[0] );
859  rtems_test_assert( rc == 0 );
860  rc = stat( file1 , &stat_buf[1] );
861  rtems_test_assert( rc == 0 );
862
863  rtems_test_assert( stat_buf[0].st_size == stat_buf[1].st_size );
864
865  fd[0] = open( file0, O_RDONLY );
866  rtems_test_assert( fd[0] > 0 );
867  fd[1] = open( file1, O_RDONLY );
868  rtems_test_assert( fd[1] > 0 );
869
870  for ( index = 0; index < stat_buf[0].st_size; ++index ) {
871    bytes_read = read( fd[0], &buf[0], 1 );
872    rtems_test_assert( bytes_read == 1 );
873    bytes_read = read( fd[1], &buf[1], 1 );
874    rtems_test_assert( bytes_read == 1 );
875    rtems_test_assert( buf[0] == buf[1] );
876  }
877  rc = close( fd[0] );
878  rtems_test_assert( rc == 0 );
879  rc = close( fd[1] );
880  rtems_test_assert( rc == 0 );
881}
882
883static void compare_directories(
884  const char *dir0,
885  const char *dir1)
886{
887  int                       rc;
888  DIR                      *dir_stream[2];
889  struct dirent            *dp;
890  struct stat               stat_buf[2];
891  char                     *path[2];
892  const unsigned int        PATH_LENGTH = 1024;
893
894  path[0] = calloc( PATH_LENGTH, sizeof(char) );
895  rtems_test_assert( path[0] != NULL );
896  path[1] = calloc( PATH_LENGTH, sizeof(char) );
897  rtems_test_assert( path[1] != NULL );
898
899  dir_stream[0] = opendir( dir0 );
900  rtems_test_assert( dir_stream[0] != NULL );
901
902  dir_stream[1] = opendir( dir1 );
903  rtems_test_assert( dir_stream[1] != NULL );
904
905  dp = readdir( dir_stream[0] );
906  rtems_test_assert( dp != NULL );
907
908  while ( dp != NULL ) {
909    rc = snprintf(path[0], PATH_LENGTH, "%s/%s", dir0, dp->d_name);
910    rtems_test_assert( rc < PATH_LENGTH );
911    rtems_test_assert( rc >= 0 );
912    rc = snprintf(path[1], PATH_LENGTH, "%s/%s", dir1, dp->d_name);
913    rtems_test_assert( rc < PATH_LENGTH );
914    rtems_test_assert( rc >= 0 );
915
916    rc = stat( path[0] , &stat_buf[0] );
917    rtems_test_assert( rc == 0 );
918
919    if (   ( strcmp( dp->d_name, "."  ) != 0)
920        && ( strcmp( dp->d_name, ".." ) != 0) ) {
921      if ( S_ISDIR( stat_buf[0].st_mode ) ) {
922        compare_directories( path[0], path[1] );
923      } else {
924        compare_files( path[0], path[1] );
925      }
926    }
927
928    dp = readdir( dir_stream[0] );
929
930  }
931  rc = closedir( dir_stream[0] );
932  rtems_test_assert( rc == 0 );
933
934  rc = closedir( dir_stream[1] );
935  rtems_test_assert( rc == 0 );
936
937  free (path[0]);
938  free (path[1]);
939}
940
941static void compare_image(
942  const char                      *mount_dir,
943  const char                      *dev,
944  const rtems_dosfs_mount_options *mount_opts )
945{
946  #define MOUNT_DIR2 "/mnt2"
947  int                       rc;
948
949  rc = mount_and_make_target_path(
950    dev,
951    MOUNT_DIR2,
952    RTEMS_FILESYSTEM_TYPE_DOSFS,
953    RTEMS_FILESYSTEM_READ_WRITE,
954    mount_opts );
955  rtems_test_assert( rc == 0 );
956
957  compare_directories(mount_dir, MOUNT_DIR2);
958
959  rc = unmount( MOUNT_DIR2 );
960  rtems_test_assert( rc == 0 );
961
962  rc = rmdir( MOUNT_DIR2 );
963  rtems_test_assert( rc == 0 );
964
965}
966/*
967 * Test the compatibility with a genuine MS Windows FAT file system.
968 */
969static void test_compatibility( void )
970{
971  int                       rc;
972  rtems_status_code         sc;
973  dev_t                     dev;
974  char                      diskpath[] = "/dev/ramdisk1";
975  rtems_dosfs_mount_options mount_opts;
976  rtems_device_major_number major;
977  FILE                     *fp;
978  int                       buffer;
979  unsigned int              index_file = 0;
980  unsigned int              index_char;
981  unsigned int              offset;
982  char                      content_buf[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
983                                        + 1];
984  char                      file_path[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
985                                      + 1];
986  DIR                      *dir_stream;
987  struct dirent            *dp;
988
989
990  mount_opts.converter = rtems_dosfs_create_utf8_converter( "CP850" );
991  rtems_test_assert( mount_opts.converter != NULL );
992
993  sc = rtems_io_register_driver( 0, &ramdisk_ops, &major );
994  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
995
996  dev = rtems_filesystem_make_dev_t( major, 1 );
997
998  sc  = rtems_disk_create_phys(
999    dev,
1000    BLOCK_SIZE,
1001    BLOCK_COUNT,
1002    ramdisk_ioctl,
1003    &disk_image,
1004    diskpath );
1005  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
1006
1007  rc = mount_and_make_target_path(
1008    diskpath,
1009    MOUNT_DIR,
1010    RTEMS_FILESYSTEM_TYPE_DOSFS,
1011    RTEMS_FILESYSTEM_READ_WRITE,
1012    &mount_opts );
1013  rtems_test_assert( rc == 0 );
1014
1015  dir_stream = opendir( MOUNT_DIR );
1016  rtems_test_assert( dir_stream != NULL );
1017
1018  dp = readdir( dir_stream );
1019  rtems_test_assert( dp != NULL );
1020
1021  while ( dp != NULL ) {
1022    index_char = 0;
1023
1024    size_t len = strlen( filenames[index_file] );
1025
1026    if ( filenames[index_file][len - 1] == '.' )
1027      rtems_test_assert( ( len - 1 ) == dp->d_namlen );
1028    else
1029      rtems_test_assert( len == dp->d_namlen );
1030
1031    rtems_test_assert( 0
1032                       == memcmp( &filenames[index_file][0], &dp->d_name[0],
1033                                  dp->d_namlen ) );
1034
1035    snprintf( file_path, sizeof( file_path ), "%s/%s", MOUNT_DIR,
1036              filenames[index_file] );
1037    fp = fopen( file_path, "r" );
1038    rtems_test_assert( fp != NULL );
1039
1040    /* These files should contain their own file names. */
1041    while ( ( buffer = fgetc( fp ) ) != EOF ) {
1042      content_buf[index_char] = buffer;
1043      ++index_char;
1044    }
1045
1046    if ( 0 == strncmp( content_buf, UTF8_BOM, UTF8_BOM_SIZE ) )
1047      offset = UTF8_BOM_SIZE;
1048    else
1049      offset = 0;
1050
1051    rtems_test_assert( 0
1052                       == memcmp( filenames[index_file],
1053                                  &content_buf[offset],
1054                                  index_char - offset ) );
1055
1056    rc = fclose( fp );
1057    rtems_test_assert( rc == 0 );
1058
1059    ++index_file;
1060    dp = readdir( dir_stream );
1061  }
1062
1063  rtems_test_assert( index_file == FILES_FILENAMES_NUMBER_OF );
1064
1065  rc = closedir( dir_stream );
1066  rtems_test_assert( rc == 0 );
1067
1068  rc = unmount( MOUNT_DIR );
1069  rtems_test_assert( rc == 0 );
1070}
1071
1072/*
1073 * Main test method
1074 */
1075static void test( void )
1076{
1077  int  rc;
1078  char start_dir[MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
1079  rtems_dosfs_mount_options mount_opts[2];
1080
1081  rc = mkdir( MOUNT_DIR, S_IRWXU | S_IRWXG | S_IRWXO );
1082  rtems_test_assert( rc == 0 );
1083
1084  snprintf( start_dir, sizeof( start_dir ), "%s/%s", MOUNT_DIR, "strt" );
1085
1086  /*
1087   * Tests with code page 850 compatible directory and file names
1088   * and the code page 850 backwards compatible default mode mode of the
1089   * FAT file system
1090   */
1091  mount_device_with_defaults( start_dir );
1092
1093  test_creating_duplicate_directories(
1094    &start_dir[0],
1095    &DIRECTORY_DUPLICATES[0],
1096    NUMBER_OF_DIRECTORIES_DUPLICATED );
1097
1098  unmount_and_close_device();
1099
1100  mount_device_with_defaults( start_dir );
1101
1102  test_duplicated_files(
1103    MOUNT_DIR,
1104    FILES_DUPLICATES,
1105    NUMBER_OF_FILES_DUPLICATED );
1106
1107  unmount_and_close_device();
1108
1109  mount_device_with_defaults( start_dir );
1110
1111  test_creating_invalid_directories();
1112
1113  test_creating_directories(
1114    &start_dir[0],
1115    &DIRECTORY_NAMES[0][0],
1116    NUMBER_OF_DIRECTORIES );
1117
1118  test_handling_directories(
1119    &start_dir[0],
1120    &DIRECTORY_NAMES[0][0],
1121    NUMBER_OF_DIRECTORIES,
1122    &FILE_NAMES[0][0],
1123    NUMBER_OF_FILES );
1124
1125  compare_image(
1126    MOUNT_DIR,
1127    "/dev/rdb",
1128    NULL);
1129
1130  rc = unmount( MOUNT_DIR );
1131  rtems_test_assert( rc == 0 );
1132
1133  /*
1134   * Again tests with code page 850 compatible directory and file names
1135   * but with multibyte string compatible conversion methods which use
1136   * iconv and utf8proc
1137   */
1138  mount_opts[0].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1139  rtems_test_assert( mount_opts[0].converter != NULL );
1140
1141  rc                     = mount(
1142    RAMDISK_PATH,
1143    MOUNT_DIR,
1144    "dosfs",
1145    RTEMS_FILESYSTEM_READ_WRITE,
1146    &mount_opts );
1147  rtems_test_assert( rc == 0 );
1148
1149  test_finding_directories(
1150    &start_dir[0],
1151    &DIRECTORY_NAMES[0][0],
1152    NUMBER_OF_DIRECTORIES,
1153    &FILE_NAMES[0][0],
1154    NUMBER_OF_FILES );
1155  unmount_and_close_device();
1156
1157  mount_device_with_iconv( start_dir, &mount_opts[0] );
1158  test_creating_invalid_directories();
1159
1160  test_creating_duplicate_directories(
1161    &start_dir[0],
1162    &DIRECTORY_DUPLICATES[0],
1163    NUMBER_OF_DIRECTORIES_DUPLICATED );
1164
1165  unmount_and_close_device();
1166
1167  mount_device_with_iconv( start_dir, &mount_opts[0] );
1168
1169  test_duplicated_files(
1170    MOUNT_DIR,
1171    FILES_DUPLICATES,
1172    NUMBER_OF_FILES_DUPLICATED );
1173
1174  unmount_and_close_device();
1175
1176  mount_device_with_iconv( start_dir, &mount_opts[0] );
1177
1178  test_creating_directories(
1179    &start_dir[0],
1180    &DIRECTORY_NAMES[0][0],
1181    NUMBER_OF_DIRECTORIES );
1182
1183  test_handling_directories(
1184    &start_dir[0],
1185    &DIRECTORY_NAMES[0][0],
1186    NUMBER_OF_DIRECTORIES,
1187    &FILE_NAMES[0][0],
1188    NUMBER_OF_FILES );
1189
1190  mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1191  rtems_test_assert( mount_opts[1].converter != NULL );
1192
1193  compare_image(
1194    MOUNT_DIR,
1195    "/dev/rdb",
1196    &mount_opts[1]);
1197
1198  rc = unmount( MOUNT_DIR );
1199  rtems_test_assert( rc == 0 );
1200
1201  print_image(
1202      "IMAGE_BIN_LE_SINGLEBYTE_H_",
1203      "IMAGE_BIN_LE_SINGLEBYTE");
1204
1205  rc = mount(
1206    RAMDISK_PATH,
1207    MOUNT_DIR,
1208    "dosfs",
1209    RTEMS_FILESYSTEM_READ_WRITE,
1210    NULL );
1211  rtems_test_assert( rc == 0 );
1212
1213  unmount_and_close_device();
1214
1215
1216  /*
1217   * Tests with multibyte directory and file names and
1218   * with multibyte string compatible conversion methods which use
1219   * iconv and utf8proc
1220   */
1221  mount_device_with_iconv( start_dir, &mount_opts[0] );
1222
1223  test_creating_duplicate_directories(
1224    &start_dir[0],
1225    &MULTIBYTE_DUPLICATES[0],
1226    NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
1227
1228  unmount_and_close_device();
1229
1230  mount_device_with_iconv( start_dir, &mount_opts[0] );
1231
1232  test_duplicated_files(
1233    MOUNT_DIR,
1234    &MULTIBYTE_DUPLICATES[0],
1235    NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
1236
1237  unmount_and_close_device();
1238
1239  mount_device_with_iconv( start_dir, &mount_opts[0] );
1240
1241  test_creating_directories(
1242    &start_dir[0],
1243    &NAMES_MULTIBYTE[0][0],
1244    NUMBER_OF_NAMES_MULTIBYTE );
1245
1246  test_handling_directories(
1247    &start_dir[0],
1248    &NAMES_MULTIBYTE[0][0],
1249    NUMBER_OF_NAMES_MULTIBYTE,
1250    &NAMES_MULTIBYTE[0][0],
1251    NUMBER_OF_NAMES_MULTIBYTE );
1252
1253  mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1254  rtems_test_assert( mount_opts[1].converter != NULL );
1255
1256  compare_image(
1257    MOUNT_DIR,
1258    "/dev/rdc",
1259    &mount_opts[1]);
1260
1261  rc = unmount( MOUNT_DIR );
1262  rtems_test_assert( rc == 0 );
1263
1264  print_image(
1265    "IMAGE_BIN_LE_MULTIBYTE_H_",
1266    "IMAGE_BIN_LE_MULTIBYTE");
1267
1268  rc = mount(
1269    RAMDISK_PATH,
1270    MOUNT_DIR,
1271    "dosfs",
1272    RTEMS_FILESYSTEM_READ_WRITE,
1273    NULL );
1274  rtems_test_assert( rc == 0 );
1275
1276  test_finding_directories(
1277    &start_dir[0],
1278    &NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
1279    NUMBER_OF_NAMES_MULTIBYTE,
1280    &NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
1281    NUMBER_OF_NAMES_MULTIBYTE );
1282
1283  unmount_and_close_device();
1284
1285  test_compatibility();
1286}
1287
1288static void Init( rtems_task_argument arg )
1289{
1290  puts( "\n\n*** TEST fsdosfsname01 ***" );
1291
1292  test();
1293
1294  puts( "*** END OF TEST fsdosfsname01 ***" );
1295
1296  rtems_test_exit( 0 );
1297}
1298
1299rtems_ramdisk_config rtems_ramdisk_configuration [] = {
1300  { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM },
1301  { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_SINGLEBYTE[0] },
1302  { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_MULTIBYTE[0] }
1303};
1304
1305size_t rtems_ramdisk_configuration_size = RTEMS_ARRAY_SIZE(rtems_ramdisk_configuration);
1306
1307#define CONFIGURE_INIT_TASK_STACK_SIZE ( 1024 * 64 )
1308#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
1309#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
1310#define CONFIGURE_MAXIMUM_DRIVERS 4
1311#define CONFIGURE_MAXIMUM_SEMAPHORES (2 * RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE)
1312#define CONFIGURE_APPLICATION_EXTRA_DRIVERS RAMDISK_DRIVER_TABLE_ENTRY
1313
1314#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
1315
1316#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
1317
1318#define CONFIGURE_FILESYSTEM_DOSFS
1319
1320/* 2 RAM disk device files + 2 mount_dir + stdin + stdout + stderr +
1321 * 2 for open directories/files  + 4 * 2 for recursive tree compares*/
1322#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS ( 7 + 2 + ( 4 * 2 ) )
1323
1324#define CONFIGURE_MAXIMUM_TASKS 1
1325
1326#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1327
1328#define CONFIGURE_INIT
1329
1330#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.