[comp.sys.amiga.tech] Question RE sending DosPackets to handlers directly

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

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
these reads with other I/O.  Does anybody have some pointers?  Below is
the test program that I have been using.  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 CTOB(handle) in there it GURUs.  With this value in there
The PutMsg() succeeds, but there is no response via Wait().  I do not have
the AmigaDos tech manual, and the autodocs and ROMKERNEL of course do not
contain any real DOS.LIBRARY information, so I am at a loss as to exactly
what is required.  The headers and such give hints, but evidently there is
some information missing.

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)