DOS

# Files and directories

## Open a file

```
BPTR filehandle = Open(CONST\_STRPTR filename, ULONG mode);

```

Where mode is one of the following:

 MODE\_NEWFILE
 MODE\_READWRITE

```
BPTR fh = Open("RAM:test", MODE\_READWRITE);

```

## Close a file

```
Close(BPTR filehandle);

```

## Seek

 OFFSET\_CURRENT
 OFFSET\_END

```
LONG old\_position = Seek(BPTR filehandle, LONG position, ULONG seekmode);
QUAD old\_position = Seek64(BPTR filehandle, QUAD position, ULONG seekmode);

```

## Writing and reading

There are two sets of functions to read and write files: unbuffered and buffered. Buffered I/O is efficient for small reads and writes.

Unbuffered read/write:

```
ULONG bytes\_read = Read(BPTR filehandle, APTR buffer, ULONG bufferlength);
ULONG bytes\_written = Write(BPTR filehandle, CONST\_APTR buffer, ULONG bufferlength);

```

Buffered read/write:

```
ULONG blocks\_read = FRead(BPTR filehandle, APTR buffer, ULONG blocklength, ULONG numblocks);
ULONG blocks\_written = FWrite(BPTR filehandle, CONST\_APTR buffer, ULONG blocklength, ULONG numblocks);

```

You must use FFlush() when switching from buffered I/O to unbuffered or vice versa:

```
FFlush(BPTR filehandle);

```

## Example

```
#include <string.h>

#include <proto/dos.h>

int main()
{
 BPTR fh = Open("RAM:test", MODE\_READWRITE);

 if (fh)
 {
 TEXT buf[200];
 stccpy(buf, "This is a test.\n", sizeof(buf));

 Write(fh, buf, strlen(buf));
 Seek(fh, 0, OFFSET\_BEGINNING);
 Read(fh, buf, sizeof(buf));

 Close(fh);
 }

 return 0;
}

```

# Scanning directories

 ED\_TYPE
 ED\_SIZE
 ED\_PROTECTION
 ED\_DATE
 ED\_COMMENT
 ED\_OWNER
 ED\_SIZE64

```
#include <dos/dosextens.h>
#include <dos/exall.h>
#include <proto/dos.h>

#define EXALL\_BUFSIZE 8192

int main()
{
 int retval = RETURN\_FAIL;
 struct ExAllData \*buffer = AllocMem(EXALL\_BUFSIZE, MEMF\_ANY);

 if (buffer)
 {
 BPTR lock = Lock("SYS:", ACCESS\_READ);

 if (lock)
 {
 struct ExAllControl \*eac = AllocDosObject(DOS\_EXALLCONTROL, NULL);

 if (eac)
 {
 ULONG type = ED\_SIZE64;
 BOOL keep\_scanning;

 eac->eac\_LastKey = 0;

 do
 {
 keep\_scanning = ExAll(lock, buffer, EXALL\_BUFSIZE, type, eac);

 if (!keep\_scanning)
 {
 LONG err = IoErr();

 switch (err)
 {
 case ERROR\_NO\_MORE\_ENTRIES:
 break;

 case ERROR\_BAD\_NUMBER:
 if (type == ED\_SIZE64)
 {
 type = ED\_OWNER;
 keep\_scanning = TRUE;
 break;
 }
 /\* fall through \*/
 default:
 PrintFault(err, "Directory scanning failed:\n");
 break;
 }
 else
 {
 struct ExAllData \*ead = buffer;

 if (eac->eac\_Entries == 0)
 continue;

 do
 {
 Printf("%s\n", ead->ed\_Name);
 ead = ead->ed\_Next;
 }
 while (ead);
 }
 }
 }
 while();

 ExAllEnd(lock, buffer, EXALL\_BUFSIZE, type, eac);
 FreeDosObject(DOS\_EXALLCONTROL, eac);
 }

 UnLock(lock);
 }
 }

 return retval;
}

```

# Notifications

With StartNotify() and EndNotify() you can start and stop getting notifications when files have changed. You can ask dos.library to notify you with a signal or a message. Please note that not all file systems support notifications.

```
#include <exec/execbase.h>
#include <proto/exec.h>
#include <proto/dos.h>

int main()
{
 struct NotifyRequest req;
 struct MsgPort \*port;

 memset(&req, 0, sizeof(req));
 port = CreateMsgPort();

 if (port)
 {
 req.nr\_Name = "S:User-Startup";
 req.nr\_Flags = NRF\_SEND\_MESSAGE | NRF\_WAIT\_REPLY;
 req.nr\_stuff.nr\_Signal.nr\_Port = port;

 if (StartNotify(&req))
 {
 ULONG notifymask = 1 << port->mp\_SigBit;

 while (TRUE)
 {
 ULONG sigs = Wait(notifymask | SIGBREAKF\_CTRL\_C);

 if (sigs & SIGBREAKF\_CTRL\_C)
 break;

 if (sigs & notifymask)
 {
 struct NotifyMessage \*msg = GetMsg(port);

 if (msg)
 {
 PutStr("File changed!");
 ReplyMsg(msg);
 }
 }
 }

 EndNotify(&req);
 }

 DeleteMsgPort(port);
 }

 return 0;
}

```