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).

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


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