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_Error defaults to NULL (not Open("NIL:",...)) and NP_CloseError to 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).

See Also


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-08-08