source: rtems/testsuites/fstests/fsdosfsname01/init.c @ 98c6d50

5
Last change on this file since 98c6d50 was 98c6d50, checked in by Chris Johns <chrisj@…>, on 10/19/17 at 05:39:16

testsuite: Use printk for all test output where possible.

  • Remove the printf support leaving the direct printk support configured with TESTS_USE_PRINTK and all other output goes via a buffered vsniprintf call to printk.
  • Control the test's single init for functions and global data with TEST_INIT and not CONFIGURE_INIT. They are now separate.

Updates #3170.

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