#172384 - Pate - Thu Feb 04, 2010 5:54 am
Hi!
A simple question: How do I change the ARCHIVE attribute of a file using libFAT?
In my DSx86 emulator I need to support the DOS chmod command http://www.ctyme.com/intr/rb-2803.htm which uses the DOS-style FAT attribute bits. If I have understood correctly, libFAT exports the UNIX-style chmod http://www.opengroup.org/onlinepubs/000095399/functions/chmod.html which does not handle the ARCHIVE attribute. Internally libFAT seems to behave just like the DOS version (as FAT is based on DOS features), but what is the best way to access the internals of libFAT from my program?
Thanks!
Pate
_________________
#172390 - elhobbs - Thu Feb 04, 2010 9:21 am
If you do not find a better way this may be a place to start... _FAT_syncToDisc in fatfile.c from the libfat source does appear to modify the archive bit. it gets called when a file is closed and it needs to be flushed to disc. it reads the directory entry from disc changes some things then writes it back to disc.
#172395 - Pate - Thu Feb 04, 2010 2:53 pm
Ok, thanks for the pointer! I'd certainly prefer to stay away from the libFAT internals, but I guess I can't avoid it completely.
Pate
_________________
#172397 - elhobbs - Thu Feb 04, 2010 3:38 pm
I may be wrong, but I do not think that modifying file attributes is in the std c library. I think it is OS specific. so perhaps an addition to libfat is in order?
#172404 - ninjalj - Fri Feb 05, 2010 12:50 am
The ARCHIVE bit is indeed DOS-specific.
My understanding of this issue goes:
- devkitARM apparently uses newlib,which, if it is the newlib I think, is a RedHat project for an embedded ISO-C (no Posix stuff) library.
- newlib has a struct devoptab_t which contains methods for device operations. It is defined in trunk/buildscripts/dkarm-eabi/patches/newlib-1.17.0.patch, as:
Code: |
+typedef struct {
+ const char *name;
+ int structSize;
+ int (*open_r)(struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
+ int (*close_r)(struct _reent *r, int fd);
+ ssize_t (*write_r)(struct _reent *r, int fd, const char *ptr, size_t len);
+ ssize_t (*read_r)(struct _reent *r, int fd, char *ptr, size_t len);
+ off_t (*seek_r)(struct _reent *r, int fd, off_t pos, int dir);
+ int (*fstat_r)(struct _reent *r, int fd, struct stat *st);
+ int (*stat_r)(struct _reent *r, const char *file, struct stat *st);
+ int (*link_r)(struct _reent *r, const char *existing, const char *newLink);
+ int (*unlink_r)(struct _reent *r, const char *name);
+ int (*chdir_r)(struct _reent *r, const char *name);
+ int (*rename_r) (struct _reent *r, const char *oldName, const char *newName);
+ int (*mkdir_r) (struct _reent *r, const char *path, int mode);
+
+ int dirStateSize;
+
+ DIR_ITER* (*diropen_r)(struct _reent *r, DIR_ITER *dirState, const char *path);
+ int (*dirreset_r)(struct _reent *r, DIR_ITER *dirState);
+ int (*dirnext_r)(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat);
+ int (*dirclose_r)(struct _reent *r, DIR_ITER *dirState);
+ int (*statvfs_r)(struct _reent *r, const char *path, struct statvfs *buf);
+ int (*ftruncate_r)(struct _reent *r, int fd, off_t len);
+ int (*fsync_r)(struct _reent *r, int fd);
+ void *deviceData;
+} devoptab_t;
|
So, no {Set,Get}Attributes here.
-libfat registers itself with newlib via a devoptab.
So, you'd need to add a couple of new fields to the devoptab_t struct. It won't get upstreamed in newlib, since it is so OS-specific.
#172406 - elhobbs - Fri Feb 05, 2010 1:10 am
wouldn't making a SetFileAttribute function in libfat make more sense then modifying newlib? certainly much less work.
#172408 - ninjalj - Fri Feb 05, 2010 1:34 am
I just got too carried looking if there was a proper way to do it, and once I found there wasn't, I didn't even think of stepping back. So much for posting this late at night.
#172409 - Dwedit - Fri Feb 05, 2010 1:49 am
GBA_NDS_FAT had the ability to get and set attributes, why not libfat?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#172771 - wintermute - Tue Mar 02, 2010 1:37 pm
Digging around I found the POSIX (f)chflags functions which seem suitable, I'll look into implementing these soon.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#172834 - ninjalj - Sat Mar 06, 2010 3:44 pm
<pedantic>
chflags is not in POSIX, it's BSD 4.4.
</pedantic>
#172836 - wintermute - Sat Mar 06, 2010 4:36 pm
some of the documentation seems to imply that it's a BSD derived function that's been added to POSIX but, either way, seems like a suitable means for setting hidden & archive attributes for us :p
Actually though, I can't seem to find a standard way to access these flags, if I'm going to have to extend st_mode in stat to show the flags I might as well just extend the flags recognised by chmod. Any thoughts?
#173079 - wintermute - Fri Mar 19, 2010 6:11 pm
Found it in the end, there's an st_flags entry in the stat structure for these flags.
Just finished adding the extensions to newlib, now for some testing. devkitARM r29 & libfat 1.0.8 should support this :)
also bumping this thread so I can find it again.
edit: and now I'm pulling the (f)chflags functions again, this isn't the solution I thought it was going to be, fatGetAttr & fatSetAttr functions for libfat will work better. There isn't access to all the DOS flags with the bsd functions and the SF_ARCHIVED bit has the opposite sense to thd DOS one :/
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#173147 - Pate - Wed Mar 24, 2010 5:55 am
Cool, thanks for working on this issue, and sorry I haven't been following this thread more closely, been busy with other issues.
So, do I understand correctly, next release should have fatGetAttr and fatSetAttr, but the current devkitARM r29 version does not yet?
Thanks again!
Pate
_________________
#173175 - wintermute - Wed Mar 24, 2010 11:21 pm
I've decided to add these functions to libfat rather than chain them through newlib since they're FAT specific and there appears to be no suitable standard function to handle the flags. The next libfat update should include them, hopefully pretty soon.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog