FAT FS enhancements

David Brennan eCos@brennanhome.com
Thu Oct 21 05:44:00 GMT 2004


Ok lets try this again. I decided that if using chmod with non-posix 
flags was not allowed, it made sense to just do all of the FAT attribing 
in a single call. I'm sure you will have other comments on this, but my 
only concern is I'm not sure if you will let me put the FAT flags and 
access macros in stat.h. It seems like a logical place, but it doesn't 
fit in with the POSIX'ness. I'd be happy to put them in any other file. 
(I'd also rather remove at least the bit level #defines from fat_supp.c 
and have it use the public ones, with whichever names you prefer.)

Let me know what names you want changed around, and if this is the 
proper structure for doing this type of change please.

Thanks
David Brennan

Andrew Lunn wrote:

>On Mon, Oct 18, 2004 at 08:46:15PM -0700, David Brennan wrote:
>  
>
>>This patch includes the changes to add a fssync function, chmod 
>>capabilities, and honor read only flag.  The chmod and honor attributes 
>>are configurable with a single CDL parameter. The fssync is not 
>>configurable.
>>    
>>
>
>There are a number of things i don't like about this patch. 
>
>chmod is part of POSIX. As such, it should stick to the POSIX standard
>as much as possible. 
>
>http://www.opengroup.org/onlinepubs/009695399/functions/chmod.html
>
>Various mode bits are also specified in POSIX
>
>http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html
>
>I would prefer that chmod() uses standard POSIX symantics. ie if you
>want a file to be read only, you remove the write bits. If a file on
>the filesystem is read only, stat() would return a mode with the write
>bits reset. If the "file" is a directory is should set S_IFDIR.
>
>Some of the FATFS attributes don't fit with POSIX. For hidden, system
>and archive i would add a fatfs specific FS_INFO_ATTRIB_FATFS key
>which could be used to set these attributes using setinfo() and
>calling getinfo() with the key would return the state of these
>attributes plus the volume attribute. Read only and directory is not
>needed here since you can get those using standard POSIX calls.
>
>fssync is not POSIX. I cannot find a POSIX equivelent system
>call. POSIX only has sync() which synchronises all filesystems.  So i
>suggest you rename this something like cyg_fs_fssync(), or you
>implement sync().
>
>        Thanks
>                Andrew
>
>
>  
>
Index: fs/fat/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/ChangeLog,v
retrieving revision 1.3
diff -U5 -w -r1.3 ChangeLog
--- fs/fat/current/ChangeLog    13 Oct 2004 21:11:37 -0000    1.3
+++ fs/fat/current/ChangeLog    21 Oct 2004 05:24:34 -0000
@@ -1,5 +1,18 @@
+2004-10-17  David Brennan  <eCos@brennanhome.com>
+
+        * src/fatfs.c:
+        * src/fatfs_supp.c:
+        * tests/fileio1.c:
+        * cdl/fatfs.cdl: Added configurable support for FAT filesystem
+        attributes.
+
+2004-10-13  David Brennan  <eCos@brennanhome.com>
+
+        * src/fatfs.c: Added code to setinfo to allow performing a 
file-system
+        sync
+
 2004-10-06  David Brennan  <eCos@brennanhome.com>
 
     * tests/fileio1.c: Added include of <stdio.h> to fix compiler
     warning for rename().
 
Index: fs/fat/current/cdl/fatfs.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/cdl/fatfs.cdl,v
retrieving revision 1.2
diff -U5 -w -r1.2 fatfs.cdl
--- fs/fat/current/cdl/fatfs.cdl    5 Oct 2004 07:45:59 -0000    1.2
+++ fs/fat/current/cdl/fatfs.cdl    21 Oct 2004 05:24:34 -0000
@@ -103,10 +103,18 @@
         active_if       CYGPKG_INFRA_DEBUG && CYGDBG_USE_ASSERTS
         description     "This option controls the inclusion of extra
                          sanity checks in node cache code."
     }
    
