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.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: nickg, richard.panton@3glab.com
46 // Purpose: Test fileio system
47 // Description: This test uses the testfs to check out the initialization
48 // and basic operation of the fileio system
50 //####DESCRIPTIONEND####
52 //==========================================================================
54 #include <pkgconf/hal.h>
55 #include <pkgconf/kernel.h>
56 #include <pkgconf/io_fileio.h>
58 #include <cyg/kernel/ktypes.h> // base kernel types
59 #include <cyg/infra/cyg_trac.h> // tracing macros
60 #include <cyg/infra/cyg_ass.h> // assertion macros
61 #include <cyg/io/flash.h>
70 #include <cyg/fileio/fileio.h>
72 #include <cyg/infra/testcase.h>
73 #include <cyg/infra/diag.h> // HAL polled output
75 #include <pkgconf/fs_jffs2.h> // Address of JFFS2
77 //==========================================================================
79 /* MTAB_ENTRY( jffs2_mte1,
83 (CYG_ADDRWORD) CYGNUM_FS_JFFS2_BASE_ADDRESS ); */
86 //==========================================================================
88 #define SHOW_RESULT( _fn, _res ) \
89 diag_printf("<FAIL>: " #_fn "() returned %d %s\n", _res, _res<0?strerror(errno):"");
91 #define CHKFAIL_TYPE( _fn, _res, _type ) { \
93 diag_printf("<FAIL>: " #_fn "() returned %d (expected -1)\n", _res); \
94 else if ( errno != _type ) \
95 diag_printf("<FAIL>: " #_fn "() failed with errno %d (%s),\n expected %d (%s)\n", errno, strerror(errno), _type, strerror(_type) ); \
98 //==========================================================================
102 #define LONGNAME1 "long_file_name_that_should_take_up_more_than_one_directory_entry_1"
103 #define LONGNAME2 "long_file_name_that_should_take_up_more_than_one_directory_entry_2"
106 //==========================================================================
108 #ifndef CYGPKG_LIBC_STRING
110 char *strcat( char *s1, const char *s2 )
114 while( (*s1++ = *s2++) != 0);
120 //==========================================================================
122 static void listdir( char *name, int statp )
127 diag_printf("<INFO>: reading directory %s\n",name);
129 dirp = opendir( name );
130 if( dirp == NULL ) SHOW_RESULT( opendir, -1 );
134 struct dirent *entry = readdir( dirp );
139 diag_printf("<INFO>: entry %14s",entry->d_name);
142 char fullname[PATH_MAX];
147 strcpy(fullname, name );
148 if( !(name[0] == '/' && name[1] == 0 ) )
149 strcat(fullname, "/" );
151 else fullname[0] = 0;
153 strcat(fullname, entry->d_name );
155 err = stat( fullname, &sbuf );
158 if( errno == ENOSYS )
159 diag_printf(" <no status available>");
160 else SHOW_RESULT( stat, err );
164 diag_printf(" [mode %08x ino %08x nlink %d size %d]",
165 sbuf.st_mode,sbuf.st_ino,sbuf.st_nlink,sbuf.st_size);
172 err = closedir( dirp );
173 if( err < 0 ) SHOW_RESULT( stat, err );
176 //==========================================================================
178 static void copyfile( char *name2, char *name1 )
186 diag_printf("<INFO>: copy file %s -> %s\n",name2,name1);
188 err = access( name1, F_OK );
189 if( err < 0 && errno != EACCES ) SHOW_RESULT( access, err );
191 err = access( name2, F_OK );
192 if( err != 0 ) SHOW_RESULT( access, err );
194 fd1 = open( name1, O_WRONLY|O_CREAT );
195 if( fd1 < 0 ) SHOW_RESULT( open, fd1 );
197 fd2 = open( name2, O_RDONLY );
198 if( fd2 < 0 ) SHOW_RESULT( open, fd2 );
202 done = read( fd2, buf, IOSIZE );
203 if( done < 0 ) SHOW_RESULT( read, done );
205 if( done == 0 ) break;
207 wrote = write( fd1, buf, done );
208 if( wrote != done ) SHOW_RESULT( write, wrote );
210 if( wrote != done ) break;
214 if( err < 0 ) SHOW_RESULT( close, err );
217 if( err < 0 ) SHOW_RESULT( close, err );
221 //==========================================================================
223 static void comparefiles( char *name2, char *name1 )
229 ssize_t done1, done2;
232 diag_printf("<INFO>: compare files %s == %s\n",name2,name1);
234 err = access( name1, F_OK );
235 if( err != 0 ) SHOW_RESULT( access, err );
237 err = access( name1, F_OK );
238 if( err != 0 ) SHOW_RESULT( access, err );
240 fd1 = open( name1, O_RDONLY );
241 if( fd1 < 0 ) SHOW_RESULT( open, fd1 );
243 fd2 = open( name2, O_RDONLY );
244 if( fd2 < 0 ) SHOW_RESULT( open, fd2 );
248 done1 = read( fd1, buf1, IOSIZE );
249 if( done1 < 0 ) SHOW_RESULT( read, done1 );
251 done2 = read( fd2, buf2, IOSIZE );
252 if( done2 < 0 ) SHOW_RESULT( read, done2 );
255 diag_printf("Files different sizes\n");
257 if( done1 == 0 ) break;
259 for( i = 0; i < done1; i++ )
260 if( buf1[i] != buf2[i] )
262 diag_printf("buf1[%d](%02x) != buf1[%d](%02x)\n",i,buf1[i],i,buf2[i]);
263 CYG_TEST_FAIL("Data in files not equal\n");
268 if( err < 0 ) SHOW_RESULT( close, err );
271 if( err < 0 ) SHOW_RESULT( close, err );
275 //==========================================================================
278 int main( int argc, char **argv )
285 // --------------------------------------------------------------
287 err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/", "jffs2" );
288 if ( err != ENOERR ) SHOW_RESULT( chdir, err );
290 diag_printf("<INFO>: JFFS2 root follows\n");
291 diag_printf("<INFO>: Note that dev cannot be stat()ed\n");
292 listdir( "/", true );
294 diag_printf("<INFO>: cd /etc\n" );
295 err = chdir( "/etc" );
296 if ( err < 0 ) SHOW_RESULT( chdir, err );
298 diag_printf("<INFO>: JFFS2 list of '' follows\n");
301 diag_printf("<INFO>: JFFS2 list of /etc follows\n");
302 listdir( "/etc", true );
304 //diag_printf("<INFO>: JFFS2 list of . follows\n");
305 //listdir( ".", true );
307 err = mount( "", "/var", "ramfs" );
308 if( err < 0 ) SHOW_RESULT( mount, err );
310 copyfile( "/etc/passwd", "/var/passwd_copy" );
312 comparefiles( "/etc/passwd", "/var/passwd_copy" );
314 diag_printf("<INFO>: JFFS2 list of / follows\n");
315 diag_printf("<INFO>: Note that /var now gives stat() info for RAMFS\n");
316 listdir( "/", true );
318 diag_printf("<INFO>: Mount JFFS2 again onto /mnt\n");
319 //sprintf( address, "%p", (void*)CYGNUM_FS_JFFS2_BASE_ADDRESS );
320 err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/mnt", "jffs2" );
321 if( err < 0 ) SHOW_RESULT( mount, err );
323 comparefiles( "/etc/passwd", "/mnt/etc/passwd" );
326 err = mkdir( "/foo", 0 );
327 CHKFAIL_TYPE( mkdir, err, EROFS );
329 err = rename( "/var", "/tmp" ); // RAMFS is mounted here
330 CHKFAIL_TYPE( rename, err, EXDEV );
332 err = rename( "/var/passwd_copy", "/mnt/etc/passwd_copy" );
333 CHKFAIL_TYPE( rename, err, EXDEV );
335 err = rename( "/etc", "/tmp" );
336 CHKFAIL_TYPE( rename, err, EROFS );
338 diag_printf("<INFO>: cd /etc\n");
339 err = chdir( "/etc" );
340 if( err < 0 ) SHOW_RESULT( chdir, err );
342 err = chdir( "/mnt/etc" );
343 if( err < 0 ) SHOW_RESULT( chdir, err );
345 //listdir( ".", true );
347 diag_printf("<INFO>: unlink /tmp\n");
348 err = unlink( "/tmp" );
349 CHKFAIL_TYPE( unlink, err, EROFS );
351 diag_printf("<INFO>: mount random area\n");
352 //sprintf(address, "%p", (void*)(CYGNUM_FS_JFFS2_BASE_ADDRESS + 0x20000));
353 err = mount( "", "/tmp", "jffs2" );
354 SHOW_RESULT( mount, err );
356 err = umount( "/mnt" );
357 if( err < 0 ) SHOW_RESULT( umount, err );
359 err = umount( "/var" );
360 if( err < 0 ) SHOW_RESULT( umount, err );
363 if( err < 0 ) SHOW_RESULT( umount, err );
366 CYG_TEST_PASS_FINISH("fileio1");
369 // -------------------------------------------------------------------------