dos.library Reference¶
dos.library is the AmigaDOS layer — file I/O, directory operations, process creation, environment variables, pattern matching, and command-line parsing. It sits above exec.library and provides the "DOS" experience. Unlike exec, dos functions operate on BPTRs (BCPL pointers, opaque file/directory handles), not standard C FILE * or file descriptors.
BPTR — not a normal pointer¶
BPTR is a BCPL-era indirect pointer. Never dereference a BPTR directly — it does not point where you think it does. Pass it only to dos.library functions (Read(), Write(), Seek(), Close(), etc.). Convert to a regular pointer with BADDR() if absolutely necessary (rare).
BPTR fh = Open("SYS:Prefs/Env-archive/SYS/font.prefs", MODE_OLDFILE);
if (!fh) { /* handle error — always check */ }
File open modes¶
| Constant | Meaning |
|---|---|
MODE_OLDFILE |
Open existing file for reading |
MODE_NEWFILE |
Create new file (or truncate existing) for writing |
MODE_READWRITE |
Open existing for read+write (file must exist) |
Open() returns 0 on failure; call IoErr() for the error code. Always check.
File I/O¶
LONG Read(BPTR file, APTR buffer, LONG length);
LONG Write(BPTR file, APTR buffer, LONG length);
LONG Seek(BPTR file, LONG position, LONG mode); /* OFFSET_BEGINNING/CURRENT/END */
void Close(BPTR file);
Read/Write return the actual byte count (or -1 on error). Seek returns the old file position (-1 on error). All dos I/O goes through the filesystem handler process — it is inherently message-based and can be asynchronous.
Locks and directory scanning¶
BPTR Lock(STRPTR name, LONG accessMode); /* SHARED_LOCK or EXCLUSIVE_LOCK */
void UnLock(BPTR lock);
Two ways to scan directories:
Examine/ExNext (classic, per-entry)¶
struct FileInfoBlock fib;
Examine(lock, &fib); /* fill fib with first entry */
while (ExNext(lock, &fib)) {
/* fib.fib_FileName, fib.fib_Size, fib.fib_DirEntryType, etc. */
if (fib.fib_DirEntryType > 0) { /* it's a directory */ }
}
Gotcha: Examine() returns info for the lock itself (not its contents). ExNext() iterates the contents. You must call Examine once before the ExNext loop. The FileInfoBlock must be longword-aligned and cannot be shared across tasks.
ExAll (V36+, bulk read)¶
struct ExAllControl *eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
eac->eac_LastKey = 0;
ExAll(lock, buffer, bufsize, ED_FULL, eac);
/* process entries in buffer, check eac->eac_Entries */
FreeDosObject(DOS_EXALLCONTROL, eac);
More efficient; returns multiple entries per call. Use ExAllEnd() to signal you're done early (V39+).
Pattern matching¶
LONG ParsePattern(STRPTR pattern, STRPTR parsed, LONG parsedLen);
LONG MatchPattern(STRPTR parsed, STRPTR str);
Two-step: parse the wildcard pattern once, then match multiple strings. ParsePattern returns 1 if the pattern contains wildcards, 0 if it's a literal. Supports #? (any chars), % (single char), [abc] (char set), [~abc] (negated set), | (OR).
There are also case-insensitive variants: ParsePatternNoCase, MatchPatternNoCase.
ReadArgs — command-line parsing¶
struct RDArgs *ReadArgs(STRPTR template, LONG *results, struct RDArgs *rdargs);
void FreeArgs(struct RDArgs *rdargs);
Template syntax (this is the standard Amiga CLI argument parser):
| Flag | Meaning |
|---|---|
/A |
Required argument |
/K |
Must use keyword (not positional) |
/N |
Numeric (stored as LONG *) |
/S |
Switch (boolean) |
/F |
Rest of command line (string) |
/M |
Multiple values (array of strings) |
/T |
Text (rest of line after keyword) |
Example: "FILE/A,PORT/K/N,QUIET/S" — FILE is required, PORT is optional numeric keyword, QUIET is a switch.
Always FreeArgs() when done.
Environment variables¶
LONG GetVar(STRPTR name, STRPTR buffer, LONG bufferlen, LONG flags);
LONG SetVar(STRPTR name, STRPTR buffer, LONG stringlen, LONG flags);
LONG DeleteVar(STRPTR name, ULONG flags, ...);
Flags: GVF_GLOBAL_ONLY (look in ENVARC: / ENV:), GVF_LOCAL_ONLY (process-local). Variables can also be accessed via FindVar() for direct pointer access.
DOS Packets¶
Filesystem handlers (L: handlers) communicate with DOS via packets (struct DosPacket). Application code rarely sends packets directly — use DoPkt()/SendPkt() only for custom handler communication. See DOS Packets for V39 additions.
Process creation¶
BPTR CreateProc(STRPTR name, LONG pri, BPTR segList, LONG stackSize);
struct Process *CreateNewProc(struct TagItem *tags); /* V36+ */
LONG RunCommand(BPTR segList, LONG stack, STRPTR cmd, LONG cmdlen);
CreateNewProc (V36+) is the preferred API — it takes tags for full control (stack size, current directory, input/output handles, etc.). CreateProc is the older, limited interface.
Status: Outdated (V47, AmigaOS 3.2) —
NP_Error/NP_CloseError. V40 "claimed to support" these tags "but in fact did not." OS 3.2 finally implements them. For V40 compatibility the defaults changed:NP_Errordefaults to NULL (notOpen("NIL:",...)) andNP_CloseErrorto FALSE (not TRUE). See AmigaOS 3.2 — What Changed for Developers.
Error handling¶
LONG IoErr(void);
void SetIoErr(LONG code);
LONG Fault(LONG code, STRPTR header, STRPTR buffer, LONG len);
LONG PrintFault(LONG code, STRPTR header);
IoErr() returns the error code from the most recent DOS call. Fault()/PrintFault() convert an error code to a human-readable string. Common codes: ERROR_OBJECT_NOT_FOUND (205), ERROR_OBJECT_EXISTS (203), ERROR_DISK_FULL (28), ERROR_WRITE_PROTECTED (29), ERROR_OBJECT_IN_USE (202).
Full coverage of error reporting (requesters, error streams, fault handling) in DOS Error Reporting. Object lifecycle for DOS_FILEHANDLE, DOS_FIB, DOS_EXALLCONTROL, DOS_STDPKT, DOS_CLI, DOS_RDARGS in DOS Objects Lifecycle.
Record locking¶
BOOL LockRecord(BPTR fh, ULONG offset, ULONG length, ULONG mode, ULONG timeout); /* V36 */
BOOL UnLockRecord(BPTR fh, ULONG offset, ULONG length); /* V36 */
struct RecordLock {
BPTR rec_FH;
ULONG rec_Offset;
ULONG rec_Length;
ULONG rec_Mode;
};
BOOL LockRecords(struct RecordLock *array, ULONG timeout);
BOOL UnLockRecords(struct RecordLock *array);
Locks a contiguous region [offset, offset+length) of an open file. Modes are REC_EXCLUSIVE / REC_EXCLUSIVE_IMMED / REC_SHARED / REC_SHARED_IMMED (in dos/record.h). Shared locks overlap freely; exclusive locks conflict with everything. LockRecords() is sequential, not atomic — lock records in a consistent order across your program. See DOS Record Locking.
Interactive files and handler detection¶
BOOL IsInteractive(BPTR file); /* classic */
BOOL IsFileSystem(STRPTR path); /* V36 */
BOOL WaitForChar(BPTR file, LONG timeout_us); /* V36 */
BOOL SetMode(BPTR fh, LONG mode); /* V36 */
IsInteractive() distinguishes file-system files from handler files. IsFileSystem() tells you whether a path resolves to a file system (side effect: it may load and start the handler). WaitForChar() polls for input availability with microsecond resolution; it operates at the handler level only and ignores bytes already buffered in the filehandle. SetMode() switches the CON-Handler between cooked, raw, and (V47) medium line modes. See Interactive Files and Handler Detection.
String streams¶
A BPTR filehandle can be backed by a memory buffer instead of a file by pointing fh_Buf, fh_Pos, fh_End at the buffer. The NIL: handler is the standard starting point; the buffer must be longword-aligned (use AllocVec()). See DOS String Streams.
Assigns¶
BOOL AssignLock(STRPTR name, BPTR lock); /* V36 — regular, multi */
BOOL AssignPath(STRPTR name, STRPTR path); /* V36 — non-binding */
BOOL AssignLate(STRPTR name, STRPTR path); /* V36 — late binding */
BOOL AssignAdd(STRPTR name, BPTR lock); /* V36 — append to multi */
BOOL RemAssignList(STRPTR name, BPTR lock); /* V36 — remove from multi */
AssignLock() creates a regular assign (or cancels with lock == ZERO); repeated AssignAdd() promotes it to a multi-assign. AssignPath() and AssignLate() are non-binding and late-binding alternatives. All suffer a known race condition with locks that have been handed out via GetDeviceProc(). Assign names are limited to 30 characters (legacy BCPL limit). See AmigaDOS Assigns.
Device list access¶
struct DosList *LockDosList(ULONG flags); /* V36 — blocking */
struct DosList *AttemptLockDosList(ULONG flags); /* V36 — non-blocking */
void UnLockDosList(ULONG flags);
struct DosList *NextDosEntry(struct DosList *, ULONG flags);
struct DosList *FindDosEntry(struct DosList *, STRPTR name, ULONG flags);
struct DevProc *GetDeviceProc(STRPTR name, struct DevProc *prev); /* V36 */
void FreeDeviceProc(struct DevProc *);
struct MsgPort *DeviceProc(STRPTR); /* legacy, prefer GetDeviceProc */
struct MsgPort *GetConsoleTask(void); /* V36 */
struct MsgPort *GetFileSysTask(void); /* V36 */
struct DosList *MakeDosEntry(STRPTR name, LONG type); /* V36 */
void FreeDosEntry(struct DosList *);
LONG AddDosEntry(struct DosList *); /* V36 — locks list itself */
BOOL RemDosEntry(struct DosList *); /* V36 — caller holds lock */
GetDeviceProc() returns the next handler candidate for a path — iterate with the previous return value, then FreeDeviceProc(). Hands out dvp_Lock owned by dos.library; DupLock() before using it with Examine()/ExAll(). Side effect: it can load and start the handler. Handlers/filesystems must use AttemptLockDosList() to avoid deadlocking with dos.library itself. See The AmigaDOS Device List.
Notification requests¶
BOOL StartNotify(struct NotifyRequest *nr); /* V36 */
void EndNotify(struct NotifyRequest *nr); /* V36 */
Watch a file or directory for changes. Allocate the NotifyRequest with MEMF_CLEAR (some fields require zero-init), populate nr_Name, nr_Flags (NRF_SEND_MESSAGE xor NRF_SEND_SIGNAL, optional NRF_WAIT_REPLY, NRF_NOTIFY_INITIAL), and either nr_Port or nr_Task + nr_SignalNum. The filesystem sends a NotifyMessage (or sets a signal) on changes. See AmigaDOS Notification Requests.
Library internals¶
dos.library's base (DosLibrary) holds pointers to the RootNode, the legacy BCPL Global Vector, and cached utility.library / intuition.library. The RootNode keeps the current time, the boot filesystem port, the resident shell segment, the CLI table, and a RNF_WILDSTAR flag. DosInfo (reached via rn_Info) holds the head of the device list and the resident-segments list. None of these should be read or written from application code — use the accessor functions (FindCliProc, FindSegment, LockDosList, DateStamp, Fault). See AmigaDOS Library Internals.
See Also¶
- BPTR, BSTR, and BCPL Legacy
- DOS Packets
- DOS Packet Reference
- AmigaDOS Date and Time
- AmigaDOS Hunk Binary Format
- The AmigaDOS Shell
- AmigaDOS Error Codes
- AmigaDOS Filesystem On-Disk Structures
- AmigaDOS Notification Requests
- AmigaDOS Assigns
- The AmigaDOS Device List
- DOS Record Locking
- Interactive Files and Handler Detection
- DOS String Streams
- DOS Objects Lifecycle
- DOS Error Reporting
- AmigaDOS Library Internals
- exec.library Reference
- AmigaOS Version History
- AmigaOS 3.2 — What Changed for Developers
Sources: Commodore-Amiga / ESCOM AG, dos.library Autodoc (1985-1996); Hyperion Entertainment, NDK 3.2 dos RelNotes (2016-2021); Thomas Richter, "ROM Kernel Reference Manual: AmigaDOS" (2024); Ralph Babel, "The Amiga Guru Book" (1993).
Raw: raw/dos/dos-library.md; raw/architecture/os-3.2-release-notes.md; raw/rkm/rkm-dos-book.md; raw/rkm/guru-book.md
Updated: 2026-10-02