source: rtems/testsuites/psxtests/psxfile01/test.c @ 3f42281e

4.11
Last change on this file since 3f42281e was 3f42281e, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 1, 2010 at 9:15:07 PM

2010-07-01 Joel Sherrill <joel.sherrilL@…>

  • psxfile01/Makefile.am, psxfile01/psxfile01.scn, psxfile01/test.c: Remove tests which put NULL entries in file handlers.
  • Property mode set to 100644
File size: 15.2 KB
Line 
1/*
2 *  Simple test program to exercise some of the basic functionality of
3 *  POSIX Files and Directories Support.
4 *
5 *  This test assumes that the file system is initialized with the
6 *  following directory structure:
7 *
8 *  XXXX fill this in.
9 *    /
10 *    /dev
11 *    /dev/XXX   [where XXX includes at least console]
12 *
13 *  COPYRIGHT (c) 1989-2010.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.com/license/LICENSE.
19 *
20 *  $Id$
21 */
22
23#include <stdio.h>
24
25#include <pmacros.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <errno.h>
31#include <string.h>
32#include <ctype.h>
33#include <rtems/imfs.h>
34
35#include <rtems.h>
36#include <rtems/libio.h>
37
38void test_case_reopen_append(void);
39
40char test_write_buffer[ 1024 ];
41rtems_filesystem_operations_table  IMFS_ops_no_evalformake;
42rtems_filesystem_operations_table  IMFS_ops_no_rename;
43
44/*
45 *  File test support routines.
46 */
47
48void test_cat(
49  char *file,
50  int   offset_arg,
51  int   length
52);
53
54void test_write(
55  char   *file,
56  off_t  offset,
57  char  *buffer
58);
59
60void test_extend(
61  char *file,
62  off_t new_len
63);
64
65void IMFS_dump( void );
66int IMFS_memfile_maximum_size( void );
67
68/*
69 *  dump_statbuf
70 */
71
72void dump_statbuf( struct stat *buf )
73{
74  int         major1;
75  int         minor1;
76  int         major2;
77  int         minor2;
78
79  rtems_filesystem_split_dev_t( buf->st_dev, major1, minor1 );
80  rtems_filesystem_split_dev_t( buf->st_rdev, major2, minor2 );
81
82  printf( "....st_dev     (0x%x:0x%x)\n", major1, minor1 );
83  printf( "....st_ino     %" PRIxino_t "  may vary by small amount\n", buf->st_ino );
84  printf( "....mode  = %08o\n", (unsigned int) buf->st_mode );
85  printf( "....nlink = %d\n", buf->st_nlink );
86
87  printf( "....uid = %d\n", buf->st_uid );
88  printf( "....gid = %d\n", buf->st_gid );
89
90  printf( "....atime = %s", ctime(&buf->st_atime) );
91  printf( "....mtime = %s", ctime(&buf->st_mtime) );
92  printf( "....ctime = %s", ctime(&buf->st_ctime) );
93
94  printf( "....st_blksize %" PRIxblksize_t "\n", buf->st_blksize );
95  printf( "....st_blocks  %" PRIxblkcnt_t "\n", buf->st_blocks );
96}
97
98void stat_a_file(
99  const char *file
100)
101{
102  int         status;
103  struct stat statbuf;
104
105  rtems_test_assert( file );
106
107  printf( "stat( %s ) returned ", file );
108  fflush( stdout );
109
110  status = stat( file, &statbuf );
111
112  if ( status == -1 ) {
113    printf( ": %s\n", strerror( errno ) );
114  } else {
115    puts("");
116    dump_statbuf( &statbuf );
117  }
118
119}
120
121/*
122 *  Main entry point of the test
123 */
124
125#if defined(__rtems__)
126int test_main(void)
127#else
128int main(
129  int argc,
130  char **argv
131)
132#endif
133{
134  int               status;
135  size_t            max_size;
136  int               fd;
137  int               i;
138  struct stat       buf;
139  char              buffer[128];
140  FILE             *file;
141  time_t            atime1;
142  time_t            mtime1;
143  time_t            ctime1;
144  time_t            atime2;
145  time_t            mtime2;
146  time_t            ctime2;
147  rtems_status_code rtems_status;
148  rtems_time_of_day time;
149
150  printf( "\n\n*** FILE TEST 1 ***\n" );
151
152  /*
153   *  Grab the maximum size of an in-memory file.
154   */
155
156  max_size = IMFS_memfile_maximum_size();
157
158  build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
159  rtems_status = rtems_clock_set( &time );
160
161  /*
162   *  Dump an empty file system
163   */
164
165  IMFS_dump();
166
167  /*
168   *  Simple stat() of /dev/console.
169   */
170
171  puts( "stat of /dev/console" );
172  status = stat( "/dev/console", &buf );
173  rtems_test_assert( !status );
174
175  dump_statbuf( &buf );
176
177  /*
178   *  Exercise mkdir() and some path evaluation.
179   */
180
181  puts( "" );
182  puts( "mkdir /dev/tty" );
183  status = mkdir( "/dev/tty", S_IRWXU );
184  rtems_test_assert( !status );
185
186  puts( "" );
187  puts( "mkdir /usr" );
188  status = mkdir( "/usr", S_IRWXU );
189  rtems_test_assert( !status );
190  puts( "mkdir /etc" );
191  status = mkdir( "/etc", S_IRWXU );
192  rtems_test_assert( !status );
193
194  puts( "mkdir /tmp" );
195  status = mkdir( "/tmp", S_IRWXU );
196  rtems_test_assert( !status );
197
198  /* this tests the ".." path in path name evaluation */
199  puts( "mkdir /tmp/.." );
200  status = mkdir( "/tmp/..", S_IRWXU );
201  rtems_test_assert( status == -1 );
202  rtems_test_assert( errno == EEXIST );
203
204  /* now check out trailing separators */
205  puts( "mkdir /tmp/" );
206  status = mkdir( "/tmp/", S_IRWXU );
207  rtems_test_assert( status == -1 );
208  rtems_test_assert( errno == EEXIST );
209
210  /* try to make a directory under a non-existent subdirectory */
211  puts( "mkdir /j/j1" );
212  status = mkdir( "/j/j1", S_IRWXU );
213  rtems_test_assert( status == -1 );
214  rtems_test_assert( errno == ENOENT );
215
216  /* this tests the ability to make a directory in the current one */
217  puts( "mkdir tmp" );
218  status = mkdir( "tmp", S_IRWXU );
219  rtems_test_assert( status == -1 );
220  rtems_test_assert( errno == EEXIST );
221
222  /* test rtems_filesystem_evaluate_path by sending NULL path */
223  status = chdir( NULL );
224  rtems_test_assert( status == -1 );
225  rtems_test_assert( errno == EFAULT );
226
227  /*
228   *  Now switch gears and exercise rmdir().
229   */
230
231  puts( "" );
232  puts( "rmdir /usr" );
233  status = rmdir( "/usr" );
234  rtems_test_assert( !status );
235
236  puts( "rmdir /dev" );
237  status = rmdir( "/dev" );
238  rtems_test_assert( status == -1 );
239  rtems_test_assert( errno ==  ENOTEMPTY);
240
241  puts( "rmdir /fred" );
242  status = rmdir ("/fred");
243  rtems_test_assert (status == -1);
244  rtems_test_assert( errno == ENOENT );
245
246  puts( "mknod /dev/test_console" );
247  status = mknod( "/dev/test_console", S_IFCHR, 0LL );
248  rtems_test_assert( !status );
249
250  puts( "mknod /dev/tty/S3" );
251  status = mknod( "/dev/tty/S3", S_IFCHR, 0xFF00000080LL );
252  rtems_test_assert( !status );
253
254  puts ("mknod /etc/passwd");
255  status = mknod( "/etc/passwd", (S_IFREG | S_IRWXU), 0LL );
256  rtems_test_assert( !status );
257
258  puts( "mkdir /tmp/my_dir");
259  status = mkdir( "/tmp/my_dir", S_IRWXU );
260  rtems_test_assert( status == 0 );
261
262  puts("mkfifo /c/my_dir" );
263  status = mkfifo( "/c/my_dir", S_IRWXU );
264  rtems_test_assert( status == -1 );
265
266  /*
267   *  Try to make a directory under a file -- ERROR
268   */
269
270  puts( "mkdir /etc/passwd/j" );
271  status = mkdir( "/etc/passwd/j", S_IRWXU );
272  rtems_test_assert( status == -1 );
273  rtems_test_assert( errno == ENOTDIR );
274
275  /*
276   *  Simple open failure case on non-existent file
277   */
278
279  puts( "open /tmp/joel - should fail with ENOENT" );
280  fd = open( "/tmp/joel", O_RDONLY );
281  rtems_test_assert( fd == -1 );
282  rtems_test_assert( errno == ENOENT );
283
284  /*
285   *  Simple open case where the file is created.
286   */
287
288  puts( "open /tmp/j" );
289  fd = open( "/tmp/j", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
290  rtems_test_assert( fd != -1 );
291  printf( "open returned file descriptor %d\n", fd );
292
293  puts( "close /tmp/j" );
294  status = close( fd );
295  rtems_test_assert( !status );
296
297  puts( "close /tmp/j again" );
298  status = close( fd );
299  rtems_test_assert( status == -1 );
300
301  puts( "unlink /tmp/j" );
302  status = unlink( "/tmp/j" );
303  rtems_test_assert( !status );
304
305  puts( "unlink /tmp" );
306  status = unlink( "/tmp" );
307  rtems_test_assert( status );
308
309  /*
310   *  Simple open failure. Trying to create an existing file.
311   */
312
313  puts("create and close /tmp/tom");
314  fd = open( "/tmp/tom", O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
315  rtems_test_assert( fd != -1 );
316  status = close( fd );
317  rtems_test_assert( status == 0 );
318
319  puts("Attempt to recreate /tmp/tom");
320  fd = open( "/tmp/tom", O_CREAT | O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO );
321  rtems_test_assert( fd == -1 );
322  rtems_test_assert( errno == EEXIST );
323
324  puts("create /tmp/john");
325  fd = open( "/tmp/john", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
326  rtems_test_assert( fd != -1 );
327
328  puts("tcdrain /tmp/john" );
329  status = tcdrain( fd );
330  rtems_test_assert( status == 0 );
331
332  /*
333   *  Test simple write to a file at offset 0
334   */
335
336  puts( "mknod /tmp/joel" );
337  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
338  test_write( "/tmp/joel", 0, "the first write!!!\n" );
339  test_cat( "/tmp/joel", 0, 0 );
340
341  /* Exercise _rename_r */
342
343  /* Simple rename test */
344  puts( "rename /tmp/joel to /tmp/drjoel");
345  status = _rename_r(NULL,"/tmp/joel","/tmp/drjoel");
346  rtems_test_assert(status == 0);
347
348  /* Simple rename test */
349  puts("rename /tmp/drjoel to /tmp/joel");
350  status = _rename_r(NULL,"/tmp/drjoel","/tmp/joel");
351  rtems_test_assert(status == 0);
352
353  /* Invalid old path */
354  puts("rename /tmp/drjoel to /tmp/joel - Should result in an error \
355since old path is not valid");
356  status = _rename_r(NULL,"/tmp/drjoel","/tmp/joel");
357  rtems_test_assert(status == -1);
358
359  /* Invalid new path */
360  puts("rename /tmp/joel to /tmp/drjoel/joel - Should result in an error \
361since new path is not valid");
362  status = _rename_r(NULL,"/tmp/joel","/tmp/drjoel/joel");
363  rtems_test_assert(status == -1);
364
365  puts("changing dir to /tmp");
366  status = chdir("/tmp/");
367  rtems_test_assert(status == 0);
368
369  puts("rename joel to drjoel");
370  status = _rename_r(NULL,"joel","drjoel");
371  rtems_test_assert(status == 0);
372
373  puts("rename drjoel to joel");
374  status = _rename_r(NULL,"drjoel","joel");
375  rtems_test_assert(status == 0);
376
377  /* Rename across file systems */
378  puts("creating directory /imfs");
379  status = mkdir("/imfs",0777);
380  rtems_test_assert(status == 0);
381  puts("creating directory /imfs/hidden_on_mount");
382  status = mkdir("/imfs/hidden_on_mount",0777);
383  rtems_test_assert(status == 0);
384
385  puts("mounting filesystem with IMFS_ops at /imfs");
386  status = mount("null", "/imfs", "imfs", RTEMS_FILESYSTEM_READ_WRITE, NULL);
387  rtems_test_assert(status == 0);
388  puts("creating directory /imfs/test (on newly mounted filesystem)");
389  status = mkdir("/imfs/test", 0777);
390  rtems_test_assert(status == 0);
391
392  puts("attempt to rename directory joel to /imfs/test/joel - should fail with EXDEV");
393  status = _rename_r(NULL, "joel", "/imfs/test/joel");
394  rtems_test_assert(status == -1);
395  rtems_test_assert(errno == EXDEV);
396
397  puts("changing dir to /");
398  status = chdir("/");
399  rtems_test_assert(status == 0);
400
401  puts("attempt to rename across filesystem, with old path having a parent node");
402  puts("attempt to rename tmp/joel to /imfs/test/joel");
403  status = _rename_r(NULL, "tmp/joel", "/imfs/test/joel");
404  rtems_test_assert(status == -1);
405  rtems_test_assert(errno == EXDEV);
406
407  puts("End of _rename_r tests");
408
409  /*
410   *  Test simple write to a file at a non-0 offset in the first block
411   */
412
413  status = unlink( "/tmp/joel" );
414  rtems_test_assert( !status );
415
416  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
417  rtems_test_assert( !status );
418
419  test_write( "/tmp/joel", 10, "the first write!!!\n" );
420  test_cat( "/tmp/joel", 0, 0 );
421  stat_a_file( "/tmp/joel" );
422
423  /*
424   *  Test simple write to a file at a non-0 offset in the second block.  Then
425   *  try to read from various offsets and lengths.
426   */
427
428  puts("unlink /tmp/joel");
429  status = unlink( "/tmp/joel" );
430  rtems_test_assert( !status );
431
432  /* Test a failure path */
433
434  puts( "unlink /tmp/joel" );
435  status = unlink( "/tmp/joel" );
436  rtems_test_assert( status == -1 );
437
438  puts( "mknod /tmp/joel");
439  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
440  rtems_test_assert( !status );
441
442  test_write( "/tmp/joel", 514, "the first write!!!\n" );
443  test_write( "/tmp/joel", 1, test_write_buffer );
444  test_write( "/tmp/joel", 63, test_write_buffer );
445  test_cat( "/tmp/joel", 0, 1 );
446  test_cat( "/tmp/joel", 1, 1 );
447  test_cat( "/tmp/joel", 490, 1 );
448  test_cat( "/tmp/joel", 512, 1 );
449  test_cat( "/tmp/joel", 513, 1 );
450  test_cat( "/tmp/joel", 514, 1 );
451  test_cat( "/tmp/joel", 520, 1 );
452  test_cat( "/tmp/joel", 1, 1024 );
453
454  /*
455   *  Read from a much longer file so we can descend into doubly and
456   *  triply indirect blocks.
457   */
458
459  if ( max_size < (size_t) 300 * 1024 ) {
460    test_extend( "/tmp/joel", max_size - 1 );
461    test_cat( "/tmp/joel", max_size / 2, 1024 );
462  } else {
463    printf( "Skipping maximum file size test since max_size is %zu bytes\n", max_size );
464    puts("That is likely to be bigger than the available RAM on many targets." );
465  }
466
467  stat_a_file( "/tmp/joel" );
468
469  /*
470   *  Now try to use a FILE * descriptor
471   *
472   *  /tmp/j should not exist at this point.
473   */
474
475  puts( "stat of /tmp/j" );
476  errno = 0;
477  status = stat( "/tmp/j", &buf );
478  printf( "stat(/tmp/j) returned %d (errno=%d)\n", status, errno );
479  dump_statbuf( &buf );
480
481  puts( "fopen of /tmp/j" );
482  file = fopen( "/tmp/j", "w+" );
483  rtems_test_assert( file );
484
485  puts( "fprintf to /tmp/j" );
486  for (i=1 ; i<=5 ; i++) {
487    status = fprintf( file, "This is call %d to fprintf\n", i );
488    rtems_test_assert( status );
489    printf( "(%d) %d characters written to the file\n", i, status );
490  }
491
492  fflush( file );
493
494  status = stat( "/tmp/j", &buf );
495  rtems_test_assert( !status );
496  dump_statbuf( &buf );
497  atime2 = buf.st_atime;
498  mtime2 = buf.st_mtime;
499  ctime2 = buf.st_ctime;
500
501
502  status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() );
503  rewind( file );
504  while ( fgets(buffer, 128, file) )
505    printf( "%s", buffer );
506
507  /*
508   * Verify only atime changed for a read.
509   */
510  status = stat( "/tmp/j", &buf );
511  rtems_test_assert( !status );
512  dump_statbuf( &buf );
513  atime1 = buf.st_atime;
514  mtime1 = buf.st_mtime;
515  ctime1 = buf.st_ctime;
516  rtems_test_assert( atime1 != atime2);
517  rtems_test_assert( mtime1 == mtime2);
518  rtems_test_assert( ctime1 == ctime2);
519
520  IMFS_dump();
521
522  unlink( "/tmp/joel" );
523
524  /*
525   *  Now truncate a file
526   */
527
528  status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() );
529  puts( "truncate /tmp/j to length of 40" );
530  status = truncate( "/tmp/j", 40 );
531  rtems_test_assert( !status );
532
533  /*
534   * Verify truncate changed only atime.
535   */
536  status = stat( "/tmp/j", &buf );
537  rtems_test_assert( !status );
538  dump_statbuf( &buf );
539  atime2 = buf.st_atime;
540  mtime2 = buf.st_mtime;
541  ctime2 = buf.st_ctime;
542  rtems_test_assert( atime1 != atime2);
543  rtems_test_assert( mtime1 == mtime2);
544  rtems_test_assert( ctime1 == ctime2);
545
546  IMFS_dump();
547
548  /* try to truncate the console and see what happens */
549  status = truncate( "/dev/console", 40 );
550  rtems_test_assert( status == 0 );
551
552  puts( "truncate /tmp/j to length of 0" );
553  status = truncate( "/tmp/j", 0 );
554  rtems_test_assert( !status );
555
556  puts( "truncate /tmp to length of 0 should fail with EISDIR\n");
557  status = truncate( "/tmp", 0 );
558  rtems_test_assert( status == -1 );
559  printf( "%d: %s\n", errno, strerror( errno ) );
560  rtems_test_assert( errno == EISDIR );
561
562  IMFS_dump();
563
564  status = truncate( "/tmp/fred", 10 );
565  rtems_test_assert( status == -1);
566
567  rtems_status = rtems_io_register_name( "/dev/console", 0, 0 );
568
569  test_case_reopen_append();
570
571  printf( "*** END OF FILE TEST 1 ***\n" );
572  rtems_test_exit( 0 );
573}
574
575/*
576 *  Open/Create a File and write to it
577 *
578 *  Test case submitted by Andrew Bythell <abythell@nortelnetworks.com>.
579 *
580 */
581
582void test_file (char *filename, char *mode);
583
584void test_case_reopen_append(void)
585{
586  printf ("Writing First File\n");
587  test_file ("/one.txt", "a");
588  test_file ("/one.txt", "a");
589
590  /* but not the second time - this will insert junk.
591     the number of ^@'s seems to equal the number of
592     actual characters in the file */
593
594  printf ("Writing Second File\n");
595  test_file ("/two.txt", "a");
596  test_file ("/two.txt", "a");
597
598  test_cat( "/one.txt", 0, 1024 );
599  test_cat( "/two.txt", 0, 1024 );
600}
601
602void test_file (char *filename, char *mode)
603{
604  FILE *fp;
605  fp = fopen (filename, mode);
606  if (!fp)
607      perror ("fopen");
608  fprintf (fp, "this is a test line\n");
609  if (fclose (fp))
610      perror ("fclose");
611}
Note: See TracBrowser for help on using the repository browser.