+    cdl_option      CYGCFG_FS_FAT_USE_ATTRIBUTES {
+        display         "Support for FAT FS file attributes"
+        flavor          bool
+        default_value   0
+        description     "This option controls if the FAT filesystem 
supports
+                         or honors the FAT filesystem file attributes."
+    }
+   
     # --------------------------------------------------------------------
    
     cdl_option      CYGPKG_FS_FAT_TESTS {
         display         "FAT FS tests"
         flavor          data
Index: fs/fat/current/src/fatfs.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/src/fatfs.c,v
retrieving revision 1.2
diff -U5 -w -r1.2 fatfs.c
--- fs/fat/current/src/fatfs.c    5 Oct 2004 07:45:59 -0000    1.2
+++ fs/fat/current/src/fatfs.c    21 Oct 2004 05:24:34 -0000
@@ -627,10 +627,17 @@
         return err;
    
     if (S_ISDIR(node->dentry.mode))
         return EISDIR;
 
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    // if the file is read only and is opened for writing
+    // fail with permission error
+    if (MODE_IS_RDONLY(node->dentry.attrib) && (mode & O_WRONLY))
+        return EPERM;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     // Allocate file object private data and
     // make a reference to this file node
 
     fd = alloc_fatfs_fd(disk, node);
     if (NULL == fd)
@@ -676,10 +683,16 @@
         return err;
 
     if (ds.node->refcnt > 0)
         return EBUSY;
    
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    // if the file is read only fail with permission error
+    if (MODE_IS_RDONLY(ds.node->dentry.attrib))
+        return EPERM;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     err = fatfs_delete_file(disk, &ds.node->dentry);
     if (err == ENOERR)
         fatfs_node_free(disk, ds.node);
    
     return err;
@@ -787,10 +800,16 @@
 
     err = fatfs_find(&ds1);
     if (err != ENOERR)
         return err;
 
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    // if the file is read only fail with permission error
+    if (MODE_IS_RDONLY(ds1.node->dentry.attrib))
+        return EPERM;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     // Protect the found nodes from being reused
     // by the search for the ds2 dir/node pair
     fatfs_node_ref(disk, ds1.dir);
     fatfs_node_ref(disk, ds1.node);
    
@@ -981,10 +1000,14 @@
         return err;
 
     // Fill in the status
    
     buf->st_mode   = ds.node->dentry.mode;
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    if (!MODE_IS_RDONLY(ds.node->dentry.attrib))
+        buf->st_mode |= (S_IWUSR | S_IWGRP | S_IWOTH);
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
     buf->st_ino    = (ino_t) ds.node->dentry.cluster;
     buf->st_dev    = 0;
     buf->st_nlink  = 1;
     buf->st_uid    = 0;
     buf->st_gid    = 0;
@@ -994,42 +1017,147 @@
     buf->st_ctime  = ds.node->dentry.ctime;
 
     return ENOERR;
 }
 
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+// 
-------------------------------------------------------------------------
+// fatfs_set_attrib()
+// Set FAT file system attributes for specified file
+
+static int
+fatfs_set_attrib(cyg_mtab_entry *mte,
+                 cyg_dir         dir,
+                 const char     *name,
+                 const cyg_fatfs_attrib_t  new_attrib)
+{
+    fatfs_disk_t      *disk = (fatfs_disk_t *) mte->data;
+    fatfs_dirsearch_t  ds;
+    int                err;
+
+    CYG_TRACE4(TFS, "chmod mte=%p dir=%p name='%s' buf=%x",
+                    mte, dir, name, new_attrib);
+
+    // Verify new_mode is valid
+    if ((new_attrib & S_FATFS_ATTRIB) != new_attrib)
+        return EINVAL;
+   
+    init_dirsearch(&ds, disk, (fatfs_node_t *) dir, name);
+
+    err = fatfs_find(&ds);
+    if (err != ENOERR)
+        return err;
+
+    // Change the "changeable" mode bits for the file.
+    ds.node->dentry.attrib = (ds.node->dentry.attrib & 
(~S_FATFS_ATTRIB)) | new_attrib;
+
+    return fatfs_write_dir_entry(disk,&ds.node->dentry);
+}
+
+// 
-------------------------------------------------------------------------
+// fatfs_get_attrib()
+// Set FAT file system attributes for specified file
+
+static int
+fatfs_get_attrib(cyg_mtab_entry *mte,
+                 cyg_dir         dir,
+                 const char     *name,
+                 cyg_fatfs_attrib_t * const file_attrib)
+{
+    fatfs_disk_t      *disk = (fatfs_disk_t *) mte->data;
+    fatfs_dirsearch_t  ds;
+    int                err;
+
+    CYG_TRACE4(TFS, "chmod mte=%p dir=%p name='%s' buf=%x",
+                    mte, dir, name, new_attrib);
+
+    init_dirsearch(&ds, disk, (fatfs_node_t *) dir, name);
+
+    err = fatfs_find(&ds);
+    if (err != ENOERR)
+        return err;
+
+    // Get the attribute field
+    CYG_CHECK_DATA_PTR(file_attrib,"Invalid destination attribute 
pointer");
+    *file_attrib = ds.node->dentry.attrib;
+
+    return ENOERR;
+}
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
 // 
-------------------------------------------------------------------------
 // fatfs_getinfo()
-// Getinfo. Nothing to support here at present.
+// Getinfo. Support for attrib
 
 static int
 fatfs_getinfo(cyg_mtab_entry *mte,
               cyg_dir         dir,
               const char     *name,
               int             key,
               void           *buf,
               int             len)
 {
+    int err;
+
     CYG_TRACE6(TFS, "getinfo mte=%p dir=%p name='%s' key=%d buf=%p len=%d",
                     mte, dir, name, key, buf, len);
-    return EINVAL;
+    err = EINVAL;
+
+    switch( key )
+    {
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+        case FS_INFO_ATTRIB:
+            err = fatfs_get_attrib(mte, dir, name, 
(cyg_fatfs_attrib_t*)buf);
+            if (err != ENOERR)
+               return err;
+            break;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+        default:
+            err = EINVAL;
+            break;
+    }
+    return err;
 }
 
 // 
-------------------------------------------------------------------------
 // fatfs_setinfo()
-// Setinfo. Nothing to support here at present.
+// Setinfo. Support for fssync and attrib
 
 static int
 fatfs_setinfo(cyg_mtab_entry *mte,
               cyg_dir         dir,
               const char     *name,
               int             key,
               void           *buf,
               int             len)
 {
-    CYG_TRACE6(TFS, "getinfo mte=%p dir=%p name='%s' key=%d buf=%p len=%d",
+    int err;
+
+    CYG_TRACE6(TFS, "setinfo mte=%p dir=%p name='%s' key=%d buf=%p len=%d",
                     mte, dir, name, key, buf, len);
-    return EINVAL;
+
+    err = EINVAL;
+
+    switch( key )
+    {
+        case FS_INFO_SYNC:
+            err = cyg_blib_sync(&(((fatfs_disk_t *) mte->data)->blib));
+            if (err != ENOERR)
+               return err;
+            break;
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+        case FS_INFO_ATTRIB:
+            err = fatfs_set_attrib(mte, dir, name, *(cyg_fatfs_attrib_t 
*)buf);
+            if (err != ENOERR)
+               return err;
+            break;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+        default:
+            err = EINVAL;
+            break;
+    }
+    return err;
 }
 
 //==========================================================================
 // File operations
 
Index: fs/fat/current/src/fatfs.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/src/fatfs.h,v
retrieving revision 1.2
diff -U5 -w -r1.2 fatfs.h
--- fs/fat/current/src/fatfs.h    5 Oct 2004 07:45:59 -0000    1.2
+++ fs/fat/current/src/fatfs.h    21 Oct 2004 05:24:35 -0000
@@ -122,10 +122,13 @@
     time_t            mtime;          // Last write timestamp
     cyg_uint8         priv_data;      // Private data
     cyg_uint32        cluster;        // First cluster number
     cyg_uint32        parent_cluster; // First cluster of parent dentry
     fatfs_data_pos_t  disk_pos;       // Position of dir entry on disk
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    cyg_fatfs_attrib_t    attrib;     // Attribute bits for DOS 
compatability
+#endif //CYGCFG_FS_FAT_USE_ATTRIBUTES
 } fatfs_dir_entry_t;
 
 typedef struct fatfs_node_s
 {
     fatfs_dir_entry_t    dentry;     // Dir entry data
Index: fs/fat/current/src/fatfs_supp.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/src/fatfs_supp.c,v
retrieving revision 1.2
diff -U5 -w -r1.2 fatfs_supp.c
--- fs/fat/current/src/fatfs_supp.c    5 Oct 2004 07:45:59 -0000    1.2
+++ fs/fat/current/src/fatfs_supp.c    21 Oct 2004 05:24:37 -0000
@@ -1622,10 +1622,14 @@
     if (DENTRY_IS_DIR(raw_dentry))
         dentry->mode = __stat_mode_DIR;
     else
         dentry->mode = __stat_mode_REG;
    
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    dentry->attrib = raw_dentry->attr;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     date_dos2unix(raw_dentry->crt_time, raw_dentry->crt_date, 
&dentry->ctime);
     date_dos2unix(0,                    raw_dentry->acc_date, 
&dentry->atime);
     date_dos2unix(raw_dentry->wrt_time, raw_dentry->wrt_date, 
&dentry->mtime);
    
     dentry->size       = raw_dentry->size;
@@ -1645,10 +1649,14 @@
 
     if (__stat_mode_DIR == dentry->mode)
         raw_dentry->attr = DENTRY_ATTR_DIR;
     else
         raw_dentry->attr = DENTRY_ATTR_ARCHIVE;
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    raw_dentry->attr = dentry->attrib;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
        
     date_unix2dos(dentry->ctime, &raw_dentry->crt_time, 
&raw_dentry->crt_date);
     date_unix2dos(dentry->atime, NULL,                  
&raw_dentry->acc_date);
     date_unix2dos(dentry->mtime, &raw_dentry->wrt_time, 
&raw_dentry->wrt_date);
    
@@ -1806,10 +1814,18 @@
    
     strncpy(dentry->filename, name, namelen);
     dentry->filename[namelen] = '\0';
    
     dentry->mode  = mode;
+
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    if (S_ISDIR(dentry->mode))
+        dentry->attrib = S_FATFS_DIR;
+    else
+        dentry->attrib = S_FATFS_ARCHIVE;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     dentry->ctime =
     dentry->atime =
     dentry->mtime = cyg_timestamp();
 
     dentry->priv_data      = 0;
@@ -1937,10 +1953,13 @@
 {
     CYG_CHECK_DATA_PTRC(disk);
     CYG_CHECK_DATA_PTRC(dentry);
    
     dentry->mode           = __stat_mode_DIR;
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    dentry->attrib         = S_FATFS_DIR;
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
     dentry->size           = disk->fat_root_dir_size;
     dentry->ctime          = 0;
     dentry->atime          = 0;
     dentry->mtime          = 0;
     dentry->filename[0]    = '\0';
@@ -2387,11 +2406,11 @@
     target->disk_pos       = new_pos;
     target->parent_cluster = dir2->cluster;
 
     // If we moved a directory, we also have to correct the '..' entry 
 
-    if (__stat_mode_DIR == target->mode)
+    if ( S_ISDIR(target->mode) )
     {
         fat_raw_dir_entry_t raw_cdentry;
         fatfs_data_pos_t    pos;
       
         fatfs_initpos(disk, target, &pos);
Index: fs/fat/current/tests/fileio1.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/fs/fat/current/tests/fileio1.c,v
retrieving revision 1.2
diff -U5 -w -r1.2 fileio1.c
--- fs/fat/current/tests/fileio1.c    13 Oct 2004 21:11:38 -0000    1.2
+++ fs/fat/current/tests/fileio1.c    21 Oct 2004 05:24:38 -0000
@@ -58,10 +58,11 @@
 //==========================================================================
 
 #include <pkgconf/hal.h>
 #include <pkgconf/kernel.h>
 #include <pkgconf/io_fileio.h>
+#include <pkgconf/fs_fat.h>
 
 #include <cyg/kernel/ktypes.h>         // base kernel types
 #include <cyg/infra/cyg_trac.h>        // tracing macros
 #include <cyg/infra/cyg_ass.h>         // assertion macros
 
@@ -286,10 +287,30 @@
 
     err = close( fd );
     if( err < 0 ) SHOW_RESULT( close, err );
 }
 
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+//==========================================================================
+
+static void checkattrib(const char *name,
+                        const cyg_fatfs_attrib_t test_attrib )
+{
+    int err;
+    cyg_fatfs_attrib_t file_attrib;
+
+    diag_printf("<INFO>: check attrib %s\n",name);
+
+    err = cyg_get_attrib(name, &file_attrib);
+    if( err != 0 ) SHOW_RESULT( stat, err );
+
+    if ( (file_attrib & S_FATFS_ATTRIB) != test_attrib )
+        diag_printf("<FAIL>: attrib %s incorrect\n\tExpected %x Was %x\n",
+                    name,test_attrib,(file_attrib & S_FATFS_ATTRIB));
+}
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
 //==========================================================================
 
 static void copyfile( char *name2, char *name1 )
 {
 
@@ -641,18 +662,81 @@
     diag_printf("<INFO>: umount /disk2\n");   
     err = umount( "/disk2" );
     if( err < 0 ) SHOW_RESULT( umount, err );   
 #endif
    
+#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
+    // Create file
+    diag_printf("<INFO>: create /foo\n");
+    createfile( "/foo", 20257 );
+
+    // Verify it is created with archive bit set
+    checkattrib( "/foo", S_FATFS_ARCHIVE );
+
+    // Make it System
+    diag_printf("<INFO>: attrib -A+S /foo\n");
+    err = cyg_set_attrib( "/foo", S_FATFS_SYSTEM );
+    if( err < 0 ) SHOW_RESULT( chmod system , err );
+
+    // Verify it is now System
+    checkattrib( "/foo", S_FATFS_SYSTEM );
+
+    // Make it Hidden
+    diag_printf("<INFO>: attrib -S+H /foo\n");
+    err = cyg_set_attrib( "/foo", S_FATFS_HIDDEN );
+    if( err < 0 ) SHOW_RESULT( chmod system , err );
+
+    // Verify it is now Hidden
+    checkattrib( "/foo", S_FATFS_HIDDEN );
+
+    // Make it Read-only
+    diag_printf("<INFO>: attrib -H+R /foo\n");
+    err = cyg_set_attrib( "/foo", S_FATFS_RDONLY );
+    if( err < 0 ) SHOW_RESULT( chmod system , err );
+
+    // Verify it is now Read-only
+    checkattrib( "/foo", S_FATFS_RDONLY );
+
+    // Verify we cannot unlink a read-only file
+    diag_printf("<INFO>: unlink /foo\n");
+    err = unlink( "/foo" );
+    if( err != -EPERM ) SHOW_RESULT( unlink, err );
+
+    // Verify we cannot rename a read-only file
+    diag_printf("<INFO>: rename /foo bundy\n");
+    err = rename( "/foo", "bundy" );
+    if( err != -EPERM ) SHOW_RESULT( rename, err );
+
+    // Verify we cannot open read-only file for writing
+    int fd;
+    diag_printf("<INFO>: create file /foo\n");
+    fd = open( "/foo", O_WRONLY );
+    if( err != -EPERM ) SHOW_RESULT( rename, err );
+    if( err > 0 ) close(fd);
+
+    // Make it Normal
+    diag_printf("<INFO>: attrib -H /foo\n");
+    err = cyg_set_attrib( "/foo", 0 );
+    if( err < 0 ) SHOW_RESULT( chmod none , err );
+
+    // Verify it is now nothing
+    checkattrib( "/foo", 0 );
+
+    // Now delete our test file
+    diag_printf("<INFO>: unlink /foo\n");
+    err = unlink( "/foo" );
+    if( err < 0 ) SHOW_RESULT( unlink, err );
+
+#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES
+
     maxfile("file.max");
 
     listdir( "/", true, -1, NULL );   
        
     diag_printf("<INFO>: unlink file.max\n");   
     err = unlink( "file.max" );
     if( err < 0 ) SHOW_RESULT( unlink, err );   
-
     diag_printf("<INFO>: umount /\n");   
     err = umount( "/" );
     if( err < 0 ) SHOW_RESULT( umount, err );   
    
     CYG_TEST_PASS_FINISH("fileio1");
Index: io/fileio/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/ChangeLog,v
retrieving revision 1.48
diff -U5 -w -r1.48 ChangeLog
--- io/fileio/current/ChangeLog    14 Oct 2004 07:34:29 -0000    1.48
+++ io/fileio/current/ChangeLog    21 Oct 2004 05:24:56 -0000
@@ -1,5 +1,14 @@
+2004-10-13  David Brennan  <eCos@brennanhome.com>
+
+        * src/file.cxx: Added a check data ptr in LOCK_FS
+
+2004-10-13  David Brennan  <eCos@brennanhome.com>
+
+        * include/fileio.h: Added definition of FS_INFO_SYNC for cyg_fssync
+        command
+
 2004-10-06  David Brennan  <eCos@brennanhome.com>
 
     * tests/pselect.c: Added check for POSIX signals while building
     the test case.
     * tests/select.c: Include sys/select.h to prevent a possible warning.
Index: io/fileio/current/include/fileio.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/include/fileio.h,v
retrieving revision 1.10
diff -U5 -w -r1.10 fileio.h
--- io/fileio/current/include/fileio.h    1 Dec 2003 14:30:33 -0000    1.10
+++ io/fileio/current/include/fileio.h    21 Oct 2004 05:24:56 -0000
@@ -152,10 +152,12 @@
 // Keys for getinfo() and setinfo()
 
 #define FS_INFO_CONF            1       /* pathconf() */
 #define FS_INFO_ACCESS          2       /* access() */
 #define FS_INFO_GETCWD          3       /* getcwd() */
+#define FS_INFO_SYNC            4       /* cyg_fssync() */
+#define FS_INFO_ATTRIB          5       /* cyg_(get|set)_attrib() */
 
 //-----------------------------------------------------------------------------
 // Types for link()
 
 #define CYG_FSLINK_HARD         1       /* form a hard link */
@@ -168,10 +170,12 @@
 {
     char        *buf;           /* buffer for cwd string */
     size_t      size;           /* size of buffer */
 };
 
+typedef cyg_uint32 cyg_fatfs_attrib_t;
+
 //-----------------------------------------------------------------------------
 // Macro to define an initialized fstab entry
 
 #define FSTAB_ENTRY( _l, _name, _data, _syncmode, _mount, _umount,      \
                      _open, _unlink,  _mkdir, _rmdir, _rename, _link,   \
@@ -328,11 +332,11 @@
 #define    CYG_FILE_TYPE_FILE      1    /* file */
 #define    CYG_FILE_TYPE_SOCKET    2    /* communications endpoint */
 #define    CYG_FILE_TYPE_DEVICE    3    /* device */
 
 //-----------------------------------------------------------------------------
-// Keys for getinf() and setinfo()
+// Keys for getinfo() and setinfo()
 
 #define FILE_INFO_CONF          1       /* fpathconf() */
 
 //-----------------------------------------------------------------------------
 // Modes for fsync()
@@ -420,10 +424,25 @@
 // data strucures.
 
 __externC time_t cyg_timestamp(void);
 
 //=============================================================================
+// Miscellaneous functions.
+
+// Provide a function to synchronize an individual file system. (ie write
+// directory information to disk)
+__externC int cyg_fssync(const char *path);
+
+// Functions to provide the equivilent of DOS ATTRIB function. Only 
applicable
+// to FAT file systems at the moment.
+__externC int cyg_set_attrib( const char *fname,
+                              const cyg_fatfs_attrib_t new_attrib );
+__externC int cyg_get_attrib( const char *fname,
+                              cyg_fatfs_attrib_t * const file_attrib );
+
+
+//=============================================================================
 // Default functions.
 // Cast to the appropriate type, these functions can be put into any of
 // the operation table slots to provide the defined error code.
 
 __externC int cyg_fileio_enosys(void);
Index: io/fileio/current/src/file.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/src/file.cxx,v
retrieving revision 1.10
diff -U5 -w -r1.10 file.cxx
--- io/fileio/current/src/file.cxx    15 Mar 2004 15:41:36 -0000    1.10
+++ io/fileio/current/src/file.cxx    21 Oct 2004 05:24:56 -0000
@@ -69,10 +69,11 @@
 //==========================================================================
 // Implement filesystem locking protocol.
 
 #define LOCK_FS( _mte_ )  {                             \
    CYG_ASSERT(_mte_ != NULL, "Bad mount table entry");  \
+   CYG_ASSERT(_mte_->fs != NULL, "Bad mount filesystem entry");  \
    cyg_fs_lock( _mte_, (_mte_)->fs->syncmode);          \
 }
 
 #define UNLOCK_FS( _mte_ ) cyg_fs_unlock( _mte_, (_mte_)->fs->syncmode)
 
@@ -522,10 +523,103 @@
 
     FILEIO_RETURN_VALUE(info.value);
 }
 
 //==========================================================================
+// Sync filesystem without unmounting
+
+__externC int cyg_fssync( const char *path )
+{
+    FILEIO_ENTRY();
+   
+    int ret = 0;
+    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+    cyg_dir dir = cyg_cdir_dir;
+    const char *name = path;
+
+    ret = cyg_mtab_lookup( &dir, &name, &mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ENOENT);
+
+    LOCK_FS( mte );
+   
+    ret = mte->fs->setinfo( mte, dir, name, FS_INFO_SYNC, NULL, 0 );
+   
+    UNLOCK_FS( mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ret);
+
+    FILEIO_RETURN_VALUE(ENOERR);
+}
+
+//==========================================================================
+// Set file attributes
+
+__externC int cyg_set_attrib( const char *fname,
+                              const cyg_fatfs_attrib_t new_attrib )
+{
+    FILEIO_ENTRY();
+   
+    int ret = 0;
+    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+    cyg_dir dir = cyg_cdir_dir;
+    const char *name = fname;
+
+    ret = cyg_mtab_lookup( &dir, &name, &mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ENOENT);
+
+    LOCK_FS( mte );
+   
+    ret = mte->fs->setinfo( mte, dir, name,
+                            FS_INFO_ATTRIB,
+                            (char *)&new_attrib, sizeof(new_attrib) );
+   
+    UNLOCK_FS( mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ret);
+
+    FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
+// Get file attributes
+
+__externC int cyg_get_attrib( const char *fname,
+                              cyg_fatfs_attrib_t * const file_attrib )
+{
+    FILEIO_ENTRY();
+   
+    int ret = 0;
+    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+    cyg_dir dir = cyg_cdir_dir;
+    const char *name = fname;
+
+    ret = cyg_mtab_lookup( &dir, &name, &mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ENOENT);
+
+    LOCK_FS( mte );
+   
+    ret = mte->fs->getinfo( mte, dir, name,
+                            FS_INFO_ATTRIB,
+                            (char *)file_attrib, sizeof(*file_attrib) );
+   
+    UNLOCK_FS( mte );
+   
+    if( 0 != ret )
+        FILEIO_RETURN(ret);
+
+    FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
 // Access() function.
 // This simply piggybacks onto stat().
 
 extern int     access(const char *path, int amode)
 {
Index: io/fileio/current/tests/select.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/fileio/current/tests/select.c,v
retrieving revision 1.7
diff -U5 -w -r1.7 select.c
--- io/fileio/current/tests/select.c    14 Oct 2004 07:34:30 -0000    1.7
+++ io/fileio/current/tests/select.c    21 Oct 2004 05:24:58 -0000
@@ -82,10 +82,11 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/select.h>
 #include <errno.h>
 #include <string.h>
+#include <sys/select.h>                // select()
 
 #ifdef CYGPKG_NET
 #include <network.h>
 #include <arpa/inet.h>
 #define TEST_NET
Index: isoinfra/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/isoinfra/current/ChangeLog,v
retrieving revision 1.26
diff -U5 -w -r1.26 ChangeLog
--- isoinfra/current/ChangeLog    15 Mar 2004 15:20:22 -0000    1.26
+++ isoinfra/current/ChangeLog    21 Oct 2004 05:24:58 -0000
@@ -1,5 +1,9 @@
+2004-10-16  David Brennan <eCos@brennanhome.com>
+
+    * include/sys/stat.h: Added info for fat fs attributes
+
 2004-03-12  Jonathan Larmour  <jifl@eCosCentric.com>
 
     * cdl/isoinfra.cdl: Typo: CYGBLD_ISO_STDIO_FILEPOS ->
     CYGBLD_ISO_STDIO_FILEPOS_HEADER.
 
Index: isoinfra/current/include/sys/stat.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/isoinfra/current/include/sys/stat.h,v
retrieving revision 1.7
diff -U5 -w -r1.7 stat.h
--- isoinfra/current/include/sys/stat.h    15 Jul 2003 13:39:40 -0000    1.7
+++ isoinfra/current/include/sys/stat.h    21 Oct 2004 05:24:59 -0000
@@ -123,10 +123,33 @@
 #define S_IRWXO  (S_IROTH|S_IWOTH|S_IXOTH)
 
 #define S_ISUID  (1<<25)
 #define S_ISGID  (1<<26)
 
+// 
-------------------------------------------------------------------------
+// FAT filesystem dir entry attributes
+
+#define S_FATFS_RDONLY  (0x01) // Read only
+#define S_FATFS_HIDDEN  (0x02) // Hidden
+#define S_FATFS_SYSTEM  (0x04) // System
+#define S_FATFS_VOLUME  (0x08) // Volume label
+#define S_FATFS_DIR     (0x10) // Subdirectory
+#define S_FATFS_ARCHIVE (0x20) // Needs archiving
+
+// Mode bits which are allowed by chmod
+#define S_FATFS_ATTRIB   (S_FATFS_RDONLY | S_FATFS_HIDDEN | 
S_FATFS_SYSTEM | \
+                          S_FATFS_ARCHIVE)
+// 
-------------------------------------------------------------------------
+// mode FAT dir entry attributes macros
+
+#define MODE_IS_RDONLY(__mode)  ((__mode) & S_FATFS_RDONLY)
+#define MODE_IS_HIDDEN(__mode)  ((__mode) & S_FATFS_HIDDEN)
+#define MODE_IS_SYSTEM(__mode)  ((__mode) & S_FATFS_SYSTEM)
+#define MODE_IS_VOLUME(__mode)  ((__mode) & S_FATFS_VOLUME)
+#define MODE_IS_DIR(__mode)     ((__mode) & S_FATFS_DIR)
+#define MODE_IS_ARCHIVE(__mode) ((__mode) & S_FATFS_ARCHIVE)
+
 
 struct stat {
     mode_t  st_mode;     /* File mode */
     ino_t   st_ino;      /* File serial number */
     dev_t   st_dev;      /* ID of device containing file */



More information about the Ecos-patches mailing list