![]() |
|||||||||
The AROS Filesystem InterfaceΣημείωση This document is currently only a draft and will most likely change before it is accepted as an official specification. It might also be deprecated if a better aproach has been found and might not correspond precisely with the current implementation.
IntroductionNormally, as an application programmer, you don't have to worry about the filesystem interface -- you can do everything you want via simple calls to DOS. However you may need to know how to interface with a filesystem if you:
Of the above the most useful of these would be doing asynchronous I/O, although it is in many cases better to use one of the publically available libraries to do this, as it will hide from you the implementation of the filesystems. It's completely differentThe interface to filesystems is different under AROS compared to AmigaOS in many ways:
Obviously this change renders the filesystem incompatible to the current AmigaOS filesystems and DOS implementation. However it should be possible to build a bridge between the filesystems if necessary. Filesystem devicesThe major API change with filesystems is that they now use the Exec Device API. You can use the normal device functions (DoIO(), AbortIO(), etc). The I/O Request structure is defined in dos/filesystems.h:
/* IORequest from <exec/io.h> */
struct IORequest
{
struct Message io_Message;
struct Device *io_Device; /* filesystem base pointer */
struct Unit *io_Unit; /* file or directory handle */
UWORD io_Command; /* the command */
UBYTE io_Flags; /* normal device flags (IOF_QUICK) */
BYTE io_Error; /* error code from device functions */
};
struct IOFileSys
{
struct IORequest IOFS;
LONG io_DosError; /* secondary error code (IoErr()) */
union {} io_Union; /* arguments - command dependant */
};
The io_DosError field is used to return the secondary error code to the caller. This is the code that is returned by the dos.library function IoErr(). The io_Error`field of `struct IORequest should only be used to return a simple failure/success for filesystem commands, and should have the normal effect for the device open/close commands. The io_Union field is an union containing different structures for each of the commands. This field has a variable length depending upon the command. The fields listed in the "Input" sections of the autodocs below refer to a specific member of this union. Command documentationOpenDevice()NameOpenDevice("*.handler", 0, iofs, 0); FunctionMount a new filesystem. The IOFileSys structure passed in iofs to the handler should contain enough information for the handler to mount the filesystem. If there is a volume mounted in this device, it is the responsibility of the handler to add the required volume nodes to the DOS device list before returning to the caller. Note here that the DOS device list is already locked, so you do not need to lock it yourself. The filesystem must return a handle to the device in the io_Unit pointer of the struct IOFileSys. The io_Error and io_DosError fields should be set appropriately for success or failure. Input
Result
CloseDevice()NameCloseDevice() FunctionTry and dismount a DOS device. If there are any mounted volumes in the device, the filesystem should remove them from the DOS device list. Note that the DOS device list will have already been locked by the caller, so you will not have to do this yourself. You should not dismount the device if there are still open files or outstanding locks. Input
ResultThe DOS device shall be dismounted if possible.
FSA_OPENNameFSA_OPEN FunctionCreate a handle to an existing file or directory. You can use this handle to read directories or read/write files. The filename io_Args[0] is relative to the path of the directory associated with the handle io_Unit. If io_Unit is NULL however, the filename should be taken as relative to the root directory of the device. This command uses the io_Union.io_OPEN member. Input
Result
FSA_CLOSENameFSA_CLOSE - close an open file FunctionClose a file or directory handle. You should write out any buffered data before returning. It is the responsibility of the filesystem to free the data pointed to by io_Unit. Input
Result
FSA_READNameFSA_READ FunctionTry and read the requested number of bytes from the filehandle. A handler will normally try and fulfill the request completely, but special handlers (such as the console) may return less than the requested number of bytes. If you reach the end of the file, you should return the number of bytes read in the current attempt. On the next call you should return 0 for EOF. Any further attempts to read should result in a return of -1 with an error code. This function uses the io_Union.io_READ_WRITE field. Input
ResultThe buffer io_Buffer should contain some data if it was possible to read any.
FSA_WRITENameFSA_WRITE - Write to a file FunctionTry to write the requested number of bytes to the filehandle. A handler should try and fulfill the request completely, but special handlers may write less than the requested number of bytes. If you cannot write any bytes return 0 in io_Length. This command uses the io_Union.io_READ_WRITE member. Input
ResultThe contents of the buffer should have been written to the stream.
FSA_SEEKNameFSA_SEEK - Seek within a file. FunctionThis command shall change the position of the next read or write in the file. The command will also return the old position in the file. FIXME: Error condition for seeking before the start, and after the end of file. This command uses the io_Union.io_SEEK member. NotesA command with io_Offset == 0, and io_SeekMode == OFFSET_CURRENT is a NOP in terms of seeking and will simply return the current file position. Input
Result
FSA_SET_FILE_SIZENameFSA_SET_FILE_SIZE - Set the size of a file. FunctionChange the size of a file. If the old file size is less than the new size, then the file is simply truncated. If the file is made larger, then the data contained in the new section is invalid. This command uses the io_Union.io_SEEK member. Input
NotesNot all handlers will support this command. FSA_WAIT_CHARNameFSA_WAIT_CHAR - wait for a character to arrive FunctionThis command will wait for a character to be ready for reading. You should only wait for a maximum of io_Timeout microseconds. If io_Timeout is 0, then you should wait indefinately. This command can be used on both plain files and interactive files. For plain files it should return immediately, unless for some reason there is no data available (a PIPE or a network file where there is no data yet). This command uses the io_Union.io_WAIT_CHAR member. Input
Result
FSA_FILE_MODENameFSA_FILE_MODE - set the mode of a file FunctionApply a new mode to the file. This command uses a mask to define which of the modes should be changed. Supplying a mask of 0 will return the current set of modes. This command uses the io_Union.io_FILE_MODE member. Input
ResultThe modes should be set to those described by the mask and mode flags.
FSA_IS_INTERACTIVENameFSA_IS_INTERACTIVE - is this file a terminal FunctionQuery the filesystem as to whether this file is a interactive terminal. This function uses the io_Union.io_IS_INTERACTIVE member. Input
Result
FSA_SAME_LOCKNameFSA_SAME_LOCK - are two locks the same? FunctionThis function will compare two locks, and return whether the refer to the same object in the filesystem. This command uses the io_Union.io_SAME_LOCK member. Input
Result
FSA_EXAMINENameFSA_EXAMINE - example a file or directory FunctionThis command will obtain information about the current file or directory and return it in the ExAllData structure passed in. We do not support passing filesystems the FileInfoBlock structure as that has limits upon the size of paths. The AROS dos.library will handle the translation between the two structures. You need only return the information requested, which is determined by the value in io_Mode. This command uses the io_Union.io_EXAMINE. Input
Result
FSA_EXAMINE_ALLNameFSA_EXAMINE_ALL - Examine the contents of a directory FunctionRead the directory information of the current file or directory. If the handle is for a file, then you need only fill in the information for that file. You need only fill in the information requested by the caller. You should continue filling in information in the buffer until you run out of space. The ed_Next fields of the ExAllData structure are used to link the entries together. The last entry should have ed_Next = NULL. Entries should be aligned to the size of the system pointer datatype. If io_DosError != 0, then the contents of the buffer is undefined. If you need space to store filenames, comments strings, etc these should be placed at the end of the buffer. Input
Result
FSA_EXAMINE_ALL_ENDNameFSA_EXAMINE_ALL_END - Finish examining a number of files. FunctionFinish examining a number of objects in the filesystem. This is used to reset the filesystems internal state if required. This command does not use the io_Union field. Input
Result
FSA_OPEN_FILENameFSA_OPEN_FILE FunctionOpen a handle onto a file, creating the file if necessary. This command only works on files, not directories. FunctionOpen a handle onto a file, creating the file if necessary. This command one io_Filename field gives the name of the file, which is relative to the handle passed in io_Unit. If the io_Unit handle is NULL, then the file is relative to the root of the directory tree. This command also allows you to change the protection bits of the file. Input
Result
FSA_CREATE_DIRNameFSA_CREATE_DIR - Create a new directory FunctionThis command tells the filesystem to create a new directory, lock it, and return a handle to the lock. The directory should be created with the modes given in io_Args[1]. FIXME: Is the lock read or write? The lock should be relative to the handle in io_Unit, or to the root directory if io_Unit == NULL. Input
ResultThe directory requested exists if it could be created.
FSA_CREATE_HARDLINKNameFSA_CREATE_HARDLINK - Create a hard link to a file. FunctionCreate a hard link to a file. There is no difference between a hard link and its original file. If the original file is deleted, the data will still exist because of the link. Hard links can not point across devices. This command uses the io_Union.io_CREATE_HARDLINK member. Input
ResultA hard link will have been created if possible.
FSA_CREATE_SOFTLINKNameFSA_CREATE_SOFTLINK - Create a soft link to a file. FunctionCreate a soft link to a file. There is a difference between a soft link and its original file. If the original file is deleted, the soft link will no longer be valid (but it will not be deleted). As soft links are stored as the filename of the link to file, they can be used across devices. This means that the filename stored must be an absolute filename, as the current directory will be unknown at read time. This command uses the io_Union.io_CREATE_SOFTLINK member. Input
ResultA soft link will have been created if possible.
FSA_RENAMENameFSA_RENAME - Rename an object in the filesystem FunctionRename an object in the filesystem. This function may be called on a file which doesn't exist. The filenames specified should be considered relative to io_Unit which specifies the current directory (or NULL for the root directory). Renaming a directory is equivalent to moving the entire contents of the directory. This command uses the io_Union.io_RENAME member. Input
Result
FSA_READ_SOFTLINKNameFSA_READ_SOFTLINK - Read the name of a softlinked file. FunctionThis command will read the name of the file referenced by file io_Unit. The filename returned is an absolute filename. This command uses the io_Union.io_READ_SOFTLINK member. Input
ResultThe buffer io_Buffer will contain the absolute filename that this link refers to.
FSA_DELETE_OBJECTNameFSA_DELETE_OBJECT - Delete an object from the filesystem FunctionDelete a given file or directory. It is illegal to try and delete a directory which contains files - you should return ERROR_DIRECTORY_NOT_EMPTY if an attempt is made. Files with outstanding handles cannot be deleted. If the io_Unit handle is NULL, the file to delete is relative to the root of the filesystem. Input
Result
FSA_SET_COMMENTNameFSA_SET_COMMENT - Set the comment of an object FunctionSet a new comment for a file or directory. The maximum length for a comment has historically been 80 characters (including NULL termination). Input
FSA_SET_PROTECTNameFSA_SET_PROTECT - Set protection bits for a file FunctionSet the protection bits on a file or directory. Note that there are four groups of protection bits:
You should note that the owner bits are handled a bit strangely as they are active low (ie 0 means enabled/set). Note that if io_Unit is valid (ie non-NULL), and io_Args[0] is NULL then you should change the mode of the object described by the io_Unit handle. Input
FSA_SET_OWNERNameFSA_SET_OWNER - Set the owner of a file FunctionThis command allows a user to set the ownership of files. The file should be changed to reflect the new owner of the directory. The owner and group fields in the arguments are interpreted as 32-bit values, however in general, they will only be 16-bit values. If the values are outside the 16-bit range, and you are unabled to handle the values then you can return an error. The ERROR_BAD_NUMBER appears to be the most appropriate error number. Special User ID's:
Special Group ID's:
Typically AmigaOS filesystems have had little multiuser support, and it should be expected that few filesystems will actually support this command. For security reasons, only the superuser or the owner of a file should be allowed to change the ownership. Input
FSA_SET_DATENameFSA_SET_DATE - Set the date of a file/directory FunctionSet the modification date of a file or directory. If the filesystem does not support the date, for example it is too old, then you should return ERROR_BAD_NUMBER. It should not be possible to set the creation date of an object (except by creating it). Input
FSA_IS_FILESYSTEMNameFSA_IS_FILESYSTEM - Ask the filesystem handler if it is a filesystem FunctionQuery the filesystem as to whether it is a proper filesystem. An example of something that is not a filesystem is a device handler like PAR:. This command uses the io_Union.io_IS_FILESYSTEM member. InputNone. Result
FSA_MORE_CACHENameFSA_MORE_CACHE - Add more cache buffers to the filesystem. FunctionAdd the number io_NumBuffers of cache buffers to the filesystem. The size of the buffer should have been given during the initial filesystem open. If the number of buffers is negative, then the result will be to remove buffers from the device. You can not have less than 0 buffers. This command uses the io_Union.io_MORE_CACHE member. Input
ResultThe number of buffers will have been altered if possible.
FSA_FORMATNameFSA_FORMAT - Initialise a filesystem FunctionInitialise a device to be used by this filesystem. The device media should have already been initialised, and this command simply gets the filesystem to write its own data. This command uses the io_Union.io_FORMAT member. Input
ResultThe filesystem will have been initialised, and is ready for mounting.
FSA_MOUNT_MODENameFSA_MOUNT_MODE FunctionChange or read the mount modes of the volume passed in io_Unit. The mask is used to select which modes are to be changed. This command uses the io_Union.io_MOUNT_MODE member. Input
Result
|
Πνευματικά Δικαιώματα © 1995-2008, Η Ομάδα Ανάπτυξης του AROS (The AROS Development Team). All rights reserved. Amiga® is a trademark of Amiga Inc. All other trademarks belong to their respective owners. |