]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/io/fileio/v2_0/src/misc.cxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / io / fileio / v2_0 / src / misc.cxx
index f878cf6f993c6c7d9f7dba40a2c5ee70d447803d..97a96fea8e3ec63a7e1cd6bf9cf9d50d7267de5a 100644 (file)
@@ -113,8 +113,9 @@ __externC cyg_mtab_entry cyg_mtab[];
 CYG_HAL_TABLE_BEGIN( cyg_mtab, mtab );
 
 // Extra entries at end of mtab for dynamic mount points.
+#if CYGNUM_FILEIO_MTAB_EXTRA > 0
 cyg_mtab_entry cyg_mtab_extra[CYGNUM_FILEIO_MTAB_EXTRA] CYG_HAL_TABLE_EXTRA(mtab) = { { NULL } };
-
+#endif
 // End of mount table, set in the linker script.
 __externC cyg_mtab_entry cyg_mtab_end;
 CYG_HAL_TABLE_END( cyg_mtab_end, mtab );
@@ -221,6 +222,16 @@ static int matchlen( const char *s1, const char *s2 )
     else return 0;
 }
 
+// -------------------------------------------------------------------------
+// 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 +241,64 @@ __externC int cyg_mtab_lookup( cyg_dir *dir, const char **name, cyg_mtab_entry *
     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;
 }