[comp.sys.amiga] How do you send a DosPacket to a handler directly?

gregg@cbnewsc.att.com (gregg.g.wonderly) (11/08/90)

Let's try this again, surely someone out there has experience with this
sort of thing!

I am trying to put together some code that will send ACTION_READ
packets to a handler after opening a file with Open().  I need to
double buffer file reads with other I/O using separate tasks.

Basically I need to do three things at once.  One is read a file.  Two
is send the segments of the file to another task to process and the
third is the main routine which needs to be able to tell the other
tasks to stop.  Does anybody have some pointers on why the code below
doesn't work?

Background...

The assignment of packet->dp_Arg1 = handle->fh_Args came from looking
at the MSH handler.  I do not know what is really required here.  If I
put something like handle, or BTOC(handle) in packet->dp_Arg1 it
GURUs.  With the handle->fh_Args value, the PutMsg() succeeds, but
there is no response via Wait().  I do not have the AmigaDos manual
which supposedly documents this sort of thing (does it?).  The Autodocs
and RKM do not contain any real DOS.LIBRARY information.  I am at a
loss as to exactly what is required.  The headers (dosextens.h) give
hints, but obviously I am missing something.

Thanks for any information you can provide.

------------------------------- Test Program -------------------------------
#include <stdio.h>
#include <exec/types.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>

typedef struct FileHandle HANDLE;
typedef struct DosPacket PACKET;

#define BTOC(x) (void *)((long)(x) << 2)
#define CTOB(x) (void *)((long)(x) >> 2)

main( argc, argv )
    int argc;
    char **argv;
{
    long n, fh;
    int sig;
    HANDLE *handle;
    PACKET *packet;
    struct MsgPort *msgpt;
    struct Message *msg, *tmsg;
    char buf[1024];

    if( (fh = Open( argv[1], MODE_OLDFILE )) == NULL )
    {
        fprintf( stderr, "Can not open %s\n", argv[1]);
        exit( 1 );
    }

    /* Read something and write it out. */

    n = Read( fh, buf, 1024 );
    Write( Output(), buf, n );

    /* Get real pointer to DosFileHandle */

    handle = BTOC(fh);

    /* Get the msgport to send to. */

    msgpt = (struct MsgPort *) handle->fh_Type;

    /* Allocate a dos packet. */

    if(( packet = (PACKET *)AllocMem( sizeof( PACKET ),
                                        MEMF_PUBLIC | MEMF_CLEAR ) ) == NULL )
    {
        fprintf( stderr, "alloc failed\n");
        Close( fh );
        exit( 1 );
    }

    /* Put together the packet. */

    packet->dp_Action = ACTION_READ;

    /* Is this what is really required? */

    packet->dp_Arg1   = (LONG) handle->fh_Args;
    packet->dp_Arg2   = (LONG) buf;
    packet->dp_Arg3   = (LONG) sizeof(buf);

    /* Get a port */

    if( (packet->dp_Port = (struct MsgPort *) CreatePort( 0L, 0 )) == NULL)
    {
        fprintf( stderr, "can get port\n");
        Close( fh );
        FreeMem( packet, sizeof( PACKET ) );
        exit( 1 );
    }

    /* Allocate a message to send. */

    if ((packet->dp_Link = (struct Message *)
        AllocMem( sizeof( struct Message ),
                                        MEMF_PUBLIC | MEMF_CLEAR ) ) == NULL )
    {
         fprintf( stderr, "alloc failed\n");
        Close( fh );
        FreeMem( packet, sizeof( PACKET ) );
        exit( 1 );
    }

    /* Fill in the message */

    tmsg = packet->dp_Link;
    tmsg->mn_Node.ln_Name = (char *) packet;  /* MSH looks here */
    tmsg->mn_Node.ln_Succ = NULL;
    tmsg->mn_Node.ln_Pred = NULL;
    tmsg->mn_ReplyPort    = packet->dp_Port;  /* Required? */
    tmsg->mn_Length       = sizeof( *packet ); /* Correct Length? */

    /* Send the message */

    if( (long)msgpt < 0)
        PutMsg( -(long)msgpt, tmsg );
    else
        PutMsg( msgpt, tmsg );

    /* Wait for the return */

    sig = Wait( (1 << packet->dp_Port->mp_SigBit) | SIGBREAKF_CTRL_C );

    if( sig & (1<<packet->dp_Port->mp_SigBit) )
    {
        msg = (struct Message *)GetMsg( packet->dp_Port );
        printf( "%d bytes read\n", packet->dp_Res1 );
        Write( Output(), buf, packet->dp_Res1 );
    }
    else
    {
        printf( "\n***BREAK***\n");
    }

    /* Clean up */

    DeletePort( packet->dp_Port );
    FreeMem( tmsg, sizeof( struct Message ) );
    FreeMem( packet, sizeof( PACKET ) );

    Close( fh );
    exit(0);
}
-- 
-----
gregg.g.wonderly@att.com   (AT&T bell laboratories)
-- 
-----
gregg.g.wonderly@att.com   (AT&T bell laboratories)