It is not as diffiult as it seems. Here is an exmaple which copies a file with asynchronous I/O:
#include <proto/exec.h>
#include <proto/dos.h>
struct MsgPort *StartRead (BPTR file,APTR buffer,LONG size,struct MsgPort *port)
{
struct FileHandle *fh = BADDR(file);
struct DosPacket *packet;
if (fh && fh->fh_Type)
{
if (packet = AllocDosObject (DOS_STDPKT,TAG_END))
{
packet->dp_Port = port;
packet->dp_Type = ACTION_READ;
packet->dp_Arg1 = fh->fh_Arg1;
packet->dp_Arg2 = (LONG)buffer;
packet->dp_Arg3 = (LONG)size;
PutMsg (fh->fh_Type,packet->dp_Link);
return (port);
}
}
return (NULL);
}
struct MsgPort *StartWrite (BPTR file,APTR buffer,LONG size,struct MsgPort *port)
{
struct FileHandle *fh = BADDR(file);
struct DosPacket *packet;
if (fh && fh->fh_Type)
{
if (packet = AllocDosObject (DOS_STDPKT,TAG_END))
{
packet->dp_Port = port;
packet->dp_Type = ACTION_WRITE;
packet->dp_Arg1 = fh->fh_Arg1;
packet->dp_Arg2 = (LONG)buffer;
packet->dp_Arg3 = (LONG)size;
PutMsg (fh->fh_Type,packet->dp_Link);
return (port);
}
}
return (NULL);
}
LONG WaitDosIO (struct MsgPort *port)
{
struct Message *msg;
struct DosPacket *packet;
long rc;
WaitPort (port);
msg = GetMsg (port);
packet = (struct DosPacket *) msg->mn_Node.ln_Name;
rc = packet->dp_Res1;
FreeDosObject (DOS_STDPKT,packet);
return (rc);
}
#define BUFFSIZE 1024
int main (void)
{
struct RDArgs *rdargs;
struct {
char *in_file;
char *out_file;
} args;
BPTR in_file;
BPTR out_file;
struct MsgPort *in_port;
struct MsgPort *out_port;
UBYTE buffer1[BUFFSIZE];
UBYTE buffer2[BUFFSIZE];
UBYTE *buffer;
long bytes_read;
if (rdargs = ReadArgs ("INFILE/A,OUTFILE/A",(APTR)&args,NULL))
{
if (in_port = CreateMsgPort())
{
if (out_port = CreateMsgPort())
{
if (in_file = Open (args.in_file,MODE_OLDFILE))
{
if (out_file = Open (args.out_file,MODE_NEWFILE))
{
buffer = buffer1;
bytes_read = Read (in_file,buffer,BUFFSIZE);
while (bytes_read > 0)
{
StartWrite (out_file,buffer,bytes_read,out_port);
buffer = (buffer == buffer1 ? buffer2 : buffer1);
StartRead (in_file,buffer,BUFFSIZE,in_port);
WaitDosIO (out_port);
bytes_read = WaitDosIO (in_port);
}
Close (out_file);
}
else
PrintFault (IoErr(),args.out_file);
Close (in_file);
}
else
PrintFault (IoErr(),args.in_file);
DeleteMsgPort (out_port);
}
DeleteMsgPort (in_port);
}
FreeArgs (rdargs);
}
else
PrintFault (IoErr(),NULL);
return (0);
}
You can use the functions StartRead, StartWrite and WaitDosIO in you program.
Please note that between StartRead and WaitDosIO and between StartWrite and WaitDosIO you must not use the file handle in any other function and you must not use the MsgPort for any other purpose than to Wait() for I/O completion.
If you use Wait() to wait for I/O completion you still have to call WaitDosIO in order to clean up and to receive the result. This works similar to exec.library's SendIO and WaitIO. However, there is no AbortIO for DOS packets.
Bye,
Thomas