AROS Application Development Manual -- The DOS Library
Warning
This document is not finished! It is highly likely that many parts are out-of-date, contain incorrect information, or are simply missing altogether. If you want to help rectify this, please contact us.
Contents
Program execution
All AROS programs must return a program execution status. This status expresses, whether the program was executed successful, and if not, how serious the case of failure was. In dos/dos.h the following constants are defined, which represent the standard return states:
RETURN_OK is returned if the program executed successfully.
RETURN_WARN means that the program executed successfully, but there was something not quite right. For example, this could be returned if a temporary file could not be deleted after use.
RETURN_WARN is also returned to express a boolean state. In this case RETURN_WARN means true, while RETURN_OK means false.
RETURN_ERROR is returned on errors that caused the execution of the program to fail partly.
RETURN_FAIL is returned if the execution of the program failed completely.
As an alternative you can use the ANSI C return codes EXIT_SUCCESS and EXIT_FAILURE.
Files and directories
Paths
FIXME: relative and absolute paths
Directories
FIXME
Links
Links are a method to apply multiple filenames to the same physical file or directory. This way, the file can be available in multiple directories with different filenames. There are two different types of links: hard links and soft links. A soft link is just a reference to another file by its name. This name may be stated as relative or absolute path. If a soft link is accessed, AROS tries to resolve the name of the file the link points to and redirects all actions to that file. Of course, the file pointed to does not have to exist. It may have been deleted after the link was created. Hard links are added entries for the same file. They don't reference the file by its name, they directly access its content. Normally, a hard link can't be distinguished from the original filename; effectively the file has been given a second name. Obviously, while soft links can link from one volume to another, hard links are always on one volume with the original entry for the file.
Note
Not all file systems support both types of links or any links at all.
FIXME
Low level file access
FIXME: Write about file handlers.
Tasks, Processes and the Shell
Tasks
AROS is a multitasking operating system. This essentially means that multiple programs may be run at the same time. Every program running is called a task. But there are also tasks that are not user-programs. There are, for example, tasks handling the file-system and tasks watching the input devices. Every task gets a certain amount of time, in which it is running. After this time it's the next task's turn; the system reschedules the tasks.
Plain tasks are very limited in their capabilities. Plain tasks must not call a function of dos.library or a function that could call a function of dos.library (this includes OpenLibrary() for most cases!). Processes don't have this limitation.
The Task Structure
A task is described by a struct Task as defined in exec/tasks.h. This structure contains information about the task like the its stack, its signals and some management data. To get the address of a task structure, use:
#include <proto/exec.h> struct Task *FindTask( STRPTR name );
The name is a pointer to the name of the task to find. Note that this name is case-sensitive! If the named task is not found, NULL is returned, otherwise a pointer to a struct Task is returned .
To get a pointer to the current task, supply NULL as name. This can never fail.
The task structure contains a field called tc_UserData. You can use this for your own purposes. It's ignored by AROS.
States
A task must be in one of following states (as set in the field tc_State of the task structure):
- TS_INVALID
- This state should never be set!
- TS_ADDED
- FIXME
- TS_RUN
- The task is currently running. On single processor architectures, only one task can be in that state.
- TS_READY
- The task is waiting for its activation.
- TS_WAIT
- The task is waiting on some .. FIXME: signal. As long as this does not occur, the program doesn't become active; it is ignored on rescheduling. Most interactive programs are in this state most of the time, as they wait for user input.
- TS_EXCEPT
- The task is in an exception.
- TS_REMOVED
- FIXME
Note
Do not set these states yourself, unless you know exactly what you are doing!
Priorities
The field tc_Node.ln_Pri of the struct Node embedded in the task structure (see exec/nodes.h and the .. FIXME:: section about exec lists ) specifies the priority of the task. Possible priorities reach from -128 to 127. The higher the priority the more processor time the task gets from the system. To set a task's priority use the function:
#include <proto/exec.h> BYTE SetTaskPri( struct Task *task, BYTE newpri );
The old priority is returned.
Stack
Every task has a stack. A stack is a piece of memory in which a tasks stores its temporary data. Compilers, for example, use the stack to store variables, you use in your programs. On many architectures, the stack is also used to supply library functions with parameters.
The size of the stack is limited. Therefore only a certain amount of data can be stored in the stack. The stack-size of a task is chosen by its caller and must be at least 4096 bytes. Tasks should generally not assume that their stack-size is bigger. So, if a task needs more stack, the stack can be exchanged by using the function:
#include <proto/exec.h> void StackSwap( struct StackSwapStruct *sss );
The only argument, sss, is a pointer to a struct StackSwapStruct as defined in exec/tasks.h.
struct StackSwapStack must contain a pointer to the beginning of the new stack (strk_Lower), to the end of the new stack (stk_Upper) and a new stack-pointer (stk_Pointer). This stack-pointer is normally set either to the same address as stk_Lower or to the same address as stk_Upper, depending on the kind of CPU used.
When calling StackSwap(), the StackSwapStruct structure supplied as sss will be filled with information about the current stack.
After finishing using the new stack, the old stack must be restored by calling StackSwap() a second time with the same StackSwapStruct.
Note
Normally, only compilers need this function. Handle it with great care as different architectures use the stack in different ways!
Processes
A process is an expanded task. Different from a task, it can use functions of dos.library, because a process structure contains some special fields, concerning files and directories. But of course, all functions that can be used on tasks can also be used on processes.
The Process Structure
A process is described by a struct Process as defined in dos/dosextens.h. The first field in struct Process is an embedded struct Task. The extra fields include information about the file-system, the console, the process is connected to, and miscellaneous other stuff.
Creating own Tasks and Processes
There are mainly two methods of creating tasks and processes: you can either call an external program (i.e. open an executable file and run the program contained in it) or you can execute a piece of code, already in memory.
Starting External Programs
External programs are always processes. FIXME
Expanded Error Diagnostics
Most functions of dos.library set the secondary error-code of the process structure on error. This way the caller can determine, why a certain system-call failed. Imagine, the function Open(), which opens a named file, fails. There can be multiple reasons for this: maybe the file named doesn't exist, maybe it is read protected. To find this out, you can query the secondary error-code set by the last function by using:
#include <proto/dos.h> LONG IoErr()
DOS-functions return one of the ERROR_ definitions from dos/dos.h. Applications can, of course, process these error-codes as well (which is useful in many cases), but often we just want to inform the user what went wrong. (Applications normally need not care if a file could not be opened because it did not exist or because it was read protected.) To output human-readable error messages, dos.library provides two functions:
#include <proto/dos.h> LONG Fault( LONG code, STRPTR header, STRPTR buffer, LONG length ); BOOL PrintFault( LONG code, STRPTR header );
While PrintFault() simply prints an error message to the standard output, Fault() fills a supplied buffer with the message. Both functions take a code argument. This is the code to be converted into a string. You can also supply a header string, which will prefix the error message. The header may be NULL, in which case nothing is prefixed.
Fault() also required a pointer to a buffer, which is to be filled with the converted string. The length of this buffer (in bytes) is to be passed in as the last argument. The total number of characters put into the buffer is returned. You are on the safe side, if your buffer has a size of 83 character plus the size of the header.
Examples for the use of these functions can be found in later chapters, especially in the chapter about .. FIXME:: Files and Directories.
Secondary error-codes from a program are handed back to the caller. If this is a shell, the secondary error-code will be put into the field cli_Result2 of the shell structure (struct CommandLineInterface as defined in dos/dosextens.h and .. FIXME:: discussed later.
You can also set the secondary error-code yourself. This way, you can either to pass it back to another function in your program or to your caller. To set the secondary error, use:
#include <proto/dos.h> LONG SetIoErr( LONG code );
code is the new secondary error-code and the old secondary error-code is returned.
Stream I/O
Open() | Open a file with the specified mode |
OpenFromLock() | Open a file from a lock |
Close() | Close a file |
FGetC() | Get a character from a buffered file |
UnGetC() | Push a character back into a read file handle |
FGets() | Read a line from a file |
FPutC() | Write a character to a file |
FPuts() | Write a string to a file |
FRead() | Read a number of blocks from a file |
FWrite() | Write a number of blocks to a file |
Flush() | Flush buffer |
PutStr() | Write string to standard output |
Read() | Read a couple of bytes from a file |
WaitForChar() | Waits for a character to arrive at a file handle |
Seek() | Change current read/write position in a file |
LockRecord() | Lock a portion of a file for exclusive access |
LockRecords() | Lock several records at the same time |
UnLockRecord() | Release a lock made with LockRecord() |
UnLockRecords() | Release array of LockRecords() record locks |
VFPrintf() | Write a formatted (RawDoFmt) string to a file |
VFWritef() | Write a formatted string to a file |
VPrintf() | Write (RawDoFmt) string to standard output |
SetVBuf() | Change file handle buffering modes / buffer size |
Write() | Write data to a file |
WriteChars() | Write data to the standard output |
SelectInput() | Change the standard input stream |
SelectOutput() | Change the standard output stream |
SelectError() | Change the error stream |
Input() | Return current input stream |
Output() | Return current output stream |
Error() | Return current error stream |
AddBuffers() | Add or remove cache memory from a file system |
ChangeMode() | Change the mode of a file handle or lock |
Pipe() | Create a pair of connected file handles |
Files/Directories
AssignAdd() | Add a directory to an assign |
AssignLate() | Create a late-binding (deferred) assign |
AssignLock() | Create an assign from a given name to a lock |
AssignPath() | Create a non-binding (path) assign |
RemAssignList() | Remove an entry from a multi-dir assign |
CreateDir() | Create a new directory |
CurrentDir() | Set a new directory as the current directory |
ParentDir() | Return a lock to the parent directory |
ParentOfFH() | Lock the directory a file is located in |
DeleteFile() | Delete a file or directory |
Rename() | Rename a file |
Relabel() | Change name of a volume |
SetVar() | Set a local or environmental variable |
FindVar() | Find a local variable |
GetVar() | Return the value of a local or global variable |
ScanVars() | Scan local/global variables according to flags |
DeleteVar() | Deletes a local or environmental variable |
MakeLink() | Create a hard- or soft link |
ReadLink() | Read the soft-link information |
SetFileSize() | Change the size of a file |
SetComment() | Set a file comment |
SetFileDate() | Change the date of a file |
SetProtection() | Set the protection bits of a file |
SetOwner() | Set the owner of a file |
AddPart() | Connects parts of a path |
FilePart() | Get a pointer to the last component of a path |
PathPart() | Give pointer to character after the last dir |
SplitName() | Split a path into pieces |
Format() | Format a device |
StartNotify() | Send a notification request to a file system |
EndNotify() | End a notification |
Examination
Lock() | Lock a file or directory |
DupLock() | Clone a lock on a file or directory |
NameFromLock() | Retrieve the full pathname from a lock |
ExAll() | Examine a directory |
ExAllEnd() | Stop an ExAll() operation |
ExNext() | Examine the next entry in a directory |
Examine() | Fill in FileInfoBlock structure of file/dir |
MatchEnd() | Free memory from MatchFirst()/MatchNext() |
MatchFirst() | Find first file/dir matching a given pattern |
MatchNext() | Find next file/dir matching a given pattern |
MatchPattern() | Check if a string matches a pattern |
MatchPatternNoCase() | Case insensitive variant of MatchPattern() |
ParsePattern() | Parse a pattern for use with MatchPattern() |
ParsePatternNoCase() | Case insensitive variant of ParsePattern() |
SameDevice() | Check if two locks are on the same device |
SameLock() | Compare two locks |
Info() | Get information about a volume in the system |
Packets
AbortPkt() | Abort an asynchronous packet |
DoPkt() | Send dospacket to file system / and wait for it |
ReplyPkt() | Reply packet |
SendPkt() | Send a packet to handler without waiting for it |
WaitPkt() | Wait for a packet to arrive |
DOS entries
AddDosEntry() | Add a given dos list entry to the dos list |
RemDosEntry() | Remove a given dos list entry from the dos list |
FreeDosEntry() | Free a dos list entry from MakeDosEntry() |
AllocDosObject() | Create a new dos object of a given type |
FreeDosObject() | Frees an object from AllocDosObject() |
AttemptLockDosList() | Try to get a lock on one of the dos lists |
FindDosEntry() | Look for next dos list entry with given name |
LockDosList() | Lock the specified Dos Lists for use |
UnLockDosList() | Free dos lists lock from LockDosList() |
MakeDosEntry() | Create an entry for the dos list |
NextDosEntry() | Look for next dos list entry with given name |
IsFileSystem() | Check if a device is a file system |
IsInteractive() | Query a file system for interactiveness |
Inhibit() | Stop a file system from being used |
Error
ErrorReport() | Display Requester for an error |
Fault() | Get error message string for an error code |
PrintFault() | Print error message to console |
IoErr() | Get the dos error code for the current process |
SetIoErr() | Set dos error code for the current process |
Arguments
ReadArgs() | Parse command line arguments |
ReadItem() | Read an item from a given character source |
FindArg() | Search for keyword in the template |
FreeArgs() | Free arguments structure from ReadArgs() |
GetArgStr() | Return pointer to argument string of process |
SetArgStr() | Set the arguments of the current process |
Process
CreateNewProc() | Create a new process |
CreateProc() | Create a new process (in an old way) |
AddSegment() | Add a segment to the resident list |
NewLoadSeg() | Do LoadSeg() and take additional action |
LoadSeg() | Load an executable file into memory |
UnLoadSeg() | Free a segment list allocated with LoadSeg() |
InternalLoadSeg() | Low-level load from fh |
InternalUnLoadSeg() | Unload a seglist from InternalLoadSeg() |
FindSegment() | Find a resident segment |
RemSegment() | Remove a segment from the system list |
DeviceProc() | Return a handle to a devices process |
CheckSignal() | Check current task for signals |
SetProgramName() | Set the name of the current program |
GetProgramName() | Get the name of the current program |
SetCurrentDirName() | Set name of current directory in CLI structure |
GetCurrentDirName() | Get name of current directory in CLI structure |
GetProgramDir() | Get the lock for PROGDIR: |
SetProgramDir() | Set the home directory for a program (PROGDIR:) |
RunCommand() | Execute a loaded command synchronously |
SystemTagList() | Execute a command via a shell |
Execute() | Execute a CLI command |
GetDeviceProc() | Find the file system for a path |
FreeDeviceProc() | Clean up after calls to GetDeviceProc() |
GetConsoleTask() | Get "task" belonging to the process' console |
SetConsoleTask() | Set the console handler for the current process |
SetFileSysTask() | Set current file system handler for a process |
GetFileSysTask() | Get the file system handler for a process |
MaxCli() | Return the highest CLI number currently in use |
Cli() | Return current process' CLI structure pointer |
CliInitNewcli() | Set up process as shell using a start-up packet |
CliInitRun() | Set up a process to be a shell |
FindCliProc() | Find a CLI process by its task number |
SetPrompt() | Set the prompt for the current CLI |
GetPrompt() | Get the current prompt |
SetMode() | Set current mode of a console device (RAW/CON) |
Miscellaneous
Delay() | Wait for at least the time specified as time-out |
CompareDates() | Compare two dates |
DateStamp() | Get the current date |
DateToStr() | Convert a DateTime struct into strings |
StrToDate() | Convert a string into a date |
StrToLong() | Convert a string into a long |