source: rtems/testsuites/fstests/fsdosfsname01/init.c @ ca835e56

Last change on this file since ca835e56 was ca835e56, checked in by Christian Mauderer <Christian.Mauderer@…>, on Nov 28, 2017 at 3:42:00 PM

dosfs: Fix files with same name as volume name.

Take care that a file in the root directory with the same name as the
volume name can be found.

Update #3257.

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