source: rtems/testsuites/psxtests/psxstat/test.c @ 0bbc89d

4.104.114.84.95
Last change on this file since 0bbc89d was 0bbc89d, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 25, 2000 at 4:52:28 PM

2000-10-24 Joel Sherrill <joel@…>

  • psxmount/test.c, psxstat/test.c: Include <imfs.h> to get IMFS_ops. It was formerly incorrectly prototyped in <libio.h>.
  • Property mode set to 100644
File size: 17.8 KB
Line 
1/*
2 *  This test exercises stat() via fstat() and generates as many of the
3 *  path evaluation cases as possible.
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <tmacros.h>
16#include <assert.h>
17#include <sys/stat.h>
18#include <fcntl.h>
19#include <limits.h>
20#include <stdio.h>
21#include <unistd.h>
22#include <errno.h>
23#include <string.h>
24#include <rtems.h>
25#include <rtems/libio.h>
26#include <imfs.h>
27
28#define MAXSYMLINK 5   /* There needs to be a better way of getting this. */
29
30
31/*
32 *  List of files which should exist.
33 */
34
35char *Files[] = {
36  "////dir1/\\//file1\\\\//",
37  "/dir1/file2",
38  "/dir1/file3",
39  "/dir1/file4",
40  "/dir1/dir1/file1",
41  "../../..//dir1/./././dir1/ file1",
42  "main.c",
43  0
44};
45
46/*
47 *  List of directories which should exist.
48 */
49
50char *Directories[] = {
51  "/dir1",
52  "/dir2",
53  "/dir3",
54  "/dir4",
55  "/dir1/dir1",
56  "/./././dir1/ dir1",
57  "/./././links", 
58  "///dir1/dir1/../../dir1/../symlinks/////",
59  0
60};
61
62char *Links_to_Dirs[]= {
63  "dir1/dir1/../../links/dir1",
64  "links/dir2",
65  "links/dir3",
66  "links/dir4",
67  "links/dir1_dir1",
68  "links/dir1_ dir1",
69  "links/../links/../links/links",
70  0
71};
72
73char *Links_to_Files[]= {
74  "links/dir1_file1",
75  "links/dir1_file2",
76  "links/dir1_file3",
77  "links/dir1_file4",
78  "links/dir1_dir1_f1",
79  "links/dir1_dir1 f1",
80  0
81};
82
83char *Links_to_dirlinks[]= {
84  "links/links/links/links_dir1",
85  "links//links_dir2",
86  "links//links_dir3",
87  "links//links_dir4",
88  "links//links_dir1_d1",
89  "links//links_dir1 d1",
90  "links//links_links",
91  0
92};
93
94char *Links_to_filelinks[]= {
95  "links///links_d1_file1",
96  "links///links_d1_file2",
97  "links///links_d1_file3",
98  "links///links_d1_file4",
99  "links///links_d1_d1_f1",
100  "links///links_r1_d1 f1",
101  0
102};
103
104char *SymLinks[]= {
105  "/symlinks/a_file_symlink",
106  "/symlinks/a_dir_symlink",
107  "/symlinks/a_link_symlink",
108  "../symlinks/no_file",
109  "/symlinks/a_dir_symlink/a_file_symlink",
110  0
111};
112
113/*
114 *  List of absolute paths to stat.
115 */
116
117char *Good_absolute_paths[] = {
118  "/dev",
119  "////dir1/\\//file1\\\\//",
120  "/dir1/\\\\/file2",
121  "/dir1/file3/////\\\\\\",
122  "/dir1/file4",
123  "/dir1/dir1/file1",
124  "/dir1/dir1/ file1",
125  "/dir1",
126  "/dir2//////\\",
127  "/dir3",
128  "/dir4",
129  "/dir1/dir1",
130  "/dir1/ dir1///\\\\",
131  "/\\/\\/\\/\\/\\/\\/links\\/\\/\\/\\/\\/\\",
132  0
133};
134
135
136char *Bad_paths[] = {
137  "/links/ENAMETOOLONG__________________________",
138  "/dir1/file4/NOTADIR",
139  "/dir1/dir1/EACCES__",
140  0
141};
142
143/*
144 *  List of relative paths to stat.
145 */
146
147char *Good_relative_paths[] = {
148  "dev",
149  "dir1/\\//file1\\\\//",
150  "dir1/\\\\/file2",
151  "dir1/file3/////\\\\\\",
152  "dir1/file4",
153  "dir1/dir1/file1",
154  "dir1/dir1/ file1",
155  "dir1",
156  "dir2//////\\",
157  "dir3",
158  "dir4",
159  "dir1/dir1",
160  "dir1/ dir1///\\\\",
161  "main.c",
162  0
163};
164
165/*
166 *  Do a stat on a single file and report the status.
167 */
168
169void stat_a_file(
170  const char *file
171)
172{
173  int         status;
174  struct stat statbuf;
175  int         major1;
176  int         minor1;
177  int         major2;
178  int         minor2;
179
180
181  assert( file );
182
183  printf( "stat( %s ) returned ", file );
184  fflush( stdout );
185
186  status = stat( file, &statbuf );
187
188  if ( status == -1 ) {
189    printf( ": %s\n", strerror( errno ) );
190  } else {
191
192    rtems_filesystem_split_dev_t( statbuf.st_dev, major1, minor1 );
193    rtems_filesystem_split_dev_t( statbuf.st_rdev, major2, minor2 );
194
195
196    printf("\n\tst_dev     (0x%x:0x%x)\n", major1, minor1 );
197    printf(  "...st_ino     %x\n", (int) statbuf.st_ino );
198    printf(  "...st_mode    %o\n", statbuf.st_mode );
199    printf(  "...st_nlink   %x\n", statbuf.st_nlink );
200    printf(  "...st_uid     %d\n", statbuf.st_uid );
201    printf(  "...st_gid     %d\n", statbuf.st_gid );
202    printf(  "...st_rdev    (0x%x:0x%x)\n", major2, minor2 );
203    printf(  "...st_size    %d\n",(unsigned int) statbuf.st_size );
204    printf(  "...st_atime   %s", ctime( &statbuf.st_atime ) );
205    printf(  "...st_mtime   %s", ctime( &statbuf.st_mtime ) );
206    printf(  "...st_ctime   %s", ctime( &statbuf.st_ctime ) );
207#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
208    printf(  "...st_blksize %x\n", statbuf.st_blksize );
209    printf(  "...st_blocks  %x\n", statbuf.st_blocks );
210#endif
211
212  }
213}
214
215/*
216 *  stat() multiple files at a time
217 */
218
219void stat_multiple_files(
220  char **files
221)
222{
223  int    i;
224
225  i = 0;
226  while ( files[i] ) {
227    stat_a_file( files[i] );
228    i++;
229  }
230}
231
232/*
233 *  chown() multiple files at a time
234 */
235void chown_multiple_files(
236  char **files
237)
238{
239  int    i;
240  uid_t  st_uid;
241  gid_t  st_gid;
242
243  st_uid = geteuid();
244  st_gid = getegid();
245
246  i = 0;
247  while ( files[i] ) {
248    printf("Change group of %s\n", files[i]);
249    chown( files[i], st_uid, (st_gid+1) );
250    stat_a_file( files[i] );
251
252    printf("Change owner of %s\n", files[i]);
253    chown( files[i], (st_uid+1), st_gid );
254    stat_a_file( files[i] );
255    i++;
256  }
257
258}
259
260
261
262/*
263 *  mknod() multiple files at a time
264 */
265
266void make_multiple_files(
267  char **files
268)
269{
270  int    i;
271  int    status;
272
273  i = 0;
274  while ( files[i] ) {
275    printf( "Making file %s\n", files[i] );
276    status = mknod( files[i], ( S_IFREG | S_IROTH|S_IWOTH ), 0LL );
277    assert( !status );
278    i++;
279  }
280  puts( "" );
281}
282
283void make_multiple_bad_files(
284  char **files
285)
286{
287  int    i;
288  int    status;
289
290  i = 0;
291  while ( files[i] ) {
292    printf( "Making file %s ", files[i] );
293    status = mknod( files[i], ( S_IFREG | S_IROTH|S_IWOTH ), 0LL );
294    assert( status );
295    printf( ": %s\n", strerror( errno ) );
296    i++;
297  }
298  puts( "" );
299}
300
301void make_multiple_links(
302  char **existing,
303  char **new
304)
305{
306  int    i;
307  int    status;
308
309  i = 0;
310  while ( new[i] && existing[i] ) {
311    printf( "Making file %s\n", new[i] );
312    status = link( existing[i], new[i] );
313    assert( !status );
314    i++;
315  }
316  puts( "" );
317
318  status = link( "fred", "bob" );
319  assert( status == -1 );
320
321  status = link( existing[1], "doug/bob" );
322  assert( status == -1 );
323}
324
325
326void make_too_many_links()
327{
328  int    i;
329  int    status;
330  char   name [20];
331
332  status = mkdir("/dummy", S_IRWXU );
333  assert( status == 0 );
334
335  for (i=1; i<= LINK_MAX; i++) {
336
337    sprintf(name,"/LinkName%d",i);
338    printf( "Making file %s\n", name );
339    status = link("/dummy" , name );
340    if( i < LINK_MAX )
341       assert( !status );
342    else
343       assert( status == -1 );
344
345  }
346}
347
348
349void make_a_symlink(
350  char *existing,
351  char *new
352)
353{
354  int    status;
355  char   buf[100];
356  int    len;
357
358  memset( buf, 0, 100 );
359
360  printf( "Making file %s\n", new );
361  status = symlink( existing, new );
362  assert( !status );
363
364  printf( "Verify with readlink\n");
365  status = readlink( new, buf, 100 );
366  len = strlen( existing );
367  assert ( status == len );
368
369  status = readlink( new, buf, 3 );
370  len = strlen( existing );
371  if (len < 3 )
372    assert( status == len );
373  else
374    assert( status == 3 );
375
376  status = strcmp( existing, buf );
377  assert( !status );
378}
379
380void make_multiple_symlinks()
381{
382 int  status;
383
384 make_a_symlink( Files[0],             SymLinks[0] );
385 make_a_symlink( Directories[0],       SymLinks[1] );
386 make_a_symlink( Links_to_dirlinks[0], SymLinks[2] );
387 make_a_symlink( "No_File",            SymLinks[3] );
388 make_a_symlink( SymLinks[1],          SymLinks[4] );
389 make_a_symlink( "//links",            "/symlinks/links"  );
390
391 stat_a_file( SymLinks[0] );
392 stat_a_file( SymLinks[1] );
393 stat_a_file( SymLinks[2] );
394 stat_a_file( SymLinks[3] );
395 stat_a_file( SymLinks[4] );
396
397 status = symlink(  "//links", "bob/frank" );
398 assert (status == -1);
399
400}
401/*
402void make_too_many_symlinks()
403{
404  int  i, status;
405  char name1[8];
406
407  for (i=1; i <= MAXSYMLINK; i++) {
408    sprintf( name1, "SymLink%d", i );
409    status = symlink( "/dummy", name1 );
410    if( i < MAXSYMLINK )
411       assert( !status );
412    else
413       assert( status == -1 );
414  }
415}
416*/
417void make_many_symlinks(
418  char  *real_file,
419  int    link_count
420)
421{
422  int  i;
423  char name1[5];
424  char name2[5];
425  char *link_file;
426
427  link_file = real_file;
428  for (i=1; i < link_count; i++) {
429    sprintf( name1, "%d", i );
430    make_a_symlink( link_file, name1 );
431    strcpy( name2, name1 );
432    link_file = name2;
433  }
434
435  for (i=1; i < link_count; i++) {
436    sprintf( name1, "%d", i );
437    stat_a_file( name1 );
438  }
439
440}
441
442/*
443 *  mkdir() multiple directories at a time
444 */
445 
446void make_multiple_directories(
447  char **files
448) 
449{
450  int    i;
451  int    status;
452
453  i = 0; 
454  while ( files[i] ) {
455    printf( "Making directory %s\n", files[i] );
456    status = mkdir( files[i], S_IRWXU );
457    assert( !status );
458    i++;
459  }
460  puts( "" );
461} 
462
463/*
464 * Cause faults.
465 */
466
467
468void Cause_faults()
469{
470  int                                   fd;
471  int                                   status;
472  char                                  longer_name[100];
473  rtems_filesystem_mount_table_entry_t *mt_entry;
474
475  /*
476   * Verify chmod with an invalid type.
477   */
478
479  printf("\n\nPass an invalid mode to chmod should fail with EPERM \n" );
480  status = chmod( Files[0], S_IFREG );
481  assert( status == -1 ); 
482  assert( errno == EPERM );
483
484  /*
485   * Try to chdir to a file.
486   */
487
488  printf("chdir to a file should fail with ENOTDIR\n");
489  status = chdir( Files[0] );
490  assert( status == -1 );
491  assert( errno == ENOTDIR );
492
493  /*
494   * Change mode to read/write on a directory.
495   * Verify directory works properly.
496   */
497
498  printf("Verify RWX permission on %s via access\n", Directories[0]);
499  status = access( Directories[0], ( R_OK | W_OK | X_OK )  );
500  assert( status == 0 );
501
502  printf( "chmod of %s to Read/Write\n", Directories[0] );
503  status = chmod( Directories[0], (S_IXGRP | S_IXOTH) );
504  assert( status == 0 );
505
506  printf( "chmod fred should fail with ENOENT\n" );
507  status = chmod( "fred", (S_IXGRP | S_IXOTH) );
508  assert( status == -1 );
509  assert( errno == ENOENT );
510
511  strcpy(longer_name, Directories[0] );
512  strcat(longer_name, "/BADNAME" );
513  printf( "Create under %s should fail with EACCES\n", Directories[0] );
514  status = mkdir( longer_name , S_IRWXU );
515  assert( status == -1 );
516  assert( errno == EACCES );
517
518  printf("chdir to %s should fail with EACCES\n", Directories[4] );
519  status = chdir( Directories[4] );
520  assert( status == -1 );
521  assert( errno == EACCES );
522
523  /*
524   * Check stat with a NULL buffer.
525   */
526
527  printf("Stat with a NULL buffer should fail with EFAULT\n");
528  status = stat( Directories[0], NULL );
529  assert( status == -1 );
530  assert( errno == EFAULT );
531
532  /*
533   * Set current to a directory with no owner permissions.
534   * Verify it works properly.
535   */
536
537  printf( "\n\nchmod of %s to Read/Write\n", Directories[0] );
538  status = chmod( Directories[0], (S_IXGRP | S_IXOTH) );
539  assert( status == 0 );
540
541  printf("mkdir %s should fail with EACCESS\n", longer_name );
542  status = mkdir( longer_name , S_IRWXU );
543  assert( status == -1 );
544  assert( errno == EACCES );
545
546  printf("\n%s Should exist ( access )\n",Directories[0] );
547  status = access( Directories[0], F_OK );
548  assert( status == 0 );
549  printf("\n%s Should have read  permission( access )\n",Directories[0] );
550  status = access( Directories[0], R_OK );
551  assert( status != 0 );
552  printf("\n%s Should have write permission( access )\n",Directories[0] );
553  status = access( Directories[0], W_OK );
554  assert( status != 0 );
555  printf("\n%s Should not have execute permission( access )\n",Directories[0] );
556  status = access( Directories[0], X_OK );
557  assert( status != 0 );
558 
559  printf("\nRestore %s to RWX\n",Directories[0] );
560  status = chmod( Directories[0], S_IRWXU );
561  assert( status == 0 );
562
563  printf("chdir to / \n");
564  status = chdir( "/" );
565  assert( status == 0 );
566
567  /*
568   * Remove one of the directories.
569   * Verify links to the removed directory still work.
570   */
571
572  printf( "Remove %s\n", Directories[5] );
573  status = rmdir( Directories[5] );
574  assert( status == 0 );
575
576  stat_a_file( Directories[5] );
577  status = access( Directories[5], F_OK );
578  assert( status != 0 );
579
580  stat_a_file( Links_to_Dirs[5] );
581  status = readlink( Links_to_Dirs[5], longer_name, 3 );
582  assert( status == -1 );
583  assert( errno == EINVAL );
584
585  stat_a_file( Links_to_dirlinks[5] );
586  printf("Chdir to %s\n", Links_to_Dirs[5] );
587  status = chdir( Links_to_Dirs[5] );
588  assert( status == 0 );
589
590  /*
591   * Verify we cannot move up from a node with no parent node.
592   */
593
594  printf("Chdir to .. should fail with ENOENT\n" );
595  status = chdir( ".." );
596  assert( status == -1 );
597  assert( errno == ENOENT );
598
599  /*
600   * Create a subdirectory under the dangling node.
601   */
602
603  printf("mkdir ../t should fail with ENOENT\n" );
604  status = mkdir( "../t" , S_IRWXU );
605  assert( status == -1 );
606  assert( errno == ENOENT );
607
608  printf("mkdir t\n");
609  status = mkdir( "t" , S_IRWXU );
610  assert( status == 0 );
611
612  printf("chdir to / \n");
613  status = chdir( "/" );
614  assert( status == 0 );
615
616  /*
617   * Check rmdir, rmnod, and unlink
618   */
619
620  printf("rmdir %s should fail with ENOTDIR\n", Links_to_Dirs[5] );
621  status = rmdir( Links_to_Dirs[5] );
622  assert( status == -1 );
623  assert( errno == ENOTDIR );
624
625  printf("unlink %s\n", Links_to_Dirs[5] );
626  status = unlink( Links_to_Dirs[5] );
627  assert( status == 0 );
628
629  printf("unlink %s should fail with ENOTEMPTY\n", Links_to_dirlinks[5] );
630  status = unlink(  Links_to_dirlinks[5] );
631  assert( status == -1 );
632  assert( errno == ENOTEMPTY );
633
634  strcpy( longer_name,  Links_to_dirlinks[5] );
635  strcat( longer_name, "/t");
636  printf("rmdir %s\n", longer_name );
637  status = rmdir( longer_name );
638  assert( status == 0 );
639
640  printf("unlink %s\n", Links_to_Dirs[5]);
641  status = unlink( Links_to_dirlinks[5] );
642  assert( status == 0 );
643
644  status = chdir( Directories[0] );
645  status = mkdir ( "my_mount_point", S_IRWXU );
646  assert( status == 0 );
647
648  printf("Attempting to mount IMFS file system at /dir1/my_mount_point \n");
649  status = mount(
650     &mt_entry,
651     &IMFS_ops,
652     RTEMS_FILESYSTEM_READ_WRITE,
653     NULL,
654     "/dir1/my_mount_point" );
655  assert( status == 0 );
656
657  printf("rmdir /dir1/my_mount_point should fail with EBUSY\n");
658  status = rmdir ("/dir1/my_mount_point" );
659  assert( status == -1 );
660  assert( errno == EBUSY );
661
662  printf( "Unmount /dir1/my_mount_point\n");
663  status = unmount( "/dir1/my_mount_point" );
664  assert( status == 0 );
665
666  /*
667   * Verify write permission is checked.
668   */
669
670  printf("chmod of %s to group and other execute\n", Files[0] );
671  status = chmod (Files[0], (S_IXGRP | S_IXOTH) );
672  assert( status == 0 );
673
674  printf("Open %s for write should fail with EACCES\n", Files[0] );
675  fd = open (Files[0], O_WRONLY); 
676  assert( fd == -1 );
677  assert( errno == EACCES );
678
679  printf("chmod of %s to User Execute and Read\n", Directories[3] );
680  status = chmod (Directories[3], (S_IXUSR | S_IRUSR) );
681  assert( status == 0 );
682  strcpy(longer_name, Directories[3] );
683  strcat(longer_name, "/NewFile" );
684  printf("Mkdir of %s should fail with EACCES\n",longer_name );
685  status = mkdir( longer_name, S_IRWXU );
686  assert( status != 0 );
687  assert( errno == EACCES );
688
689  printf(" Making too many hard links.\n" );
690  make_too_many_links( );
691
692  printf( "pass fstat a null pointer should fail with EFAULT\n");
693  status = fstat( fd, NULL );
694  assert( status == -1 ); 
695  assert( errno == EFAULT);
696
697  /*
698   * The current directory MUST be restored at the end of this test.
699   */
700
701  printf("chdir to / \n");
702  status = chdir( "/" );
703  assert( status == 0 );
704
705}
706
707void Show_Time()
708{
709  rtems_time_of_day time;
710  rtems_status_code status;
711
712  status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time );
713  printf(">>>>Current Time: ");
714  print_time( " - rtems_clock_get - ", &time, "\n" );
715}
716
717/*
718 *  main entry point to the test
719 */
720
721#if defined(__rtems__)
722int test_main(void)
723#else
724int main(
725  int    argc,
726  char **argv
727)
728#endif
729{
730  rtems_status_code status;
731  rtems_time_of_day time;
732
733  puts( "\n\n*** STAT TEST 01 ***" );
734
735  build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
736  status = rtems_clock_set( &time );
737
738  /*
739   *  Create the files and directories for the test.
740   */
741  Show_Time();
742
743  make_multiple_directories( Directories );
744  make_multiple_files( Files );
745  make_multiple_links( Directories,    Links_to_Dirs );
746  make_multiple_links( Files,          Links_to_Files );
747
748  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
749  make_multiple_links( Links_to_Dirs,  Links_to_dirlinks );
750  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
751  make_multiple_links( Links_to_Files, Links_to_filelinks );
752
753  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
754
755  /*
756   *  Now go through all the absolute path.
757   */
758
759  puts( "Doing the stat() on all the good absolute paths" );
760  stat_multiple_files( Good_absolute_paths );
761
762  /*
763   *  run through the relative paths.
764   */
765
766  puts( "\nDoing the stat() on all the good relative paths" );
767  stat_multiple_files( Good_relative_paths );
768
769  /*
770   * Change directory and releative paths are now bad.
771   */
772
773  puts("\nchdir to dev");
774  chdir("dev");
775  puts("\nstat relative paths that are now bad");
776  stat_multiple_files( Good_relative_paths );
777
778  /*
779   * Change directory to the link directory and follow links.
780   */
781
782  puts("\nchdir to ../links");
783  chdir("../links");
784  puts("Doing the stat() on good links\n");
785  stat_multiple_files( Links_to_Dirs );
786  stat_multiple_files( Links_to_Files );
787  stat_multiple_files( Links_to_dirlinks  );
788  stat_multiple_files( Links_to_filelinks );
789 
790  /*
791   * Chmod on dir1/dir1.  This allows the error path to be hit.
792   */
793
794  printf( "chmod of %s to Read/Write\n", Directories[4] );
795  chmod( Directories[4], (S_IROTH|S_IWOTH) );
796  puts( "\nDoing the stat() on all the bad paths" );
797
798  stat_multiple_files( Bad_paths );
799  make_multiple_bad_files( Bad_paths );
800
801  printf( "Return %s to RWX\n", Directories[4] );
802  chmod( Directories[4], S_IRWXU );
803
804
805  /*
806   * Check out symbolic links.
807   */
808
809  make_multiple_symlinks();
810  make_many_symlinks( "/symlinks", 10 );
811
812  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
813  Cause_faults();
814
815  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
816  chown_multiple_files( Files );
817
818  status = rtems_task_wake_after( 5 * TICKS_PER_SECOND );
819  chown_multiple_files( Links_to_Dirs );
820 
821  puts( "\n\n*** END OF STAT TEST 01 ***" );
822  exit(0);
823}
824
825
826
827
828
829
830
Note: See TracBrowser for help on using the repository browser.