This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RAMFS fixes: file permissions and lseek()


Attached for your review is a patch for the RAMFS filesystem which addresses the following items:

2005-05-29 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 filesystems from 000 to 777. This helps
applications which check for the existence of certain file
permissions.


       (ramfs_fo_write, ramfs_fo_lseek) Fixed the RAMFS implementation
   of lseek()
       to make it POSIX-compliant.  The previous implementation did not
   handle
       lseek()'s beyond the EOF.

The POSIX documentation for lseek() says:

   The /lseek/() function shall allow the file offset to be set beyond
   the end of the existing data in the file. If data is later written
   at this point, subsequent reads of data in the gap shall return
   bytes with the value 0 until data is actually written into the gap.

The /lseek/() function shall not, by itself, extend the size of a file.

Thanks,

--
Dan Jakubiec
Systech Corporation

Index: ecos/packages/fs/ram/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/ram/current/ChangeLog,v
retrieving revision 1.15
diff -u -5 -p -r1.15 ChangeLog
--- ecos/packages/fs/ram/current/ChangeLog	27 Mar 2005 18:21:15 -0000	1.15
+++ ecos/packages/fs/ram/current/ChangeLog	30 Sep 2005 00:29:30 -0000
@@ -1,5 +1,16 @@
+2005-05-29  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 filesystems from 000 to 777.  This helps
+	applications which check for the existence of certain file permissions.
+
+	(ramfs_fo_write, ramfs_fo_lseek) Fixed the RAMFS implementation of lseek()
+	to make it POSIX-compliant.  The previous implementation did not handle
+	lseek()'s beyond the EOF.
+
 2005-03-27  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* tests/ramfs1.c (SHOW_RESULT): Fixed compiler warning about format
 	not matching type.
 
Index: ecos/packages/fs/ram/current/src/ramfs.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/ram/current/src/ramfs.c,v
retrieving revision 1.8
diff -u -5 -p -r1.8 ramfs.c
--- ecos/packages/fs/ram/current/src/ramfs.c	15 Mar 2004 17:17:10 -0000	1.8
+++ ecos/packages/fs/ram/current/src/ramfs.c	30 Sep 2005 00:29:32 -0000
@@ -1489,11 +1489,11 @@ static int ramfs_mount    ( cyg_fstab_en
     ramfs_node *root;
     int err;
     
     // 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;
 
     // Add . and .. entries back to self.
@@ -1563,11 +1563,11 @@ static int ramfs_open     ( cyg_mtab_ent
         {
             // No node there, if the O_CREAT bit is set then we must
             // 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;
 
             err = add_direntry( ds.dir, ds.name, ds.namelen, node );
@@ -1667,11 +1667,11 @@ static int ramfs_mkdir    ( cyg_mtab_ent
         {
             // The entry does not exist, and it is the last element in
             // 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;
 
             // Add "." and ".." entries.
@@ -2096,52 +2096,82 @@ static int ramfs_fo_write     (struct CY
     // If the APPEND mode bit was supplied, force all writes to
     // the end of the file.
     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 )
+    // Check that pos is valid.
+    if( (pos < 0) || (pos > RAMFS_FILESIZE_MAX) )
         return EINVAL;
 
+    // If the current file position has been set beyond the end of the file,
+    // then we must now zero-fill the unwritten area before adding new data.
+    while( pos > node->size )
+    {
+        cyg_uint8 *fbuf;
+        size_t bsize;
+        off_t num_zero = pos - node->size;
+
+        // Get the next chunk of buffer space
+        err = findbuffer_node( node, node->size, &fbuf, &bsize, true );
+
+        // Stop writing if there is no more space in the file.
+        if( err == ENOSPC )
+        {
+            pos = node->size;
+            break;
+        }
+        if( err != ENOERR )
+            return err;
+        
+        // Zero-fill as many bytes as possible/necessary in the current block.
+        if( num_zero > bsize )
+            num_zero = bsize;
+        memset( fbuf, 0, num_zero );
+        node->size += num_zero;
+    }
+
     // Now loop over the iovecs until they are all done, or
     // we get an error.
-    for( i = 0; i < uio->uio_iovcnt; i++ )
+    if ( err == ENOERR)
     {
-        cyg_iovec *iov = &uio->uio_iov[i];
-        char *buf = (char *)iov->iov_base;
-        off_t len = iov->iov_len;
-
-        // loop over the vector writing it to the file until it has
-        // all been done.
-        while( len > 0 )
+        for( i = 0; i < uio->uio_iovcnt; i++ )
         {
-            cyg_uint8 *fbuf;
-            size_t bsize;
-            off_t l = len;
-            
-            err = findbuffer_node( node, pos, &fbuf, &bsize, true );
-
-            // Stop writing if there is no more space in the file and
-            // indicate end of data.
-            if( err == ENOSPC )
-                break;
-            
-            if( err != ENOERR )
-                return err;
-            
-            // adjust size to this block
-            if( l > bsize )
-                l = bsize;
-
-            // copy data in
-            memcpy( fbuf, buf, l );
+            cyg_iovec *iov = &uio->uio_iov[i];
+            char *buf = (char *)iov->iov_base;
+            off_t len = iov->iov_len;
+
+            // loop over the vector writing it to the file until it has
+            // all been done.
+            while( len > 0 )
+            {
+                cyg_uint8 *fbuf;
+                size_t bsize;
+                off_t l = len;
+                
+                err = findbuffer_node( node, pos, &fbuf, &bsize, true );
 
-            // Update working vars
-            len -= l;
-            buf += l;
-            pos += l;
-            resid -= l;
+                // Stop writing if there is no more space in the file and
+                // indicate end of data.
+                if( err == ENOSPC )
+                    break;
+                
+                if( err != ENOERR )
+                    return err;
+                
+                // adjust size to this block
+                if( l > bsize )
+                    l = bsize;
+
+                // copy data in
+                memcpy( fbuf, buf, l );
+
+                // Update working vars
+                len -= l;
+                buf += l;
+                pos += l;
+                resid -= l;
+            }
         }
     }
 
     // We wrote some data successfully, update the modified and access
     // times of the node, increase its size appropriately, and update
@@ -2150,11 +2180,12 @@ static int ramfs_fo_write     (struct CY
     node->ctime = cyg_timestamp();
     if( pos > node->size )
         node->size = pos;    
 
     uio->uio_resid = resid;
-    fp->f_offset = pos;
+    if( fp->f_offset < pos )
+        fp->f_offset = pos;
     
     return err;
 }
 
 // -------------------------------------------------------------------------
@@ -2184,13 +2215,12 @@ static int ramfs_fo_lseek     (struct CY
 
     default:
         return EINVAL;
     }
     
-    // Check that pos is still within current file size, or at the
-    // very end.
-    if( pos < 0 || pos > node->size )
+    // Check that pos is valid.  It's okay for it go beyond the end of file.
+    if( (pos < 0) || (pos > RAMFS_FILESIZE_MAX) )
         return EINVAL;
 
     // All OK, set fp offset and return new position.
     *apos = fp->f_offset = pos;
     


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]