Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:37

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  Simple test program to exercise some of the basic functionality of
0007  *  POSIX Files and Directories Support.
0008  *
0009  *  This test assumes that the file system is initialized with the
0010  *  following directory structure:
0011  *
0012  *  XXXX fill this in.
0013  *    /
0014  *    /dev
0015  *    /dev/XXX   [where XXX includes at least console]
0016  */
0017 
0018 /*
0019  *  COPYRIGHT (c) 1989-2012.
0020  *  On-Line Applications Research Corporation (OAR).
0021  *
0022  * Redistribution and use in source and binary forms, with or without
0023  * modification, are permitted provided that the following conditions
0024  * are met:
0025  * 1. Redistributions of source code must retain the above copyright
0026  *    notice, this list of conditions and the following disclaimer.
0027  * 2. Redistributions in binary form must reproduce the above copyright
0028  *    notice, this list of conditions and the following disclaimer in the
0029  *    documentation and/or other materials provided with the distribution.
0030  *
0031  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0032  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0033  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0034  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0035  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0036  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0037  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0038  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0039  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0040  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0041  * POSSIBILITY OF SUCH DAMAGE.
0042  */
0043 
0044 #ifdef HAVE_CONFIG_H
0045 #include "config.h"
0046 #endif
0047 
0048 #include <stdio.h>
0049 
0050 #include <pmacros.h>
0051 #include <sys/types.h>
0052 #include <sys/stat.h>
0053 #include <fcntl.h>
0054 #include <unistd.h>
0055 #include <errno.h>
0056 #include <string.h>
0057 #include <inttypes.h>
0058 #include <ctype.h>
0059 #include <reent.h>
0060 #include <rtems/imfs.h>
0061 
0062 #include <rtems.h>
0063 #include <rtems/libio.h>
0064 
0065 #include "primode.h"
0066 
0067 const char rtems_test_name[] = "PSXFILE 1";
0068 
0069 /* forward declarations to avoid warnings */
0070 void test_case_reopen_append(void);
0071 void dump_statbuf(struct stat *buf);
0072 void stat_a_file(const char *file);
0073 int test_main(void);
0074 
0075 char test_write_buffer[ 1024 ];
0076 rtems_filesystem_operations_table  IMFS_ops_no_evalformake;
0077 rtems_filesystem_operations_table  IMFS_ops_no_rename;
0078 
0079 static const char somefile[] = "somefile";
0080 
0081 static const char somelink[] = "somelink";
0082 
0083 /*
0084  *  File test support routines.
0085  */
0086 
0087 void test_cat(
0088   char *file,
0089   int   offset_arg,
0090   int   length
0091 );
0092 
0093 void test_write(
0094   char   *file,
0095   off_t  offset,
0096   char  *buffer
0097 );
0098 
0099 void test_extend(
0100   char *file,
0101   off_t new_len
0102 );
0103 
0104 /*
0105  *  dump_statbuf
0106  */
0107 void dump_statbuf( struct stat *buf )
0108 {
0109   rtems_device_major_number major1;
0110   rtems_device_minor_number minor1;
0111   rtems_device_major_number major2;
0112   rtems_device_minor_number minor2;
0113 
0114   rtems_filesystem_split_dev_t( buf->st_dev, major1, minor1 );
0115   rtems_filesystem_split_dev_t( buf->st_rdev, major2, minor2 );
0116 
0117   printf( "....st_dev     (0x%" PRIx32 ":0x%" PRIx32 ")\n", major1, minor1 );
0118   printf( "....st_rdev    (0x%" PRIx32 ":0x%" PRIx32 ")\n", major2, minor2 );
0119   printf( "....st_ino     %" PRIxino_t "  may vary by small amount\n", buf->st_ino );
0120   printf( "....mode  = %08" PRIomode_t "\n", buf->st_mode );
0121   printf( "....nlink = %d\n", buf->st_nlink );
0122 
0123   printf( "....uid = %d\n", buf->st_uid );
0124   printf( "....gid = %d\n", buf->st_gid );
0125 
0126   printf( "....atime = %s", ctime(&buf->st_atime) );
0127   printf( "....mtime = %s", ctime(&buf->st_mtime) );
0128   printf( "....ctime = %s", ctime(&buf->st_ctime) );
0129 
0130   printf( "....st_blksize %" PRIxblksize_t "\n", buf->st_blksize );
0131   printf( "....st_blocks  %" PRIxblkcnt_t "\n", buf->st_blocks );
0132 }
0133 
0134 void stat_a_file(
0135   const char *file
0136 )
0137 {
0138   int         status;
0139   struct stat statbuf;
0140 
0141   rtems_test_assert( file );
0142 
0143   printf( "stat( %s ) returned ", file );
0144 
0145   status = stat( file, &statbuf );
0146 
0147   if ( status == -1 ) {
0148     printf( ": %s\n", strerror( errno ) );
0149   } else {
0150     puts("");
0151     dump_statbuf( &statbuf );
0152   }
0153 
0154 }
0155 
0156 static void test_open_directory(void)
0157 {
0158   int status;
0159   int fd;
0160 
0161   fd = open( somefile, O_CREAT, S_IRWXU );
0162   rtems_test_assert( fd >= 0 );
0163 
0164   status = close( fd );
0165   rtems_test_assert( status == 0 );
0166 
0167 #ifdef O_DIRECTORY
0168   errno = 0;
0169   fd = open( somefile, O_DIRECTORY, S_IRWXU );
0170   rtems_test_assert( fd == -1 );
0171   rtems_test_assert( errno == ENOTDIR );
0172 #endif
0173 
0174   status = unlink( somefile );
0175   rtems_test_assert( status == 0 );
0176 
0177   errno = 0;
0178   fd = open( somefile, O_RDONLY );
0179   rtems_test_assert( fd == -1 );
0180   rtems_test_assert( errno == ENOENT );
0181 }
0182 
0183 static void test_open_cloexec(void)
0184 {
0185   int status;
0186   int fd;
0187   mode_t mode;
0188 
0189   mode = O_CREAT;
0190 
0191 #ifdef O_CLOEXEC
0192   mode |= O_CLOEXEC;
0193 #endif
0194 
0195   fd = open( somefile, mode, S_IRWXU );
0196   rtems_test_assert( fd >= 0 );
0197 
0198   status = close( fd );
0199   rtems_test_assert( status == 0 );
0200 
0201   status = unlink( somefile );
0202   rtems_test_assert( status == 0 );
0203 
0204   errno = 0;
0205   fd = open( somefile, O_RDONLY );
0206   rtems_test_assert( fd == -1 );
0207   rtems_test_assert( errno == ENOENT );
0208 }
0209 
0210 static void test_open_nofollow(void)
0211 {
0212   int status;
0213   int fd;
0214   struct stat st;
0215 
0216   fd = open( somefile, O_CREAT, S_IRWXU );
0217   rtems_test_assert( fd >= 0 );
0218 
0219   status = close( fd );
0220   rtems_test_assert( status == 0 );
0221 
0222   status = symlink( somefile, somelink );
0223   rtems_test_assert( status == 0 );
0224 
0225   fd = open( somelink, O_RDONLY );
0226   rtems_test_assert( fd >= 0 );
0227 
0228   status = fstat( fd, &st );
0229   rtems_test_assert( status == 0 );
0230   rtems_test_assert( S_ISREG( st.st_mode ) );
0231 
0232   status = close( fd );
0233   rtems_test_assert( status == 0 );
0234 
0235 #ifdef O_NOFOLLOW
0236   fd = open( somelink, O_RDONLY | O_NOFOLLOW );
0237   rtems_test_assert( fd >= 0 );
0238 
0239   status = fstat( fd, &st );
0240   rtems_test_assert( status == 0 );
0241   rtems_test_assert( S_ISLNK( st.st_mode ) );
0242 
0243   status = close( fd );
0244   rtems_test_assert( status == 0 );
0245 #endif
0246 
0247   status = unlink( somelink );
0248   rtems_test_assert( status == 0 );
0249 
0250   errno = 0;
0251   fd = open( somelink, O_RDONLY );
0252   rtems_test_assert( fd == -1 );
0253   rtems_test_assert( errno == ENOENT );
0254 
0255   status = unlink( somefile );
0256   rtems_test_assert( status == 0 );
0257 
0258   errno = 0;
0259   fd = open( somefile, O_RDONLY );
0260   rtems_test_assert( fd == -1 );
0261   rtems_test_assert( errno == ENOENT );
0262 }
0263 
0264 /*
0265  *  Main entry point of the test
0266  */
0267 
0268 #if defined(__rtems__)
0269 int test_main(void)
0270 #else
0271 int main(
0272   int argc,
0273   char **argv
0274 )
0275 #endif
0276 {
0277   int               status;
0278   size_t            max_size;
0279   int               fd;
0280   int               i;
0281   struct stat       buf;
0282   char              buffer[128];
0283   FILE             *file;
0284   time_t            atime1;
0285   time_t            mtime1;
0286   time_t            ctime1;
0287   time_t            atime2;
0288   time_t            mtime2;
0289   time_t            ctime2;
0290   rtems_status_code rtems_status;
0291   rtems_time_of_day time;
0292 
0293   TEST_BEGIN();
0294 
0295   test_open_directory();
0296   test_open_cloexec();
0297   test_open_nofollow();
0298 
0299   /*
0300    *  Grab the maximum size of an in-memory file.
0301    */
0302 
0303   max_size = IMFS_MEMFILE_MAXIMUM_SIZE;
0304 
0305   build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
0306   rtems_status = rtems_clock_set( &time );
0307   directive_failed( rtems_status, "clock set" );
0308 
0309   /*
0310    *  Simple stat() of /dev/console.
0311    */
0312 
0313   puts( "stat of /dev/console" );
0314   status = stat( "/dev/console", &buf );
0315   rtems_test_assert( !status );
0316 
0317   dump_statbuf( &buf );
0318 
0319   /*
0320    *  Exercise mkdir() and some path evaluation.
0321    */
0322 
0323   puts( "" );
0324   puts( "mkdir /dev/tty" );
0325   status = mkdir( "/dev/tty", S_IRWXU );
0326   rtems_test_assert( !status );
0327 
0328   puts( "" );
0329   puts( "mkdir /usr" );
0330   status = mkdir( "/usr", S_IRWXU );
0331   rtems_test_assert( !status );
0332   puts( "mkdir /etc" );
0333   status = mkdir( "/etc", S_IRWXU );
0334   rtems_test_assert( !status );
0335 
0336   puts( "mkdir /tmp" );
0337   status = mkdir( "/tmp", S_IRWXU );
0338   rtems_test_assert( !status );
0339 
0340   /* this tests the ".." path in path name evaluation */
0341   puts( "mkdir /tmp/.." );
0342   status = mkdir( "/tmp/..", S_IRWXU );
0343   rtems_test_assert( status == -1 );
0344   rtems_test_assert( errno == EEXIST );
0345 
0346   /* now check out trailing separators */
0347   puts( "mkdir /tmp/" );
0348   status = mkdir( "/tmp/", S_IRWXU );
0349   rtems_test_assert( status == -1 );
0350   rtems_test_assert( errno == EEXIST );
0351 
0352   /* try to make a directory under a non-existent subdirectory */
0353   puts( "mkdir /j/j1" );
0354   status = mkdir( "/j/j1", S_IRWXU );
0355   rtems_test_assert( status == -1 );
0356   rtems_test_assert( errno == ENOENT );
0357 
0358   /* this tests the ability to make a directory in the current one */
0359   puts( "mkdir tmp" );
0360   status = mkdir( "tmp", S_IRWXU );
0361   rtems_test_assert( status == -1 );
0362   rtems_test_assert( errno == EEXIST );
0363 
0364   /*
0365    *  Now switch gears and exercise rmdir().
0366    */
0367 
0368   puts( "" );
0369   puts( "rmdir /usr" );
0370   status = rmdir( "/usr" );
0371   rtems_test_assert( !status );
0372 
0373   puts( "rmdir /dev" );
0374   status = rmdir( "/dev" );
0375   rtems_test_assert( status == -1 );
0376   rtems_test_assert( errno ==  ENOTEMPTY);
0377 
0378   puts( "rmdir /fred" );
0379   status = rmdir ("/fred");
0380   rtems_test_assert (status == -1);
0381   rtems_test_assert( errno == ENOENT );
0382 
0383   puts( "rmdir /tmp/bha" );
0384   status = rmdir( "/tmp/bha" );
0385   rtems_test_assert( status == -1 );
0386   rtems_test_assert( errno == ENOENT );
0387 
0388   puts( "mknod /dev/test_console" );
0389   status = mknod( "/dev/test_console", S_IFCHR, 0LL );
0390   rtems_test_assert( !status );
0391 
0392   puts( "mknod /dev/tty/S3" );
0393   status = mknod( "/dev/tty/S3", S_IFCHR, 0xFF00000080LL );
0394   rtems_test_assert( !status );
0395 
0396   puts ("mknod /etc/passwd");
0397   status = mknod( "/etc/passwd", (S_IFREG | S_IRWXU), 0LL );
0398   rtems_test_assert( !status );
0399 
0400   puts( "mkdir /tmp/my_dir");
0401   status = mkdir( "/tmp/my_dir", S_IRWXU );
0402   rtems_test_assert( status == 0 );
0403 
0404   puts("mkfifo /c/my_dir" );
0405   status = mkfifo( "/c/my_dir", S_IRWXU );
0406   rtems_test_assert( status == -1 );
0407 
0408   /*
0409    *  Try to make a directory under a file -- ERROR
0410    */
0411 
0412   puts( "mkdir /etc/passwd/j" );
0413   status = mkdir( "/etc/passwd/j", S_IRWXU );
0414   rtems_test_assert( status == -1 );
0415   rtems_test_assert( errno == ENOTDIR );
0416 
0417   /*
0418    *  Simple open failure case on non-existent file
0419    */
0420 
0421   puts( "open /tmp/joel - should fail with ENOENT" );
0422   fd = open( "/tmp/joel", O_RDONLY );
0423   rtems_test_assert( fd == -1 );
0424   rtems_test_assert( errno == ENOENT );
0425 
0426   /*
0427    *  Simple open case where the file is created.
0428    */
0429 
0430   puts( "open /tmp/j" );
0431   fd = open( "/tmp/j", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
0432   rtems_test_assert( fd != -1 );
0433   printf( "open returned file descriptor %d\n", fd );
0434 
0435   puts( "close /tmp/j" );
0436   status = close( fd );
0437   rtems_test_assert( !status );
0438 
0439   puts( "close /tmp/j again" );
0440   status = close( fd );
0441   rtems_test_assert( status == -1 );
0442 
0443   puts( "unlink /tmp/j" );
0444   status = unlink( "/tmp/j" );
0445   rtems_test_assert( !status );
0446 
0447   puts( "unlink /tmp" );
0448   status = unlink( "/tmp" );
0449   rtems_test_assert( status );
0450 
0451   /*
0452    *  Simple open failure. Trying to create an existing file.
0453    */
0454 
0455   puts("create and close /tmp/tom");
0456   fd = open( "/tmp/tom", O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
0457   rtems_test_assert( fd != -1 );
0458   status = close( fd );
0459   rtems_test_assert( status == 0 );
0460 
0461   puts("Attempt to recreate /tmp/tom");
0462   fd = open( "/tmp/tom", O_CREAT | O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO );
0463   rtems_test_assert( fd == -1 );
0464   rtems_test_assert( errno == EEXIST );
0465 
0466   puts("create /tmp/john");
0467   fd = open( "/tmp/john", O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO );
0468   rtems_test_assert( fd != -1 );
0469   status = close( fd );
0470   rtems_test_assert( status == 0 );
0471 
0472   /*
0473    * Open a file in read-only mode and try to truncate
0474    */
0475 
0476   puts( "Attempt to create a file, open in read-only mode and truncate it" );
0477   fd = open( "/tmp/bha", O_CREAT | O_RDONLY | O_TRUNC, S_IRUSR );
0478   rtems_test_assert( fd == -1 );
0479   rtems_test_assert( errno == EINVAL );
0480 
0481   puts( "Exercise the reentrant version _link_r -- Expect ENOENT" );
0482   status = _link_r( NULL, "/tmp/notexist", "/tmp/cannotexist" );
0483   rtems_test_assert( status == -1 );
0484   rtems_test_assert( errno == ENOENT );
0485 
0486   puts( "Unlink /tmp/bha using the reentrant version -- OK" );
0487   status = _unlink_r( NULL, "/tmp/bha" );
0488   rtems_test_assert( status == 0 );
0489 
0490   /*
0491    * Simple test case for mknod
0492    */
0493 
0494   puts( "mknod with bad type - expect EINVAL" );
0495   status = mknod( "/tmp/bha", 0, 0LL );
0496   rtems_test_assert( status == -1 );
0497   rtems_test_assert( errno == EINVAL );
0498 
0499   /*
0500    * Read from filedes opened for write
0501    */
0502 
0503   puts( "open /tmp/bha in write only mode -- OK" );
0504   fd = open( "/tmp/bha", O_CREAT | O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO );
0505   rtems_test_assert( fd != -1 );
0506 
0507   puts( "attempt fcntl on opened file -- OK" );
0508   status = fcntl( fd, F_SETFD, 0 );
0509   rtems_test_assert( status == 0 );
0510 
0511   puts( "attempt to read from /tmp/bha - expect EBADF" );
0512   status = read( fd, buffer, 10 );
0513   rtems_test_assert( status == -1 );
0514   rtems_test_assert( errno == EBADF );
0515 
0516   puts( "closing and unlinking /tmp/bha" );
0517   status = close( fd );
0518   status |= unlink( "/tmp/bha" );
0519   rtems_test_assert( status == 0 );
0520 
0521   puts( "open /tmp/bha in read only mode -- OK" );
0522   fd = open( "/tmp/bha", O_CREAT | O_RDONLY, S_IRWXU|S_IRWXG|S_IRWXO );
0523   rtems_test_assert( fd != -1 );
0524 
0525   puts( "attempt to read from /tmp/bha - expect EBADF" );
0526   status = write( fd, buffer, 10 );
0527   rtems_test_assert( status == -1 );
0528   rtems_test_assert( errno == EBADF );
0529 
0530   puts( "closing and unlinking /tmp/bha" );
0531   status = close( fd );
0532   status |= unlink( "/tmp/bha" );
0533   rtems_test_assert( status == 0 );
0534 
0535   /*
0536    * Read/write from an unopened filedes
0537    */
0538   puts( "attempt to read from an unopened filedes - expect EBADF" );
0539   status = read( 5, buffer, 10 );
0540   rtems_test_assert( status == -1 );
0541   rtems_test_assert( errno == EBADF );
0542 
0543   puts( "attempt to write to an unopened filedes - expect EBADF" );
0544   status = write( 5, buffer, 10 );
0545   rtems_test_assert( status == -1 );
0546   rtems_test_assert( errno == EBADF );
0547 
0548   /*
0549    *  Test simple write to a file at offset 0
0550    */
0551 
0552   puts( "mknod /tmp/joel" );
0553   status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
0554   test_write( "/tmp/joel", 0, "the first write!!!\n" );
0555   test_cat( "/tmp/joel", 0, 0 );
0556 
0557   /* Exercise _rename_r */
0558 
0559   /* Simple rename test */
0560   puts( "rename /tmp/joel to /tmp/drjoel");
0561   status = _rename_r(NULL,"/tmp/joel","/tmp/drjoel");
0562   rtems_test_assert(status == 0);
0563 
0564   /* Simple rename test */
0565   puts("rename /tmp/drjoel to /tmp/joel");
0566   status = _rename_r(NULL,"/tmp/drjoel","/tmp/joel");
0567   rtems_test_assert(status == 0);
0568 
0569   /* Invalid old path */
0570   puts("rename /tmp/drjoel to /tmp/joel - Should result in an error \
0571 since old path is not valid");
0572   status = _rename_r(NULL,"/tmp/drjoel","/tmp/joel");
0573   rtems_test_assert(status == -1);
0574 
0575   /* Invalid new path */
0576   puts("rename /tmp/joel to /tmp/drjoel/joel - Should result in an error \
0577 since new path is not valid");
0578   status = _rename_r(NULL,"/tmp/joel","/tmp/drjoel/joel");
0579   rtems_test_assert(status == -1);
0580 
0581   puts("changing dir to /tmp");
0582   status = chdir("/tmp/");
0583   rtems_test_assert(status == 0);
0584 
0585   puts("rename joel to drjoel");
0586   status = _rename_r(NULL,"joel","drjoel");
0587   rtems_test_assert(status == 0);
0588 
0589   puts("rename drjoel to joel");
0590   status = _rename_r(NULL,"drjoel","joel");
0591   rtems_test_assert(status == 0);
0592 
0593   /* Rename across file systems */
0594   puts("creating directory /imfs");
0595   status = mkdir("/imfs",0777);
0596   rtems_test_assert(status == 0);
0597   puts("creating directory /imfs/hidden_on_mount");
0598   status = mkdir("/imfs/hidden_on_mount",0777);
0599   rtems_test_assert(status == 0);
0600 
0601   puts("mounting filesystem with IMFS_ops at /imfs");
0602   status = mount("null", "/imfs", "imfs", RTEMS_FILESYSTEM_READ_WRITE, NULL);
0603   rtems_test_assert(status == 0);
0604   puts("creating directory /imfs/test (on newly mounted filesystem)");
0605   status = mkdir("/imfs/test", 0777);
0606   rtems_test_assert(status == 0);
0607 
0608   puts("attempt to rename directory joel to /imfs/test/joel - should fail with EXDEV");
0609   status = _rename_r(NULL, "joel", "/imfs/test/joel");
0610   rtems_test_assert(status == -1);
0611   rtems_test_assert(errno == EXDEV);
0612 
0613   puts("changing dir to /");
0614   status = chdir("/");
0615   rtems_test_assert(status == 0);
0616 
0617   puts("attempt to rename across filesystem, with old path having a parent node");
0618   puts("attempt to rename tmp/joel to /imfs/test/joel");
0619   status = _rename_r(NULL, "tmp/joel", "/imfs/test/joel");
0620   rtems_test_assert(status == -1);
0621   rtems_test_assert(errno == EXDEV);
0622 
0623   puts("End of _rename_r tests");
0624 
0625   /*
0626    *  Test simple write to a file at a non-0 offset in the first block
0627    */
0628 
0629   status = unlink( "/tmp/joel" );
0630   rtems_test_assert( !status );
0631 
0632   status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
0633   rtems_test_assert( !status );
0634 
0635   test_write( "/tmp/joel", 10, "the first write!!!\n" );
0636   test_cat( "/tmp/joel", 0, 0 );
0637   stat_a_file( "/tmp/joel" );
0638 
0639   /*
0640    *  Test simple write to a file at a non-0 offset in the second block.  Then
0641    *  try to read from various offsets and lengths.
0642    */
0643 
0644   puts("unlink /tmp/joel");
0645   status = unlink( "/tmp/joel" );
0646   rtems_test_assert( !status );
0647 
0648   /* Test a failure path */
0649 
0650   puts( "unlink /tmp/joel" );
0651   status = unlink( "/tmp/joel" );
0652   rtems_test_assert( status == -1 );
0653 
0654   puts( "mknod /tmp/joel");
0655   status = mknod( "/tmp/joel", (S_IFREG | S_IRWXU), 0LL );
0656   rtems_test_assert( !status );
0657 
0658   test_write( "/tmp/joel", 514, "the first write!!!\n" );
0659   test_write( "/tmp/joel", 1, test_write_buffer );
0660   test_write( "/tmp/joel", 63, test_write_buffer );
0661   test_cat( "/tmp/joel", 0, 1 );
0662   test_cat( "/tmp/joel", 1, 1 );
0663   test_cat( "/tmp/joel", 490, 1 );
0664   test_cat( "/tmp/joel", 512, 1 );
0665   test_cat( "/tmp/joel", 513, 1 );
0666   test_cat( "/tmp/joel", 514, 1 );
0667   test_cat( "/tmp/joel", 520, 1 );
0668   test_cat( "/tmp/joel", 1, 1024 );
0669 
0670   /*
0671    *  Read from a much longer file so we can descend into doubly and
0672    *  triply indirect blocks.
0673    */
0674 
0675   if ( max_size < (size_t) 300 * 1024 ) {
0676     test_extend( "/tmp/joel", max_size - 1 );
0677     test_cat( "/tmp/joel", max_size / 2, 1024 );
0678   } else {
0679     printf( "Skipping maximum file size test since max_size is %zu bytes\n", max_size );
0680     puts("That is likely to be bigger than the available RAM on many targets." );
0681   }
0682 
0683   stat_a_file( "/tmp/joel" );
0684 
0685   /*
0686    *  Now try to use a FILE * descriptor
0687    *
0688    *  /tmp/j should not exist at this point.
0689    */
0690 
0691   puts( "stat of /tmp/j" );
0692   errno = 0;
0693   status = stat( "/tmp/j", &buf );
0694   printf( "stat(/tmp/j) returned %d (errno=%d)\n", status, errno );
0695   dump_statbuf( &buf );
0696 
0697   puts( "fopen of /tmp/j" );
0698   file = fopen( "/tmp/j", "w+" );
0699   rtems_test_assert( file );
0700 
0701   puts( "fprintf to /tmp/j" );
0702   for (i=1 ; i<=5 ; i++) {
0703     status = fprintf( file, "This is call %d to fprintf\n", i );
0704     rtems_test_assert( status );
0705     printf( "(%d) %d characters written to the file\n", i, status );
0706   }
0707 
0708   fflush( file );
0709 
0710   status = stat( "/tmp/j", &buf );
0711   rtems_test_assert( !status );
0712   dump_statbuf( &buf );
0713   atime2 = buf.st_atime;
0714   mtime2 = buf.st_mtime;
0715   ctime2 = buf.st_ctime;
0716 
0717 
0718   status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() + 1);
0719   rewind( file );
0720   while ( fgets(buffer, 128, file) )
0721     printf( "%s", buffer );
0722 
0723   /*
0724    * Verify only atime changed for a read.
0725    */
0726   status = stat( "/tmp/j", &buf );
0727   rtems_test_assert( !status );
0728   dump_statbuf( &buf );
0729   atime1 = buf.st_atime;
0730   mtime1 = buf.st_mtime;
0731   ctime1 = buf.st_ctime;
0732   rtems_test_assert( atime1 != atime2);
0733   rtems_test_assert( mtime1 == mtime2);
0734   rtems_test_assert( ctime1 == ctime2);
0735 
0736   unlink( "/tmp/joel" );
0737 
0738   /*
0739    *  Now truncate a file
0740    */
0741 
0742   status = rtems_task_wake_after( rtems_clock_get_ticks_per_second() );
0743   puts( "truncate /tmp/j to length of 40" );
0744   status = truncate( "/tmp/j", 40 );
0745   rtems_test_assert( !status );
0746 
0747   /*
0748    * Verify truncate changed all except atime.
0749    */
0750   status = stat( "/tmp/j", &buf );
0751   rtems_test_assert( !status );
0752   dump_statbuf( &buf );
0753   atime2 = buf.st_atime;
0754   mtime2 = buf.st_mtime;
0755   ctime2 = buf.st_ctime;
0756   rtems_test_assert( atime1 == atime2);
0757   rtems_test_assert( mtime1 != mtime2);
0758   rtems_test_assert( ctime1 != ctime2);
0759 
0760   /* try to truncate the console and see what happens */
0761   errno = 0;
0762   status = truncate( "/dev/console", 40 );
0763   rtems_test_assert( status == 0 || ( status == -1 && errno == EINVAL ) );
0764 
0765   puts( "truncate /tmp/j to length of 0" );
0766   status = truncate( "/tmp/j", 0 );
0767   rtems_test_assert( !status );
0768 
0769   puts( "truncate /tmp to length of 0 should fail with EISDIR\n");
0770   status = truncate( "/tmp", 0 );
0771   rtems_test_assert( status == -1 );
0772   printf( "%d: %s\n", errno, strerror( errno ) );
0773   rtems_test_assert( errno == EISDIR );
0774 
0775   status = truncate( "/tmp/fred", 10 );
0776   rtems_test_assert( status == -1);
0777 
0778   rtems_status = rtems_io_register_name( "/dev/not_console", 0, 0 );
0779   directive_failed( rtems_status, "io register" );
0780 
0781   test_case_reopen_append();
0782 
0783   TEST_END();
0784   rtems_test_exit( 0 );
0785 }
0786 
0787 /*
0788  *  Open/Create a File and write to it
0789  *
0790  *  Test case submitted by Andrew Bythell <abythell@nortelnetworks.com>.
0791  *
0792  */
0793 
0794 void test_file (char *filename, char *mode);
0795 
0796 void test_case_reopen_append(void)
0797 {
0798   printf ("Writing First File\n");
0799   test_file ("/one.txt", "a");
0800   test_file ("/one.txt", "a");
0801 
0802   /* but not the second time - this will insert junk.
0803      the number of ^@'s seems to equal the number of
0804      actual characters in the file */
0805 
0806   printf ("Writing Second File\n");
0807   test_file ("/two.txt", "a");
0808   test_file ("/two.txt", "a");
0809 
0810   test_cat( "/one.txt", 0, 1024 );
0811   test_cat( "/two.txt", 0, 1024 );
0812 }
0813 
0814 void test_file (char *filename, char *mode)
0815 {
0816   FILE *fp;
0817   fp = fopen (filename, mode);
0818   if (!fp)
0819       perror ("fopen");
0820   fprintf (fp, "this is a test line\n");
0821   if (fclose (fp))
0822       perror ("fclose");
0823 }