DOS Objects Lifecycle¶
Several AmigaDOS objects have hidden elements beyond what the public struct declaration shows. sizeof() therefore does not describe the real allocation size, and a hand-rolled AllocMem() can leave the object in a state that the rest of dos.library rejects or crashes on. For these objects, dos.library provides a constructor–destructor pair:
APTR AllocDosObject(ULONG type, struct TagItem *tags); /* V36 */
APTR AllocDosObjectTagList(ULONG type, struct TagItem *tags);
APTR AllocDosObjectTags(ULONG type, ULONG tag1, ...);
void FreeDosObject(ULONG type, APTR ptr); /* V36 */
All three constructors share one entry point. AllocDosObjectTags() accepts a variadic tag list terminated by TAG_DONE.
Object types¶
Defined in dos/dos.h. The list changes over releases — the table below is V36+.
| Type | Object | Hidden elements? | Notes |
|---|---|---|---|
DOS_FILEHANDLE 2.0+ |
struct FileHandle |
Yes | Never hand-allocate. The tag ADO_FH_Mode is accepted but currently unused. |
DOS_EXALLCONTROL 2.0+ |
struct ExAllControl |
Yes | Must be allocated with AllocDosObject(). |
DOS_FIB 2.0+ |
struct FileInfoBlock |
No | Long-word alignment required; use D_S() on the stack. |
DOS_STDPKT 2.0+ |
struct StandardPacket |
No, but a layout quirk | Returned pointer is to the inner DosPacket, not the StandardPacket. |
DOS_CLI 2.0+ |
struct CommandLineInterface |
Yes (V47+) | Manual construction no longer works as of V47; the Shell needs the private elements. |
DOS_RDARGS 2.0+ |
struct RDArgs |
No | Use this for custom ReadArgs() flows over alternative inputs. |
DOS_FILEHANDLE¶
Used for Open()-style file handles. ADO_FH_Mode (from dos/dostags.h) takes one of the values from MODE_OLDFILE / MODE_NEWFILE / MODE_READWRITE. The autodoc implies it controls handle initialization, but the current implementation ignores it; do not rely on a particular mode after AllocDosObject().
DOS_STDPKT¶
Aggregates an exec Message and a DosPacket with the linkage fields (sp_Msg.mn_Node, sp_Pkt.dp_Link, sp_Pkt.dp_Port) pre-wired. AllocDosObject(DOS_STDPKT, NULL) returns the address of the inner DosPacket (&sp_Pkt), not the outer StandardPacket. Pass that pointer to SendPkt() and to FreeDosObject().
If you construct the structure yourself, ensure the DosPacket is longword-aligned and link mn_Node of the message and dp_Link of the packet to each other.
DOS_CLI¶
Constructed with optional tag list:
| Tag | Effect |
|---|---|
ADO_PromptLen 2.0+ |
Size in bytes of cli_Prompt |
ADO_CommNameLen 2.0+ |
Size in bytes of cli_CommandName |
ADO_CommFileLen 2.0+ |
Size in bytes of cli_CommandFile |
ADO_DirLen 2.0+ |
Size in bytes of cli_SetName |
None of these tags are useful in practice — the V47 Shell uses hard-coded limits rather than the field sizes. Allocate with TAG_DONE for normal use.
V47+: do not construct
struct CLImanually. It contains private elements that the Shell relies on; missing them yields a degraded shell. Always go throughAllocDosObject().
FreeDosObject — releasing an object¶
void FreeDosObject(ULONG type, APTR ptr);
Destroys the object and releases its resources. Pass ptr = NULL to perform a no-op (handy for cleanup paths). The type argument must match what was passed to AllocDosObject().
For DOS_STDPKT, ptr is the address of the inner DosPacket, not the outer StandardPacket.
FreeDosObject() does not touch IoErr().
Memory leak in old releases¶
FreeDosObject(DOS_CLI, …) on AmigaDOS V37 and earlier did not free all buffers associated with the CLI structure. The leak was fixed in V39. If you must support pre-V39, free cli_Prompt, cli_CommandName, cli_CommandFile, and cli_SetName manually before calling FreeDosObject().
Worked example¶
#include <dos/dos.h>
#include <dos/dostags.h>
struct ExAllControl *MakeExAllControl(void)
{
return (struct ExAllControl *)AllocDosObject(DOS_EXALLCONTROL, NULL);
}
void DisposeExAllControl(struct ExAllControl *eac)
{
FreeDosObject(DOS_EXALLCONTROL, eac);
}
/* Sending a packet to a handler using AllocDosObject. */
struct MsgPort *port; /* target handler port */
struct DosPacket *pkt;
pkt = (struct DosPacket *)AllocDosObject(DOS_STDPKT, NULL);
if (pkt) {
pkt->dp_Type = ACTION_CURRENT_VOLUME;
pkt->dp_Arg1 = 0;
SendPkt(pkt, port);
WaitPkt(); /* or WaitPort(port) then GetMsg() */
/* ...use dp_Res1/dp_Res2... */
FreeDosObject(DOS_STDPKT, pkt);
}
See Also¶
- dos.library Reference
- DOS Packets
- DOS Packet Reference
- DOS Error Reporting
- BPTR, BSTR, and BCPL Legacy
Sources: Thomas Richter, "ROM Kernel Reference Manual: AmigaDOS" (First Edition, 2024), Chapter 16.1 — Object Constructors and Destructors.
Raw: raw/rkm/rkm-dos-book.md
Updated: 2026-10-02