source: rtems/testsuites/psxtests/psxfile01/test.c @ edeed26

4.104.114.84.95
Last change on this file since edeed26 was df49c60, checked in by Joel Sherrill <joel.sherrill@…>, on 06/12/00 at 15:00:15

Merged from 4.5.0-beta3a

  • Property mode set to 100644
File size: 11.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-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.OARcorp.com/rtems/license.html.
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
38char test_write_buffer[ 1024 ];
39
40/*
41 *  File test support routines.
42 */
43
44void test_cat(
45  char *file,
46  int   offset_arg,
47  int   length
48);
49
50void test_write(
51  char   *file,
52  off_t  offset,
53  char  *buffer
54);
55
56void test_extend(
57  char *file,
58  off_t new_len
59);
60
61void IMFS_dump( void );
62int IMFS_memfile_maximum_size( void );
63
64/*
65 *  dump_statbuf
66 */
67
68void dump_statbuf( struct stat *buf )
69{
70  int         major1;
71  int         minor1;
72  int         major2;
73  int         minor2;
74
75  rtems_filesystem_split_dev_t( buf->st_dev, major1, minor1 );
76  rtems_filesystem_split_dev_t( buf->st_rdev, major2, minor2 );
77
78  printf( "....st_dev     (0x%x:0x%x)\n", major1, minor1 );
79  printf( "....st_ino     %x  may vary by small amount\n",
80      (unsigned int) buf->st_ino );
81  printf( "....mode  = %08o\n", buf->st_mode );
82  printf( "....nlink = %d\n", buf->st_nlink );
83
84  printf( "....uid = %d\n", buf->st_uid );
85  printf( "....gid = %d\n", buf->st_gid );
86
87  printf( "....atime = %s", ctime(&buf->st_atime) );
88  printf( "....mtime = %s", ctime(&buf->st_mtime) );
89  printf( "....ctime = %s", ctime(&buf->st_ctime) );
90
91#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
92  printf( "....st_blksize %x\n", buf.st_blksize );
93  printf( "....st_blocks  %x\n", buf.st_blocks );
94#endif
95
96}
97
98void stat_a_file(
99  const char *file
100)
101{
102  int         status;
103  struct stat statbuf;
104
105  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/*
123 *  Main entry point of the test
124 */
125
126#if defined(__rtems__)
127int test_main(void)
128#else
129int main(
130  int argc,
131  char **argv
132)
133#endif
134{
135  int               status;
136  int               max_size;
137  int               fd;
138  int               i;
139  struct stat       buf;
140  char              buffer[128];
141  FILE             *file;
142  time_t            atime1;
143  time_t            mtime1;
144  time_t            ctime1;
145  time_t            atime2;
146  time_t            mtime2;
147  time_t            ctime2;
148  rtems_status_code rtems_status;
149  rtems_time_of_day time;
150
151  printf( "\n\n*** FILE TEST 1 ***\n" );
152
153  /*
154   *  Grab the maximum size of an in-memory file.
155   */
156
157  max_size = IMFS_memfile_maximum_size();
158
159  build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
160  rtems_status = rtems_clock_set( &time );
161
162  /*
163   *  Dump an empty file system
164   */
165
166  IMFS_dump();
167
168  /*
169   *  Simple stat() of /dev/console.
170   */
171
172  puts( "stat of /dev/console" );
173  status = stat( "/dev/console", &buf );
174  assert( !status );
175
176  dump_statbuf( &buf );
177
178  /*
179   *  Exercise mkdir() and some path evaluation.
180   */
181
182  puts( "" );
183  puts( "mkdir /dev/tty" );
184  status = mkdir( "/dev/tty", S_IRWXU );
185  assert( !status );
186
187  puts( "" );
188  puts( "mkdir /usr" );
189  status = mkdir( "/usr", S_IRWXU );
190  assert( !status );
191  puts( "mkdir /etc" );
192  status = mkdir( "/etc", S_IRWXU );
193  assert( !status );
194
195  puts( "mkdir /tmp" );
196  status = mkdir( "/tmp", S_IRWXU );
197  assert( !status );
198
199  /* this tests the ".." path in path name evaluation */
200  puts( "mkdir /tmp/.." );
201  status = mkdir( "/tmp/..", S_IRWXU );
202  assert( status == -1 );
203  assert( errno == EEXIST );
204
205  /* now check out trailing separators */
206  puts( "mkdir /tmp/" );
207  status = mkdir( "/tmp/", S_IRWXU );
208  assert( status == -1 );
209  assert( errno == EEXIST );
210
211  /* try to make a directory under a non-existent subdirectory */
212  puts( "mkdir /j/j1" );
213  status = mkdir( "/j/j1", S_IRWXU );
214  assert( status == -1 );
215  assert( errno == ENOENT );
216
217  /* this tests the ability to make a directory in the current one */
218  puts( "mkdir tmp" );
219  status = mkdir( "tmp", S_IRWXU );
220  assert( status == -1 );
221  assert( errno == EEXIST );
222
223  /* test rtems_filesystem_evaluate_path by sending NULL path */
224  status = chdir( NULL );
225  assert( status == -1 );
226
227  /*
228   *  Now switch gears and exercise rmdir().
229   */
230
231  puts( "" );
232  puts( "rmdir /usr" );
233  status = rmdir( "/usr" );
234  assert( !status );
235
236  puts( "rmdir /dev" );
237  status = rmdir( "/dev" );
238  assert( status == -1 );
239  assert( errno ==  ENOTEMPTY);
240
241  puts( "rmdir /fred" );
242  status = rmdir ("/fred");
243  assert (status == -1);
244  assert( errno == ENOENT );
245
246  puts( "mknod /dev/test_console" );
247  status = mknod( "/dev/test_console", S_IFCHR, 0LL );
248  assert( !status );
249
250  puts( "mknod /dev/tty/S3" );
251  status = mknod( "/dev/tty/S3", S_IFCHR, 0xFF00000080LL );
252  assert( !status );
253
254  puts ("mknod /etc/passwd");
255  status = mknod( "/etc/passwd", (S_IFREG | S_IRWXU), 0LL );
256  assert( !status );
257
258  puts( "mkdir /tmp/my_dir");
259  status = mkdir( "/tmp/my_dir", S_IRWXU );
260  assert( status == 0 );
261
262  puts("mkfifo /c/my_dir" );
263  status = mkfifo( "/c/my_dir", S_IRWXU );
264  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  assert( status == -1 );
273  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  assert( fd == -1 );
282  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  assert( fd != -1 );
291  printf( "open returned file descriptor %d\n", fd );
292
293  puts( "close /tmp/j" );
294  status = close( fd );
295  assert( !status );
296
297  puts( "close /tmp/j again" );
298  status = close( fd );
299  assert( status == -1 );
300
301  puts( "unlink /tmp/j" );
302  status = unlink( "/tmp/j" );
303  assert( !status );
304
305  puts( "unlink /tmp" );
306  status = unlink( "/tmp" );
307  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  assert( fd != -1 );
316  status = close( fd );
317  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  assert( fd == -1 );
322  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  assert( fd != -1 );
327
328  puts("tcdrain /tmp/john" );
329  status = tcdrain( fd );
330  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  /*
342   *  Test simple write to a file at a non-0 offset in the first block
343   */
344
345  status = unlink( "/tmp/joel" );
346  assert( !status );
347
348  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
349  assert( !status );
350
351  test_write( "/tmp/joel", 10, "the first write!!!\n" );
352  test_cat( "/tmp/joel", 0, 0 );
353  stat_a_file( "/tmp/joel" );
354
355  /*
356   *  Test simple write to a file at a non-0 offset in the second block.  Then
357   *  try to read from various offsets and lengths.
358   */
359
360  puts("unlink /tmp/joel");
361  status = unlink( "/tmp/joel" );
362  assert( !status );
363
364  /* Test a failure path */
365
366  puts( "unlink /tmp/joel" );
367  status = unlink( "/tmp/joel" );
368  assert( status == -1 );
369
370  puts( "mknod /tmp/joel");
371  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
372  assert( !status );
373
374  test_write( "/tmp/joel", 514, "the first write!!!\n" );
375  test_write( "/tmp/joel", 1, test_write_buffer );
376  test_write( "/tmp/joel", 63, test_write_buffer );
377  test_cat( "/tmp/joel", 0, 1 );
378  test_cat( "/tmp/joel", 1, 1 );
379  test_cat( "/tmp/joel", 490, 1 );
380  test_cat( "/tmp/joel", 512, 1 );
381  test_cat( "/tmp/joel", 513, 1 );
382  test_cat( "/tmp/joel", 514, 1 );
383  test_cat( "/tmp/joel", 520, 1 );
384  test_cat( "/tmp/joel", 1, 1024 );
385
386  /*
387   *  Read from a much longer file so we can descend into doubly and
388   *  triply indirect blocks.
389   */
390
391  if ( max_size < 300 * 1024 ) {
392    test_extend( "/tmp/joel", max_size - 1 );
393    test_cat( "/tmp/joel", max_size / 2, 1024 );
394  } else {
395    printf( "Skipping maximum file size test since max_size is %d bytes\n", max_size );
396    puts("That is likely to be bigger than the available RAM on many targets." );
397  }
398
399  stat_a_file( "/tmp/joel" );
400
401  /*
402   *  Now try to use a FILE * descriptor
403   *
404   *  /tmp/j should not exist at this point.
405   */
406
407  puts( "stat of /tmp/j" );
408  errno = 0;
409  status = stat( "/tmp/j", &buf );
410  printf( "stat(/tmp/j) returned %d (errno=%d)\n", status, errno );
411  dump_statbuf( &buf );
412
413  puts( "fopen of /tmp/j" );
414  file = fopen( "/tmp/j", "w+" );
415  assert( file );
416
417  puts( "fprintf to /tmp/j" );
418  for (i=1 ; i<=5 ; i++) {
419    status = fprintf( file, "This is call %d to fprintf\n", i );
420    assert( status );
421    printf( "(%d) %d characters written to the file\n", i, status );
422  }
423
424  fflush( file );
425
426  status = stat( "/tmp/j", &buf );
427  assert( !status );
428  dump_statbuf( &buf );
429  atime2 = buf.st_atime;
430  mtime2 = buf.st_mtime;
431  ctime2 = buf.st_ctime;
432
433
434  status = rtems_task_wake_after( 1 * TICKS_PER_SECOND );
435  rewind( file );
436  while ( fgets(buffer, 128, file) )
437    printf( "%s", buffer );
438
439  /*
440   * Verify only atime changed for a read.
441   */
442  status = stat( "/tmp/j", &buf );
443  assert( !status );
444  dump_statbuf( &buf );
445  atime1 = buf.st_atime;
446  mtime1 = buf.st_mtime;
447  ctime1 = buf.st_ctime;
448  assert( atime1 != atime2);
449  assert( mtime1 == mtime2);
450  assert( ctime1 == ctime2);
451
452  IMFS_dump();
453
454  unlink( "/tmp/joel" );
455
456  /*
457   *  Now truncate a file
458   */
459
460  status = rtems_task_wake_after( 1 * TICKS_PER_SECOND );
461  puts( "truncate /tmp/j to length of 40" );
462  status = truncate( "/tmp/j", 40 );
463  assert( !status );
464
465  /*
466   * Verify truncate changed only atime.
467   */
468  status = stat( "/tmp/j", &buf );
469  assert( !status );
470  dump_statbuf( &buf );
471  atime2 = buf.st_atime;
472  mtime2 = buf.st_mtime;
473  ctime2 = buf.st_ctime;
474  assert( atime1 != atime2);
475  assert( mtime1 == mtime2);
476  assert( ctime1 == ctime2);
477
478  IMFS_dump();
479
480  /* try to truncate the console and see what happens */
481  status = truncate( "/dev/console", 40 );
482  assert(status == -1 );
483
484  puts( "truncate /tmp/j to length of 0" );
485  status = truncate( "/tmp/j", 0 );
486  assert( !status );
487
488  puts( "truncate /tmp to length of 0 should fail with EISDIR\n");
489  status = truncate( "/tmp", 0 );
490  assert( status == -1 );
491  printf( "%d: %s\n", errno, strerror( errno ) );
492  assert( errno == EISDIR );
493
494  IMFS_dump();
495
496  status = truncate( "/tmp/fred", 10 );
497  assert( status == -1);
498
499  rtems_status = rtems_io_register_name( "/dev/console", 0, 0 );
500
501  printf( "*** END OF FILE TEST 1 ***\n" );
502  exit( 0 );
503}
504
505
Note: See TracBrowser for help on using the repository browser.