🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #6894

Re: How do you send a DosPacket to a handler directly?

#6894
From: Doug Walker
Date: Tue, 20 Nov 1990 18:57
176 lines
6008 bytes
In article <1990Nov7.185224.4215@cbnewsc.att.com> gregg@cbnewsc.att.com (gregg.g.wonderly) writes:
>Let's try this again, surely someone out there has experience with this
>sort of thing!

Yes, but most of us don't care to admit it :-)

>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

This is correct.  If you look at the AmigaDOS packet-level documentation,
or the article John Toebes and I wrote for Amiga Transactor a couple of
years ago on filesystems, you will see that the FileHandle structure
field Arg1 is what's supposed to be passed for reads and so on.

>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().  

It works for me!  What you have should work just find.  Actually, 
using a WaitPort() on your reply port would work just as well.

You do have one problem, however - DOS packet messages are not like
other exec messages - DOS feels free to mess around with the linkage
fields in the structure.  You are setting dp_Port to your allocated
replyport;  instead of this, you need to allocate a local variable
of type struct MsgPort * to keep your reply port in and set dp_Port
from that.  Once the message is sent off to DOS, DOS will change
the value in that field.

Change your program as follows:

>#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, *replyport;;
>    struct Message *msg, *tmsg;
>    char buf[1024];
>
...

>    /* Get a port */
>
>    if( (replyport = 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 */
     WaitPort(replyport);
>    msg = (struct Message *)GetMsg( packet->dp_Port );
>    printf( "%d bytes read\n", packet->dp_Res1 );
>    Write( Output(), buf, packet->dp_Res1 );
>
>    /* Clean up */
>
>    DeletePort( replyport);
>    FreeMem( tmsg, sizeof( struct Message ) );
>    FreeMem( packet, sizeof( PACKET ) );
>
>    Close( fh );
>    exit(0);
>}

For your edification, here's a routine that will send a DOS packet
anywhere you want:

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <proto/exec.h>
#include <proto/dos.h>


LONG sendpkt(pid,action,args,nargs,res)
struct MsgPort *pid;  /* process indentifier ... (handlers message port ) */
LONG action,	      /* packet type ... (what you want handler to do )   */
     args[],	      /* a pointer to a argument list		*/
     nargs,	      /* number of arguments in list		*/
     res[];	      /* pointer to 2 longs for result, or NULL */
   {
   struct MsgPort	 *replyport;
   struct StandardPacket *packet;

   LONG  count, lres, *pargs;

   replyport = (struct MsgPort *) CreatePort(NULL,0);
   if(!replyport) return(0L);

   packet = (struct StandardPacket *)
      AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
   if(!packet)
      {
      DeletePort(replyport);
      return(0L);
      }

   packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
   packet->sp_Pkt.dp_Link	  = &(packet->sp_Msg);
   packet->sp_Pkt.dp_Port	  = replyport;
   packet->sp_Pkt.dp_Type	  = action;

   /* copy the args into the packet */
   pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
   for(count=0;count < nargs;count++)
      pargs[count]=args[count];

   PutMsg(pid,(struct Message *)packet); /* send packet */

   WaitPort(replyport);
   GetMsg(replyport);

   if(res)
   {
      lres = res[0] = packet->sp_Pkt.dp_Res1;
      res[1] = packet->sp_Pkt.dp_Res2;
   }

   FreeMem((char *)packet,(long)sizeof(struct StandardPacket));
   DeletePort(replyport);

   return(lres);
}

  *****
=*|_o_o|\\=====Doug Walker, Software Distiller====== BBS: (919)460-7430 =
 *|. o.| ||                                          1200/2400/9600 Dual
  | o  |//     For all you do, this bug's for you!
  ====== 
usenet: ...mcnc!rti!sas!walker   plink: dwalker  bix: djwalker 
Technical Details
Message-ID: <1990Nov20.185718.13083@unx.sas.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!uakari.primate.wisc.edu!uflorida!gatech!mcnc!rti!mozart!walker
References: <1990Nov7.185224.4215@cbnewsc.att.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!uakari.primate.wisc.edu!uflorida!gatech!mcnc!rti!mozart!walker
From: walker@unx.sas.com (Doug Walker)
Newsgroups: comp.sys.amiga.tech
Subject: Re: How do you send a DosPacket to a handler directly?
Keywords: DosPacket handler
Message-ID: <1990Nov20.185718.13083@unx.sas.com>
Date: 20 Nov 90 18:57:18 GMT
References: <1990Nov7.185224.4215@cbnewsc.att.com>
Organization: SAS Institute Inc.
Lines: 176