source: rtems/testsuites/psxtests/psxreaddir/test.c @ b4043ea

5
Last change on this file since b4043ea was 698c2e50, checked in by Sebastian Huber <sebastian.huber@…>, on 03/25/14 at 07:06:16

tests/psxtests: Use <rtems/test.h>

  • Property mode set to 100644
File size: 12.5 KB
Line 
1/**
2 *  @file
3 *
4 *  This is a native test to explore how the readdir() family works.
5 *  Newlib supports the following readdir() family members:
6 *
7 *    closedir()   -
8 *    readdir()    -
9 *    scandir()    -
10 *    opendir()    -
11 *    rewinddir()  -
12 *    telldir()    - BSD not in POSIX
13 *    seekdir()    - BSD not in POSIX
14 *
15 *
16 *  seekdir() takes an offset which is a byte offset.  The Linux
17 *  implementation of this appears to seek to the ((off/DIRENT_SIZE) + 1)
18 *  record where DIRENT_SIZE seems to be 12 bytes.
19 */
20
21/*
22 *  COPYRIGHT (c) 1989-2012.
23 *  On-Line Applications Research Corporation (OAR).
24 *
25 *  The license and distribution terms for this file may be
26 *  found in the file LICENSE in this distribution or at
27 *  http://www.rtems.org/license/LICENSE.
28 */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <stdio.h>
35#include <sys/types.h>
36#include <fcntl.h>
37#include <dirent.h>
38#include <string.h>
39#include <unistd.h>
40#include <errno.h>
41#include <rtems/imfs.h>
42
43const char rtems_test_name[] = "PSXREADDIR";
44
45/* forward declarations to avoid warnings */
46int test_main(void);
47void printdir(DIR *directory);
48void complete_printdir(char *path);
49int select1(const struct dirent *entry);
50int select2(const struct dirent *entry);
51int compare_ascending(const struct dirent **a, const struct dirent **b);
52int compare_descending( const struct dirent **a, const struct dirent **b);
53void test_across_mount(void);
54void test_across_mount(void);
55
56DIR *directory;
57DIR *directory2;
58DIR *directory3;
59DIR *directory_not;
60
61/*
62int scandir ( const char *dirname,
63   struct dirent *** namelist,
64   int (*select) __P((struct dirent *)),
65   int (*dcomp) __P((const struct dirent **, const struct dirent **))
66);
67*/
68
69#if defined(__rtems__)
70#define d_type d_reclen
71#include <pmacros.h>
72#endif
73
74void printdir( DIR *directory )
75{
76  struct dirent *d;
77
78  printf( "%-20s %8s %8s %8s %4s\n",
79     "name", "    inode", " offset", "reclen", " type" );
80  d = readdir(directory);
81
82  while (d) {
83    printf( "%-20s %8ld %8" PRIdoff_t " %6d   0x%04x\n",
84       d->d_name, d->d_ino, d->d_off, d->d_reclen, d->d_type );
85    d = readdir(directory);
86
87  }
88}
89
90void complete_printdir( char *path )
91{
92  DIR *the_dir;
93  int status;
94
95  the_dir = opendir( path );
96  rtems_test_assert( the_dir );
97
98  printdir( the_dir );
99  status = closedir( the_dir );
100  rtems_test_assert( !status );
101}
102
103char *many_files[] = {
104        "a",
105        "b",
106        "c",
107        "d",
108        "e",
109        "f",
110        "g",
111        "h",
112        "i",
113        "j",
114        "k",
115        "l",
116        "m",
117        "n",
118        "o",
119        "p",
120        "q",
121        "r",
122        "s",
123        "t",
124        "u",
125        "v",
126        "w",
127        "x",
128        "y",
129        "z",
130        "aa",
131        "ab",
132        "ac",
133        "ad",
134        "ae",
135        "af",
136        "ag",
137        "ah",
138        "ai",
139        "aj",
140        "ak",
141        "al",
142        "am",
143        "an",
144        "ao",
145        "ap",
146        "aq",
147        "ar"
148};
149
150char *dnames[] = {
151        "a",
152        "b",
153        "c",
154        "d",
155        "e",
156        "f",
157        "c/y",
158        "c/z",
159        "c/x",
160        "c/y/a3333",
161        "c/y/j123",
162        "END"
163};
164
165int select1 ( const struct dirent *entry )
166{
167   printf("SCANDIR SELECT1 accepts  nodename: %s\n", entry->d_name );
168   return 1;
169}
170
171int select2 ( const struct dirent *entry )
172{
173   if( strcmp( entry->d_name, "y") == 0 ) {
174      printf("SCANDIR SELECT accepted nodename: %s\n", entry->d_name );
175      return 1;
176   }
177   printf("SCANDIR SELECT rejected nodename: %s\n", entry->d_name );
178   return 0;
179}
180
181int compare_ascending(const struct dirent **a, const struct dirent **b )
182{
183   int i;
184
185   i = strcmp (
186      (char *)((struct dirent *)(*a)->d_name),
187      (char *)((struct dirent *)(*b)->d_name)
188   );
189   return i;
190}
191
192int compare_descending( const struct dirent **a, const struct dirent **b )
193{
194   int i;
195
196   i = strcmp (
197      (char *)((const struct dirent *)(*b)->d_name),
198      (char *)((const struct dirent *)(*a)->d_name)
199   );
200
201   return i;
202}
203
204void test_across_mount(void)
205{
206  int status;
207
208  /*
209   * Verify Readdir works correctly over mount points.
210   */
211
212  printf("Validate readdir across mount point\n");
213  rtems_test_assert( mkdir( "/imfs", 0777 ) == 0 );
214  rtems_test_assert( mkdir( "/imfs/should_be_hidden", 0777 ) == 0 );
215  complete_printdir("/imfs" );
216  printf("Attempting to mount IMFS file system at /imfs \n");
217  status = mount(
218    "null",
219    "/imfs",
220    "imfs",
221     RTEMS_FILESYSTEM_READ_WRITE,
222     NULL );
223  rtems_test_assert( status == 0 );
224  printf( "create /imfs/testdir and /imfs/testdir/testsubdir\n");
225
226  status = mkdir( "/imfs/testdir", 0777 );
227  rtems_test_assert( status == 0 );
228  status = mkdir( "/imfs/testdir/testsubdir", 0777 );
229  rtems_test_assert( status == 0 );
230
231  complete_printdir("/imfs" );
232  complete_printdir("/imfs/" );
233  complete_printdir("/imfs/." );
234  complete_printdir("/imfs/testdir" );
235  complete_printdir("/imfs/testdir/.." );
236}
237
238#if defined(__rtems__)
239int test_main(void)
240#else
241int main(
242  int argc,
243  char **argv
244)
245#endif
246{
247  static const char *my_file = "/b/my_file";
248
249  int fd;
250  int i;
251  int status;
252  off_t off;
253  struct dirent *d_not;
254  struct dirent **namelist;
255  struct stat s;
256
257
258  TEST_BEGIN();
259
260  printf( "\nchdir to the root directory\n" );
261  status = chdir( "/" );
262  printf( "chdir() status : %d\n\n", status );
263
264  printf( "\nCreating a series of directories under /\n" );
265  i=0;
266  while ( strcmp(dnames[i], "END") != 0 )
267  {
268     status = mkdir( dnames[i], 0x1c0 );
269     printf("Creating directory: %s      %d %d   ", dnames[i], status, errno );
270     if ( errno == 0 )
271        printf(" Success\n");
272     else
273        printf(" Failure\n");
274
275     i++;
276  }
277
278  /*
279   * Create files under many and open the directory.
280   */
281
282  printf("Create a lot of files\n");
283  status = mkdir( "/many", 0x1c0 );
284  status = chdir( "/many" );
285  for (i = 0; i<44; i++) {
286    printf("Create %s\n", many_files[i]);
287    fd = open (many_files[i], O_CREAT, S_IRWXU);
288    close (fd);
289  }
290  printf("Open /many and print the directory\n");
291  directory_not = opendir( "/many" );
292  printdir ( directory_not );
293  d_not = readdir( directory_not );
294  rtems_test_assert( d_not == 0 );
295
296  printf("open %s\n", my_file);
297  fd = open (my_file, O_CREAT, S_IRWXU);
298  rtems_test_assert( fd != -1 );
299  close (fd);
300
301  printf("scandir a file status: ");
302  status = scandir(
303     my_file,
304     &namelist,
305     select1,
306     NULL
307  );
308  printf("%d\n", status);
309
310  printf("Open /b/new_file\n");
311  fd  = open( "/b/new_file", O_CREAT, S_IRWXU );
312  rtems_test_assert( fd != -1 );
313
314  printf("fcntl F_SETFD should return 0\n");
315  status = fcntl( fd, F_SETFD, 1 );
316  rtems_test_assert( status == 0 );
317
318  printf("fcntl F_SETFD should return 1\n");
319  status = fcntl( fd, F_GETFD, 1 );
320  rtems_test_assert( status == 1 );
321
322  printf("fcntl F_DUPFD should return a file descriptor\n");
323  status = fcntl( fd, F_DUPFD, 0 );
324  rtems_test_assert ( status >= 0 );
325
326  printf("close duplicate should return 0\n");
327  status = close( status );
328  rtems_test_assert ( status == 0 );
329
330  printf("fcntl F_GETFL returns current flags\n");
331  status = fcntl( fd, F_GETFL, 1 );
332  printf("fcntl F_GETFL returned 0x%x\n", status );
333  rtems_test_assert( status != -1 );
334
335  printf("fcntl F_SETFL to add O_APPEND and O_NONBLOCK\n");
336  status = fcntl( fd, F_SETFL, O_APPEND|O_NONBLOCK );
337  rtems_test_assert ( status != -1 );
338
339  printf("fcntl F_GETFL return current flags to see changes\n");
340  status = fcntl( fd, F_GETFL, 1 );
341  printf("fcntl F_GETFL returned 0x%x\n", status );
342  rtems_test_assert( status != -1 );
343
344  printf("fcntl F_GETLK should return -1\n");
345  status = fcntl( fd, F_GETLK, 1 );
346  rtems_test_assert ( status == -1 );
347
348  printf("fcntl F_SETLK should return -1\n");
349  status = fcntl( fd, F_SETLK, 1 );
350  rtems_test_assert ( status == -1 );
351
352  printf("fcntl F_SETLKW should return -1\n");
353  status = fcntl( fd, F_SETLKW, 1 );
354  rtems_test_assert ( status == -1 );
355
356  printf("fcntl F_SETOWN should return -1\n");
357  status = fcntl( fd, F_SETOWN, 1 );
358  rtems_test_assert ( status == -1 );
359
360  printf("fcntl F_GETOWN should return -1\n");
361  status = fcntl( fd, F_GETOWN, 1 );
362  rtems_test_assert ( status == -1 );
363
364  printf("fcntl invalid argument should return -1\n");
365  status = fcntl( fd, 0xb, 1 );
366  printf("Status %d\n",status);
367  rtems_test_assert( status == -1 );
368
369  printf("close should return 0\n");
370  status = close( fd );
371  rtems_test_assert ( status == 0 );
372
373  printf("opendir, readdir and closedir %s\n", my_file);
374  directory_not = opendir (my_file);
375  rtems_test_assert( directory_not != NULL );
376  d_not = readdir(directory_not);
377  rtems_test_assert( d_not == NULL );
378  status = closedir (directory_not);
379  rtems_test_assert (status == 0);
380
381  printf("opendir, readdir and closedir\n");
382  directory_not = opendir ("/a");
383  rtems_test_assert( directory_not != NULL );
384  d_not = readdir (directory_not);
385  rtems_test_assert( d_not == NULL );
386  status = closedir (directory_not);
387  rtems_test_assert (status == 0);
388
389  printf("chdir to %s\n", my_file);
390  status = chdir (my_file);
391  rtems_test_assert (status == -1);
392
393  printf( "\nPerforming stat of directory /\n");
394  status = stat( "/", &s );
395  printf("status for stat : %d, size of directory: %" PRIdoff_t "\n\n", status, s.st_size);
396
397  puts( "\nOpen and print directory /" );
398  directory = opendir("/");
399  rtems_test_assert( directory );
400  printdir(directory);
401
402  printf("\nmkdir /d/my_dir\n");
403  status = mkdir( "/d/my_dir", 0x1c0 );
404  printf("Open /d/my_dir\n");
405  directory_not = opendir( "/d/my_dir" );
406  rtems_test_assert( directory_not );
407
408  printf( "remove /d/my_dir.\n" );
409  status = rmdir( "/d/my_dir" );
410  rtems_test_assert( status == 0 );
411
412  printf( "close /d/my_dir.\n" );
413  closedir( directory_not );
414
415  printf( "\nOpening directory /c\n" );
416  directory2 = opendir("/c");
417
418  rtems_test_assert( directory2 );
419
420  printdir(directory2);
421  status = closedir( directory2 );
422
423  printf( "\nOpening directory /c/y\n" );
424  directory3 = opendir("/c/y");
425  rtems_test_assert( directory3 );
426  printdir(directory3);
427  status = closedir( directory3 );
428
429  printf( "\nLSEEK to the start of the open directory\n" );
430  lseek( directory->dd_fd, 0, SEEK_SET );
431  printdir(directory);
432
433  lseek( directory->dd_fd, 0, SEEK_CUR );
434
435  lseek( directory->dd_fd, 0, SEEK_END );
436
437  lseek( directory->dd_fd, 0, -99 );
438
439  printf( "\nRewinding directory\n" );
440  rewinddir( directory );
441  printdir(directory);
442
443#if 0
444  /* Newlib's implementation does not check for NULL */
445  printf( "Send rewinddir a NULL pointer\n");
446  rewinddir( NULL );
447#endif
448
449  printf( "\nSeek directory\n" );
450  printf( "telldir() should report only sizeof(struct dirent) increments \n" );
451  printf( "in position. Sizeof(struct dirent): %zd\n",
452                          sizeof(struct dirent) );
453  rewinddir( directory );
454  for( off=0 ; off<=200 ; off=off + sizeof(struct dirent) / 4 ) {
455    seekdir( directory, off );
456    printf(
457       "seeked to %2" PRIdoff_t " -- currently at %2ld\n",
458       off,
459       telldir(directory)
460    );
461  }
462
463  printf( "Send seekdir a NULL pointer\n");
464  seekdir( NULL, off );
465
466  printf( "\nClosing directory\n" );
467  status = closedir( directory );
468
469  printf( "\nSCANDIR TEST\n");
470  printf( "\nselection rule 1\n");
471  printf( "scanning for any entry under directory /c\n\n");
472  status = scandir(
473     "/c",
474     &namelist,
475     select1,
476     NULL
477  );
478  printf("\nscandir status: %d\n", status );
479  for ( i=0; i<status; i++)
480  {
481     printf("Selected Node Name: %s\n", namelist[i]->d_name );
482  }
483
484  printf( "\nselection rule 2\n");
485  printf( "scanning for any entry under directory /c whose name = y\n\n");
486  status = scandir(
487     "/c",
488     &namelist,
489     select2,
490     NULL
491  );
492  printf("\nscandir status: %d\n", status );
493  for ( i=0; i<status; i++)
494  {
495     printf("Selected Node Name: %s\n", namelist[i]->d_name );
496  }
497
498  printf( "\nSCANDIR with sorting\n" );
499  printf( "\nselection rule 1\n");
500  printf( "scanning for any entry under directory /c\n");
501  printf( "sort in ascending order\n\n");
502  status = scandir(
503     "/c",
504     &namelist,
505     select1,
506     compare_ascending
507  );
508  printf("\nscandir status: %d\n", status );
509  for ( i=0; i<status; i++)
510  {
511     printf("Selected and Sorted Node Name: %s\n", namelist[i]->d_name );
512  }
513
514
515  printf( "\nSCANDIR with sorting\n" );
516  printf( "\nselection rule 1\n");
517  printf( "scanning for any entry under directory /c\n");
518  printf( "sort in descending order\n\n");
519  status = scandir(
520     "/c",
521     &namelist,
522     select1,
523     compare_descending
524  );
525  printf("scandir status: %d\n", status );
526  for ( i=0; i<status; i++)
527  {
528     printf("Selected and Sorted Node Name: %s\n", namelist[i]->d_name );
529  }
530
531  printf("unlink %s should return 0\n", my_file);
532  status = unlink( my_file );
533  rtems_test_assert ( status == 0 );
534
535  test_across_mount();
536  TEST_END();
537  rtems_test_exit(0);
538}
Note: See TracBrowser for help on using the repository browser.