changeset 2078:cfec912002f3

* src/ramfs.c: Implement holes in files when using BLOCK allocation method. This requires allowing lseek to go past the end of the file. * test/ramfs2.c: Extended the lseek test to now seek past the end of the file. With the BLOCK allocation method this will create a whole. With the SIMPLE allocation method is just allocates the memory and fills it with zero. * cdl/ramfs.cdl: Added in interface which both SIMPLE and BLOCK implement. This allows the inference engine to work out is should enable BLOCK if SIMPLE is disabled by the user. 2005-10-01 Dan Jakubiec <dan.jakubiec@systech.com> * src/ramfs.c: (ramfs_mount, ramfs_open, ramfs_mkdir) Changed the permissions for files and directories created on RAMFS file systems from 000 to 777. This helps ported applications which wrongly assume there is some security concept and check for the existence of certain file permissions.
author asl
date Sun, 02 Oct 2005 14:03:14 +0000
parents da2b798f04fb
children 2ae48600be8b
files packages/fs/ram/current/ChangeLog packages/fs/ram/current/cdl/ramfs.cdl packages/fs/ram/current/src/ramfs.c packages/fs/ram/current/tests/ramfs2.c
diffstat 4 files changed, 120 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/packages/fs/ram/current/ChangeLog
+++ b/packages/fs/ram/current/ChangeLog
@@ -1,3 +1,26 @@
+2005-10-01  Andrew Lunn   <andrew.lunn@ascom.ch>
+
+	* src/ramfs.c: Implement holes in files when using BLOCK
+	allocation method. This requires allowing lseek to go past the end
+	of the file.
+
+	* test/ramfs2.c: Extended the lseek test to now seek past the end
+	of the file. With the BLOCK allocation method this will create a
+	whole. With the SIMPLE allocation method is just allocates the
+	memory and fills it with zero.
+
+	* cdl/ramfs.cdl: Added in interface which both SIMPLE and BLOCK
+	implement. This allows the inference engine to work out is should
+	enable BLOCK if SIMPLE is disabled by the user.
+
+2005-10-01  Dan Jakubiec  <dan.jakubiec@systech.com>
+
+	* src/ramfs.c: (ramfs_mount, ramfs_open, ramfs_mkdir) Changed the
+	permissions for files and directories created on RAMFS file systems
+	from 000 to 777. This helps ported applications which wrongly
+	assume there is some security concept and check for the existence
+	of certain file permissions.
+
 2005-03-27  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* tests/ramfs1.c (SHOW_RESULT): Fixed compiler warning about format
