source: rtems/testsuites/psxtests/psxfile01/test.c @ 78edd44

4.104.114.84.95
Last change on this file since 78edd44 was 78edd44, checked in by Joel Sherrill <joel.sherrill@…>, on 11/02/99 at 16:38:19

Minor fixes to make screen match a bit better.

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