source: rtems/testsuites/fstests/fsdosfsname01/init.c @ 581c9982

4.11
Last change on this file since 581c9982 was 581c9982, checked in by Ralf Kirchner <ralf.kirchner@…>, on Mar 22, 2013 at 2:14:11 PM

fsdsosfsname01: Ensure endian correctness

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