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

4.104.114.84.9
Last change on this file since 3c0c898 was 3c0c898, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 5, 2004 at 3:51:13 PM

2004-03-05 Joel Sherrill <joel@…>

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