--- a/packages/fs/ram/current/cdl/ramfs.cdl
+++ b/packages/fs/ram/current/cdl/ramfs.cdl
@@ -65,6 +65,17 @@ cdl_package CYGPKG_FS_RAM {
     implements     CYGINT_IO_FILEIO_FS
 
     compile        -library=libextras.a ramfs.c
+        
+    requires       CYGINT_FS_RAM_ALLOC == 1
+
+    cdl_interface  CYGINT_FS_RAM_ALLOC {
+        display       "Functions to allocate RAM"
+        description   "
+            This interface is implemented by functions
+            which allocate RAM to hold the contents of the files"
+    }
+
+
 
     # ----------------------------------------------------------------------
     # Simple allocation mechanism using malloc()
@@ -75,6 +86,7 @@ cdl_package CYGPKG_FS_RAM {
 	default_value 1
 	active_if      !CYGPKG_FS_RAM_BLOCKS
 
+        implements CYGINT_FS_RAM_ALLOC
 	cdl_option     CYGNUM_RAMFS_REALLOC_INCREMENT {
 	    display       "Size of file data storage increment"
 	    flavor        data
@@ -95,7 +107,7 @@ cdl_package CYGPKG_FS_RAM {
 	default_value  0
 	active_if      !CYGPKG_FS_RAM_SIMPLE
 
-	
+        implements CYGINT_FS_RAM_ALLOC	
 	cdl_option     CYGNUM_RAMFS_BLOCK_SIZE {
 	    display       "Size of file data storage block"
 	    flavor        data
--- a/packages/fs/ram/current/src/ramfs.c
+++ b/packages/fs/ram/current/src/ramfs.c
@@ -654,7 +654,7 @@ static int findbuffer_node( ramfs_node  
                             size_t *size,       // returned buffer size
                             cyg_bool alloc)     // extend allocation?
 {
-    if( alloc && (pos == node->datasize || node->datasize == 0) )
+    if( alloc && (pos >= node->datasize || node->datasize == 0) )
     {
         // If we are allowed to alloc new data, and we are at the end of the
         // current data allocation, or there is no data present, allocate or
@@ -668,7 +668,8 @@ static int findbuffer_node( ramfs_node  
             newdata = realloc( node->data, pos+CYGNUM_RAMFS_REALLOC_INCREMENT );
         
         if( newdata == NULL ) return ENOSPC;
-        else memset( newdata+pos, 0, CYGNUM_RAMFS_REALLOC_INCREMENT );
+        else memset( newdata + node->datasize, 0, 
+                     pos + CYGNUM_RAMFS_REALLOC_INCREMENT - node->datasize );
         
         node->data = newdata;
         node->datasize = pos+CYGNUM_RAMFS_REALLOC_INCREMENT;
@@ -730,7 +731,7 @@ static int findbuffer_direct( off_t pos,
     ramfs_block *b;
     
     *buffer = NULL;
-    *size = 0;
+    *size = CYGNUM_RAMFS_BLOCK_SIZE - bpos;
     
     if( bi >= nblocks )
         return ENOERR;
@@ -740,8 +741,9 @@ static int findbuffer_direct( off_t pos,
     if( b == NULL )
     {
         // There is no block there. If _alloc_ is true we can fill the
-        // slot in with a new block. If it is false, we indicate end of
-        // data with a zero size result.
+        // slot in with a new block. If it is false, we indicate there
+        // is no block and size indicates where the block would end if
+        // it existed.
         if( alloc )
         {
             b = block_alloc();
@@ -753,7 +755,6 @@ static int findbuffer_direct( off_t pos,
     }
 
     *buffer = &((*b)[bpos]);
-    *size = CYGNUM_RAMFS_BLOCK_SIZE - bpos;
 
     return ENOERR;
 }
@@ -1491,7 +1492,7 @@ static int ramfs_mount    ( cyg_fstab_en
     
     // Allocate a node to be the root of this filesystem and initialize it.
 
-    root = alloc_node(__stat_mode_DIR);
+    root = alloc_node(__stat_mode_DIR|S_IRWXU|S_IRWXG|S_IRWXO);
 
     if( root == NULL )
         return ENOSPC;
@@ -1565,7 +1566,7 @@ static int ramfs_open     ( cyg_mtab_ent
             // create a new one. The dir and name fields of the dirsearch
             // object will have been updated so we know where to put it.
 
-            node = alloc_node( __stat_mode_REG );
+            node = alloc_node( __stat_mode_REG|S_IRWXU|S_IRWXG|S_IRWXO);
 
             if( node == NULL )
                 return ENOSPC;
@@ -1669,7 +1670,7 @@ static int ramfs_mkdir    ( cyg_mtab_ent
             // the pathname, so we can create it here.
             int doterr, dotdoterr, direrr;
         
-            node = alloc_node( __stat_mode_DIR );
+            node = alloc_node( __stat_mode_DIR | S_IRWXU|S_IRWXG|S_IRWXO);
 
             if( node == NULL )
                 return ENOSPC;
@@ -2058,10 +2059,14 @@ static int ramfs_fo_read      (struct CY
             // at present.
             if( l > bsize )
                 l = bsize;
-
-            // copy data out
-            memcpy( buf, fbuf, l );
-
+            
+            if (fbuf) {
+              // copy data out
+              memcpy( buf, fbuf, l );
+            } else { // hole, so return zeros here.
+              memset( buf, 0, l );
+            }
+ 
             // Update working vars
             len -= l;
             buf += l;
@@ -2098,10 +2103,6 @@ static int ramfs_fo_write     (struct CY
     if( fp->f_flag & CYG_FAPPEND )
         pos = fp->f_offset = node->size;
     
-    // Check that pos is within current file size, or at the very end.
-    if( pos < 0 || pos > node->size )
-        return EINVAL;
-
     // Now loop over the iovecs until they are all done, or
     // we get an error.
     for( i = 0; i < uio->uio_iovcnt; i++ )
@@ -2186,11 +2187,6 @@ static int ramfs_fo_lseek     (struct CY
         return EINVAL;
     }
     
-    // Check that pos is still within current file size, or at the
-    // very end.
-    if( pos < 0 || pos > node->size )
-        return EINVAL;
-
     // All OK, set fp offset and return new position.
     *apos = fp->f_offset = pos;
     
--- a/packages/fs/ram/current/tests/ramfs2.c
+++ b/packages/fs/ram/current/tests/ramfs2.c
@@ -166,9 +166,75 @@ int main( int argc, char **argv )
     err = fclose(stream);
     if (err != 0) SHOW_RESULT( fclose, err );
 
+    CYG_TEST_INFO("open file /fseek");
+    stream = fopen("/fseek", "r+");
+    if (!stream) {
+      diag_printf("<FAIL>: fopen() returned NULL, %s\n", strerror(errno));
+    }
+
+    CYG_TEST_INFO("fseek()ing past the end to create a hole");
+    /* Seek 1K after the end of the file */
+    err = fseek(stream, sizeof(buf), SEEK_END);
+    if ( err < 0 ) SHOW_RESULT( fseek, err );
+
+    pos = ftell(stream);
+    
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != (2*sizeof(buf))) CYG_TEST_FAIL("ftell is not telling the truth");
+    
+    CYG_TEST_INFO("writing test pattern");    
+    err=fwrite(buf,sizeof(buf), 1, stream);
+    if ( err < 0 ) SHOW_RESULT( fwrite, err );
+    
+    pos = ftell(stream);
+    
+    if (pos < 0) SHOW_RESULT( ftell, pos );
+    if (pos != (3*sizeof(buf))) CYG_TEST_FAIL("ftell is not telling the truth");
+
+    CYG_TEST_INFO("closing file");
+    err = fclose(stream);
+    if (err != 0) SHOW_RESULT( fclose, err );
+
+    CYG_TEST_INFO("open file /fseek");
+    stream = fopen("/fseek", "r+");
+    if (!stream) {
+      diag_printf("<FAIL>: fopen() returned NULL, %s\n", strerror(errno));
+    }
+    
+    err = fread(buf1,sizeof(buf1),1, stream);
+    if (err != 1) SHOW_RESULT( fread, err );
+    
+    CYG_TEST_INFO("Comparing contents");
+    if (memcmp(buf, buf1, sizeof(buf1))) {
+      CYG_TEST_FAIL("File contents inconsistent");
+    }
+
+    err = fread(buf1,sizeof(buf1),1, stream);
+    if (err != 1) SHOW_RESULT( fread, err );
+    
+    for (i = 0; i< sizeof(buf); i++) {
+      if (buf1[i] != 0)
+        CYG_TEST_FAIL("Hole does not contain zeros");
+    }
+    
+    err = fread(buf1,sizeof(buf1),1, stream);
+    if (err != 1) SHOW_RESULT( fread, err );
+    
+    if (memcmp(buf, buf1, sizeof(buf1))) {
+      CYG_TEST_FAIL("File contents inconsistent");
+    }
+
+    CYG_TEST_INFO("closing file");
+
+    /* Close the file */
+    err = fclose(stream);
+    if (err != 0) SHOW_RESULT( fclose, err );
+    
     CYG_TEST_INFO("umount /");    
     err = umount( "/" );
     if( err < 0 ) SHOW_RESULT( umount, err );    
     
     CYG_TEST_PASS_FINISH("ramfs2");
+
+
 }