source: rtems/c/src/tests/psxtests/psxfile01/test.c @ 3f06c298

4.104.114.84.95
Last change on this file since 3f06c298 was 3f06c298, checked in by Jennifer Averett <Jennifer.Averett@…>, on Mar 31, 1999 at 11:22:42 PM

Added prints for calls into the file system. Added O_EXCL for an open that
tested that the same file could not be created twice.

  • Property mode set to 100644
File size: 11.0 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\n", 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    dump_statbuf( &statbuf );
116  }
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  int               max_size;
136  int               fd, fd1;
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  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  assert( !status );
185
186  puts( "" );
187  puts( "mkdir /usr" );
188  status = mkdir( "/usr", S_IRWXU );
189  assert( !status );
190  puts( "mkdir /etc" );
191  status = mkdir( "/etc", S_IRWXU );
192  assert( !status );
193
194  puts( "mkdir /tmp" );
195  status = mkdir( "/tmp", S_IRWXU );
196  assert( !status );
197
198  /* this tests the ".." path in path name evaluation */
199  puts( "mkdir /tmp/.." );
200  status = mkdir( "/tmp/..", S_IRWXU );
201  assert( status == -1 );
202  assert( errno == EEXIST );
203
204  /* now check out trailing separators */
205  puts( "mkdir /tmp/" );
206  status = mkdir( "/tmp/", S_IRWXU );
207  assert( status == -1 );
208  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  assert( status == -1 );
214  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  assert( status == -1 );
220  assert( errno == EEXIST );
221
222  /* test rtems_filesystem_evaluate_path by sending NULL path */
223  status = chdir( NULL );
224  assert( status == -1 );
225
226  /*
227   *  Now switch gears and exercise rmdir().
228   */
229
230  puts( "" );
231  puts( "rmdir /usr" );
232  status = rmdir( "/usr" );
233  assert( !status );
234
235  puts( "rmdir /dev" );
236  status = rmdir( "/dev" );
237  assert( status == -1 );
238  assert( errno ==  ENOTEMPTY);
239
240  puts( "rmdir /fred" );
241  status = rmdir ("/fred");
242  assert (status == -1);
243  assert( errno == ENOENT );
244
245  puts( "mknod /dev/test_console" );
246  status = mknod( "/dev/test_console", S_IFCHR, 0LL );
247  assert( !status );
248
249  puts( "mknod /dev/tty/S3" );
250  status = mknod( "/dev/tty/S3", S_IFCHR, 0xFF00000080LL );
251  assert( !status );
252
253  puts ("mknod /etc/passwd");
254  status = mknod( "/etc/passwd", (S_IFREG | S_IRWXU), 0LL );
255  assert( !status );
256
257  puts( "mkdir /tmp/my_dir");
258  status = mkdir( "/tmp/my_dir", S_IRWXU );
259  assert( status == 0 );
260
261  puts("mkfifo /c/my_dir" );
262  status = mkfifo( "/c/my_dir", S_IRWXU );
263  assert( status == -1 );
264
265  /*
266   *  Try to make a directory under a file -- ERROR
267   */
268
269  puts( "mkdir /etc/passwd/j" );
270  status = mkdir( "/etc/passwd/j", S_IRWXU );
271  assert( status == -1 );
272  assert( errno == ENOTDIR );
273
274  /*
275   *  Simple open failure case on non-existent file
276   */
277
278  puts( "open /tmp/joel - should fail with ENOENT" );
279  fd = open( "/tmp/joel", O_RDONLY );
280  assert( fd == -1 );
281  assert( errno == ENOENT );
282
283  /*
284   *  Simple open case where the file is created.
285   */
286
287  puts( "open /tmp/j" );
288  fd = open( "/tmp/j", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
289  assert( fd != -1 );
290  printf( "open returned file descriptor %d\n", fd );
291
292  puts( "close /tmp/j" );
293  status = close( fd );
294  assert( !status );
295
296  puts( "close /tmp/j again" );
297  status = close( fd );
298  assert( status == -1 );
299
300  puts( "unlink /tmp/j" );
301  status = unlink( "/tmp/j" );
302  assert( !status );
303
304  puts( "unlink /tmp" );
305  status = unlink( "/tmp" );
306  assert( status );
307
308  /*
309   *  Simple open failure. Trying to create an existing file.
310   */
311
312  puts("create and close /tmp/tom");
313  fd = open( "/tmp/tom", O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
314  assert( fd != -1 );
315  status = close( fd );
316  assert( status == 0 );
317
318  puts("Attempt to recreate /tmp/tom");
319  fd = open( "/tmp/tom", O_CREAT | O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO );
320  assert( fd == -1 );
321  assert( errno == EEXIST );
322
323  puts("create /tmp/john");
324  fd = open( "/tmp/john", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
325  assert( fd != -1 );
326
327  puts("tcdrain /tmp/john" );
328  status = tcdrain( fd );
329  assert( status == 0 );
330
331  /*
332   *  Test simple write to a file at offset 0
333   */
334
335  puts( "mknod /tmp/joel" );
336  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
337  test_write( "/tmp/joel", 0, "the first write!!!\n" );
338  test_cat( "/tmp/joel", 0, 0 );
339
340  /*
341   *  Test simple write to a file at a non-0 offset in the first block
342   */
343
344  status = unlink( "/tmp/joel" );
345  assert( !status );
346
347  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
348  assert( !status );
349
350  test_write( "/tmp/joel", 10, "the first write!!!\n" );
351  test_cat( "/tmp/joel", 0, 0 );
352  stat_a_file( "/tmp/joel" );
353
354  /*
355   *  Test simple write to a file at a non-0 offset in the second block.  Then
356   *  try to read from various offsets and lengths.
357   */
358
359  puts("unlink /tmp/joel");
360  status = unlink( "/tmp/joel" );
361  assert( !status );
362
363  /* Test a failure path */
364
365  puts( "unlink /tmp/joel" );
366  status = unlink( "/tmp/joel" );
367  assert( status == -1 );
368
369  puts( "mknod /tmp/joel");
370  status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
371  assert( !status );
372
373  test_write( "/tmp/joel", 514, "the first write!!!\n" );
374  test_write( "/tmp/joel", 1, test_write_buffer );
375  test_write( "/tmp/joel", 63, test_write_buffer );
376  test_cat( "/tmp/joel", 0, 1 );
377  test_cat( "/tmp/joel", 1, 1 );
378  test_cat( "/tmp/joel", 490, 1 );
379  test_cat( "/tmp/joel", 512, 1 );
380  test_cat( "/tmp/joel", 513, 1 );
381  test_cat( "/tmp/joel", 514, 1 );
382  test_cat( "/tmp/joel", 520, 1 );
383  test_cat( "/tmp/joel", 1, 1024 );
384
385  /*
386   *  Read from a much longer file so we can descend into doubly and
387   *  triply indirect blocks.
388   */
389
390  test_extend( "/tmp/joel", max_size - 1 );
391  test_cat( "/tmp/joel", max_size / 2, 1024 );
392
393  stat_a_file( "/tmp/joel" );
394
395  /*
396   *  Now try to use a FILE * descriptor
397   *
398   *  /tmp/j should not exist at this point.
399   */
400
401  puts( "stat of /tmp/j" );
402  errno = 0;
403  status = stat( "/tmp/j", &buf );
404  printf( "stat(/tmp/j) returned %d (errno=%d)\n", status, errno );
405  dump_statbuf( &buf );
406
407  puts( "fopen of /tmp/j" );
408  file = fopen( "/tmp/j", "w+" );
409  assert( file );
410
411  puts( "fprintf to /tmp/j" );
412  for (i=1 ; i<=5 ; i++) {
413    status = fprintf( file, "This is call %d to fprintf\n", i );
414    assert( status );
415    printf( "(%d) %d characters written to the file\n", i, status );
416  }
417
418  fflush( file );
419
420  status = stat( "/tmp/j", &buf );
421  assert( !status );
422  dump_statbuf( &buf );
423  atime2 = buf.st_atime;
424  mtime2 = buf.st_mtime;
425  ctime2 = buf.st_ctime;
426
427
428  status = rtems_task_wake_after( 1 * TICKS_PER_SECOND );
429  rewind( file );
430  while ( fgets(buffer, 128, file) )
431    printf( buffer );
432
433  /*
434   * Verify only atime changed for a read.
435   */
436  status = stat( "/tmp/j", &buf );
437  assert( !status );
438  dump_statbuf( &buf );
439  atime1 = buf.st_atime;
440  mtime1 = buf.st_mtime;
441  ctime1 = buf.st_ctime;
442  assert( atime1 != atime2);
443  assert( mtime1 == mtime2);
444  assert( ctime1 == ctime2);
445
446  IMFS_dump();
447
448  unlink( "/tmp/joel" );
449
450  /*
451   *  Now truncate a file
452   */
453
454  status = rtems_task_wake_after( 1 * TICKS_PER_SECOND );
455  puts( "truncate /tmp/j to length of 40" );
456  status = truncate( "/tmp/j", 40 );
457  assert( !status );
458
459  /*
460   * Verify truncate changed only atime.
461   */
462  status = stat( "/tmp/j", &buf );
463  assert( !status );
464  dump_statbuf( &buf );
465  atime2 = buf.st_atime;
466  mtime2 = buf.st_mtime;
467  ctime2 = buf.st_ctime;
468  assert( atime1 != atime2);
469  assert( mtime1 == mtime2);
470  assert( ctime1 == ctime2);
471
472  IMFS_dump();
473
474  /* try to truncate the console and see what happens */
475  status = truncate( "/dev/console", 40 );
476  assert(status == -1 );
477
478  puts( "truncate /tmp/j to length of 0" );
479  status = truncate( "/tmp/j", 0 );
480  assert( !status );
481
482  puts( "truncate /tmp to length of 0 should fail with EISDIR\n");
483  status = truncate( "/tmp", 0 );
484  assert( status == -1 );
485  printf( "%d: %s\n", errno, strerror( errno ) );
486  assert( errno == EISDIR );
487
488  IMFS_dump();
489
490  status = truncate( "/tmp/fred", 10 );
491  assert( status == -1);
492
493  rtems_status = rtems_io_register_name( "/dev/console", 0, 0 );
494
495  printf( "*** END OF FILE TEST 1 ***\n" );
496  exit( 0 );
497}
498
499
Note: See TracBrowser for help on using the repository browser.