Index: packages/io/fileio/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/io/fileio/current/ChangeLog,v retrieving revision 1.61 diff -u -r1.61 ChangeLog --- packages/io/fileio/current/ChangeLog 23 Oct 2005 20:45:11 -0000 1.61 +++ packages/io/fileio/current/ChangeLog 16 Feb 2006 17:00:43 -0000 @@ -1,3 +1,9 @@ +2006-02-16 Peter Korsgaard + + * src/misc.cxx (cyg_mtab_lookup): Corrected implementation for + relative paths crossing mount points. + * tests/fileio1.c (cyg_user_start): Add a test for the above fix. + 2005-10-20 Andrew Lunn * src/select.cxx: Needs sys/time.h for struct timeval. Index: packages/io/fileio/current/src/misc.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/io/fileio/current/src/misc.cxx,v retrieving revision 1.10 diff -u -r1.10 misc.cxx --- packages/io/fileio/current/src/misc.cxx 22 Jan 2005 14:03:37 -0000 1.10 +++ packages/io/fileio/current/src/misc.cxx 16 Feb 2006 17:00:43 -0000 @@ -222,6 +222,16 @@ } // ------------------------------------------------------------------------- +// Simple strlen implementation + +static int my_strlen(const char *c) +{ + int l = 0; + while (*c++) l++; + return l; +} + +// ------------------------------------------------------------------------- // Search the mtab for the entry that matches the longest substring of // **name. @@ -230,35 +240,64 @@ cyg_mtab_entry *m, *best = NULL; int best_len = 0; - // Unrooted file names go straight to current dir + // Unrooted file names start from current dir if( **name != '/' ) { + int cwd_len; if (*mte == (cyg_mtab_entry *)NULL) { // No known current directory return -1; } - // Current directory is well known - return 0; - } - // Otherwise search the mount table. - for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ ) + best = *mte; + cwd_len = my_strlen((*mte)->name); + + // current dir is not the correct mte if the relative path crosses + // mount points - search for best matching mount point + for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ ) + { + if( m->name != NULL && m->valid ) + { + int len = matchlen(m->name, (*mte)->name); + // mount point under cwd? + if (len == cwd_len) + { + if (m->name[len] == '/') + len++; + + len = matchlen(*name, &m->name[len]); + if (len > best_len) + best = m, best_len = len; + } + } + } + + // did we find a better match? + if (best != *mte) + *dir = best->root; + } + else { - if( m->name != NULL && m->valid ) + // Otherwise search the mount table. + for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ ) { - int len = matchlen(*name,m->name); - if( len > best_len ) - best = m, best_len = len; + if( m->name != NULL && m->valid ) + { + int len = matchlen(*name,m->name); + if( len > best_len ) + best = m, best_len = len; + } } + + // No match found, bad path name... + if( best_len == 0 ) return -1; + + *dir = best->root; } - // No match found, bad path name... - if( best_len == 0 ) return -1; - *name += best_len; if( **name == '/' ) (*name)++; *mte = best; - *dir = best->root; return 0; } Index: packages/io/fileio/current/tests/fileio1.c =================================================================== RCS file: /cvs/ecos/ecos/packages/io/fileio/current/tests/fileio1.c,v retrieving revision 1.7 diff -u -r1.7 fileio1.c --- packages/io/fileio/current/tests/fileio1.c 27 Mar 2005 17:36:28 -0000 1.7 +++ packages/io/fileio/current/tests/fileio1.c 16 Feb 2006 17:00:43 -0000 @@ -422,6 +422,8 @@ checkfile( "/ram/tinky"); checkfile( "/ram/laalaa"); comparefiles( "/ram/tinky", "/ram/laalaa" ); + comparefiles( "/ram/tinky", "ram/laalaa" ); + comparefiles( "ram/tinky", "/ram/laalaa" ); err = chdir( "/ram" ); if( err < 0 ) SHOW_RESULT( chdir, err );