1 //==========================================================================
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2004 eCosCentric Limited
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: nickg, richard.panton@3glab.com, jlarmour
47 // Purpose: Test fileio system
48 // Description: This test uses the testfs to check out the initialization
49 // and basic operation of the fileio system
51 //####DESCRIPTIONEND####
53 //==========================================================================
55 #include <pkgconf/hal.h>
56 #include <pkgconf/io_fileio.h>
57 #include <pkgconf/isoinfra.h>
58 #include <pkgconf/system.h>
59 #include <pkgconf/fs_rom.h>
69 #include <cyg/fileio/fileio.h>
71 #include <cyg/infra/cyg_type.h>
72 #include <cyg/infra/testcase.h>
73 #include <cyg/infra/diag.h> // HAL polled output
75 // Test ROMFS data. Two example data files are generated so that
76 // the test will work on both big-endian and little-endian targets.
77 #if (CYG_BYTEORDER == CYG_LSBFIRST)
78 # include <cyg/romfs/testromfs_le.h>
80 # include <cyg/romfs/testromfs_be.h>
83 //==========================================================================
85 MTAB_ENTRY( romfs_mte1,
89 (CYG_ADDRWORD) &filedata[0] );
92 //==========================================================================
94 #define SHOW_RESULT( _fn, _res ) \
95 diag_printf("<FAIL>: " #_fn "() returned %d %s\n", (int)_res, _res<0?strerror(errno):"");
97 #define CHKFAIL_TYPE( _fn, _res, _type ) { \
99 diag_printf("<FAIL>: " #_fn "() returned %d (expected -1)\n", (int)_res); \
100 else if ( errno != _type ) \
101 diag_printf("<FAIL>: " #_fn "() failed with errno %d (%s),\n expected %d (%s)\n", errno, strerror(errno), _type, strerror(_type) ); \
104 //==========================================================================
108 #define LONGNAME1 "long_file_name_that_should_take_up_more_than_one_directory_entry_1"
109 #define LONGNAME2 "long_file_name_that_should_take_up_more_than_one_directory_entry_2"
112 //==========================================================================
114 #ifndef CYGINT_ISO_STRING_STRFUNCS
116 char *strcat( char *s1, const char *s2 )
120 while( (*s1++ = *s2++) != 0);
126 //==========================================================================
128 static void listdir( char *name, int statp )
133 diag_printf("<INFO>: reading directory %s\n",name);
135 dirp = opendir( name );
136 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
140 struct dirent *entry = readdir( dirp );
145 diag_printf("<INFO>: entry %14s",entry->d_name);
146 #ifdef CYGPKG_FS_ROM_RET_DIRENT_DTYPE
147 diag_printf(" d_type %2x", entry->d_type);
151 char fullname[PATH_MAX];
156 strcpy(fullname, name );
157 if( !(name[0] == '/' && name[1] == 0 ) )
158 strcat(fullname, "/" );
160 else fullname[0] = 0;
162 strcat(fullname, entry->d_name );
164 err = stat( fullname, &sbuf );
167 if( errno == ENOSYS )
168 diag_printf(" <no status available>");
169 else SHOW_RESULT( stat, err );
173 diag_printf(" [mode %08x ino %08x nlink %d size %ld]",
174 sbuf.st_mode,sbuf.st_ino,sbuf.st_nlink,sbuf.st_size);
176 #ifdef CYGPKG_FS_ROM_RET_DIRENT_DTYPE
177 if ((entry->d_type & S_IFMT) != (sbuf.st_mode & S_IFMT))
178 CYG_TEST_FAIL("File mode's don't match between dirent and stat");
185 err = closedir( dirp );
186 if( err < 0 ) SHOW_RESULT( stat, err );
189 //==========================================================================
192 static void copyfile( char *name2, char *name1 )
200 diag_printf("<INFO>: copy file %s -> %s\n",name2,name1);
202 err = access( name1, F_OK );
203 if( err < 0 && errno != EACCES ) SHOW_RESULT( access, err );
205 err = access( name2, F_OK );
206 if( err != 0 ) SHOW_RESULT( access, err );
208 fd1 = open( name1, O_WRONLY|O_CREAT );
209 if( fd1 < 0 ) SHOW_RESULT( open, fd1 );
211 fd2 = open( name2, O_RDONLY );
212 if( fd2 < 0 ) SHOW_RESULT( open, fd2 );
216 done = read( fd2, buf, IOSIZE );
217 if( done < 0 ) SHOW_RESULT( read, done );
219 if( done == 0 ) break;
221 wrote = write( fd1, buf, done );
222 if( wrote != done ) SHOW_RESULT( write, wrote );
224 if( wrote != done ) break;
228 if( err < 0 ) SHOW_RESULT( close, err );
231 if( err < 0 ) SHOW_RESULT( close, err );
236 //==========================================================================
238 static void comparefiles( char *name2, char *name1 )
244 ssize_t done1, done2;
247 diag_printf("<INFO>: compare files %s == %s\n",name2,name1);
249 err = access( name1, F_OK );
250 if( err != 0 ) SHOW_RESULT( access, err );
252 err = access( name1, F_OK );
253 if( err != 0 ) SHOW_RESULT( access, err );
255 fd1 = open( name1, O_RDONLY );
256 if( fd1 < 0 ) SHOW_RESULT( open, fd1 );
258 fd2 = open( name2, O_RDONLY );
259 if( fd2 < 0 ) SHOW_RESULT( open, fd2 );
263 done1 = read( fd1, buf1, IOSIZE );
264 if( done1 < 0 ) SHOW_RESULT( read, done1 );
266 done2 = read( fd2, buf2, IOSIZE );
267 if( done2 < 0 ) SHOW_RESULT( read, done2 );
270 diag_printf("Files different sizes\n");
272 if( done1 == 0 ) break;
274 for( i = 0; i < done1; i++ )
275 if( buf1[i] != buf2[i] )
277 diag_printf("buf1[%d](%02x) != buf1[%d](%02x)\n",i,buf1[i],i,buf2[i]);
278 CYG_TEST_FAIL("Data in files not equal\n");
283 if( err < 0 ) SHOW_RESULT( close, err );
286 if( err < 0 ) SHOW_RESULT( close, err );
290 //==========================================================================
293 int main( int argc, char **argv )
297 #if defined(CYGSEM_FILEIO_BLOCK_USAGE)
298 struct cyg_fs_block_usage usage;
303 // --------------------------------------------------------------
305 diag_printf("<INFO>: ROMFS root follows\n");
306 listdir( "/", true );
308 diag_printf("<INFO>: cd /etc\n" );
309 err = chdir( "/etc" );
311 SHOW_RESULT( chdir, err );
312 CYG_TEST_FAIL_FINISH("romfs1");
315 diag_printf("<INFO>: ROMFS list of '' follows\n");
318 diag_printf("<INFO>: ROMFS list of /etc follows\n");
319 listdir( "/etc", true );
321 diag_printf("<INFO>: ROMFS list of . follows\n");
322 listdir( ".", true );
325 err = mount( "", "/var", "ramfs" );
326 if( err < 0 ) SHOW_RESULT( mount, err );
328 copyfile( "/etc/passwd", "/var/passwd_copy" );
330 comparefiles( "/etc/passwd", "/var/passwd_copy" );
333 diag_printf("<INFO>: ROMFS list of / follows\n");
335 diag_printf("<INFO>: Note that /var now gives stat() info for RAMFS\n");
337 listdir( "/", true );
339 diag_printf("<INFO>: Mount ROMFS again onto /mnt\n");
340 sprintf( address, "%p", (void*)&filedata[0] );
341 err = mount( address, "/mnt", "romfs" );
342 if( err < 0 ) SHOW_RESULT( mount, err );
344 comparefiles( "/etc/passwd", "/mnt/etc/passwd" );
347 err = mkdir( "/foo", 0 );
348 CHKFAIL_TYPE( mkdir, err, EROFS );
350 err = rename( "/var", "/tmp" ); // RAMFS is mounted here
352 CHKFAIL_TYPE( rename, err, EXDEV );
354 CHKFAIL_TYPE( rename, err, EROFS );
357 err = rename( "/var/passwd_copy", "/mnt/etc/passwd_copy" );
358 CHKFAIL_TYPE( rename, err, EXDEV );
360 err = rename( "/etc", "/tmp" );
361 CHKFAIL_TYPE( rename, err, EROFS );
363 diag_printf("<INFO>: cd /etc\n");
364 err = chdir( "/etc" );
365 if( err < 0 ) SHOW_RESULT( chdir, err );
367 err = chdir( "/mnt/etc" );
368 if( err < 0 ) SHOW_RESULT( chdir, err );
370 listdir( ".", true );
372 diag_printf("<INFO>: unlink /tmp\n");
373 err = unlink( "/tmp" );
374 CHKFAIL_TYPE( unlink, err, EROFS );
376 diag_printf("<INFO>: mount random area\n");
377 sprintf(address, "%p", (void*)(&filedata[0] + 0x100));
378 err = mount( address, "/tmp", "romfs" );
379 CHKFAIL_TYPE( mount, err, ENOENT );
381 err = umount( "/mnt" );
382 if( err < 0 ) SHOW_RESULT( umount, err );
384 err = umount( "/var" );
386 if( err < 0 ) SHOW_RESULT( umount, err );
388 CHKFAIL_TYPE( umount, err, EINVAL );
391 #if defined(CYGSEM_FILEIO_BLOCK_USAGE)
392 err = cyg_fs_getinfo("/", FS_INFO_BLOCK_USAGE, &usage, sizeof(usage));
393 if( err < 0 ) SHOW_RESULT( cyg_fs_getinfo, err );
394 diag_printf("<INFO>: total size: %6lld blocks, %10lld bytes\n",
395 usage.total_blocks, usage.total_blocks * usage.block_size);
396 diag_printf("<INFO>: free size: %6lld blocks, %10lld bytes\n",
397 usage.free_blocks, usage.free_blocks * usage.block_size);
398 diag_printf("<INFO>: block size: %6u bytes\n", usage.block_size);
400 // --------------------------------------------------------------
403 if( err < 0 ) SHOW_RESULT( umount, err );
406 CYG_TEST_PASS_FINISH("romfs1");
409 // -------------------------------------------------------------------------