Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!usc!apple!agate!linus!linus!mbunix!duncant From: duncant@mbunix.mitre.org (Thomson) Newsgroups: comp.sys.amiga.tech Subject: Asynchronous I/O, Packet Interface (Need Help) Message-ID: <126865@linus.mitre.org> Date: 27 Nov 90 00:43:34 GMT Sender: usenet@linus.mitre.org Organization: The MITRE Corp., Bedford, MA Lines: 177 I'm looking for some help in how to do asynchronous I/O using the AmigaDOS packet interface. I can't get it to work, even for the most simple case, and I'm sure that I'm not making a programming goof. I think that my problem is that I'm working from an "AmigaDOS Technical Reference Manual" that applies to AmigaDOS 1.0. I assumed that later releases were all backward compatible, so that if I coded in accordance with this manual, my code would work, but apparantly this is not the case. Can someone who owns a more recent version of the documentation, or, even better, someone who knows from experience how this stuff is supposed to work, give me a hand here? I'd really appreciate it, as I'm totally stumped and have no way to debug any further. BTW, the Autodocs don't provide any help in this area, since they only cover function calls, not services obtained by sending packets to a handler, as is the case here. What I'm trying to do is send an AmigaDOS packet to a file system handler, requesting a Read on a file, which has already been opened by calling Open(). 1) Is the following the correct way to set up the arguments of the packet structure? std_pkt->sp_Pkt.dp_Type = ACTION_READ; std_pkt->sp_Pkt.dp_Arg1 = (LONG) in_hdl; /* BPTR to file handle */ std_pkt->sp_Pkt.dp_Arg2 = (LONG) storage; /* Normal C pointer to storage */ std_pkt->sp_Pkt.dp_Arg3 = size; /* Number of bytes to read */ Here, std_pkt is a pointer to a StandardPacket structure. 2) The StandardPacket structure contains a Message structure and a DosPacket structure. Is the following the correct way to initialize these structures? /* Initialize the Message structure within the StandardPacket structure */ std_pkt->sp_Msg.mn_Node.ln_Name = (char *) &(std_pkt->sp_Pkt); std_pkt->sp_Msg.mn_Node.ln_Type = NT_MESSAGE; std_pkt->sp_Msg.mn_ReplyPort = reply_port; std_pkt->sp_Msg.mn_Length = sizeof( struct DosPacket ); /* Initialize the DosPacket structure within the StandardPacket structure */ std_pkt->sp_Pkt.dp_Link = &(std_pkt->sp_Msg); std_pkt->sp_Pkt.dp_Port = reply_port; Here, reply_port is a pointer to a MsgPort structure, which has been created with a call to CreatePort. 3) If the answer to 1) and 2) is "Yes", then why, oh why, does my program bring up Mr. Guru? The complete code follows. Any help that could be offered would REALLY be appreciated. Perhaps someone from Commodore that works on AmigaDOS????? This is something I asked about on the net many months ago. Nobody was able to offer any help then, but I've since dug the program out and I'd really like to get it working. Duncan Thomson (duncant@mbunix.mitre.org) -----------------------------code follows-------------------------------------- /****************************************************************************** * * TESTIO.C * * Tests ASYNCHRONOUS I/O using the AmigaDOS packet interface. * * Run the program giving the name of a file. A single read * operation will be attempted on the file. * * Bugs: Program doesn't work. I wish I knew why! * */ #include #include #include #include #include #include main( argc, argv ) int argc; char *argv[]; { BPTR in_hdl; struct FileHandle *hptr; struct MsgPort *handler_proc; struct MsgPort *reply_port; struct StandardPacket *std_pkt; char *storage; /* Check for correct program invocation */ if( argc!=2 ) { printf( "Usage: %s infile_name\n", argv[0] ); exit( 10 ); } /* Open input file */ in_hdl = Open( argv[1], MODE_OLDFILE ); if( in_hdl == NULL ) puke_and_die( "Can't open input file" ); /* Get the handler process ID from the file handle */ hptr = (struct FileHandle *) BADDR( in_hdl ); handler_proc = (struct MsgPort *) (hptr->fh_Type); printf( "Handler proc id (from file handle) is: 0x%lx\n", handler_proc ); /* Just to check, get the process ID another way */ handler_proc = DeviceProc( argv[1] ); printf( "Handler proc id (from DeviceProc) is: 0x%lx\n", handler_proc ); /* Allocate storage area */ storage = malloc( 1024 ); if( storage==NULL ) puke_and_die( "No memory for storage" ); printf( "Storage ptr is: 0x%lx\n", storage ); /* Create a reply port */ reply_port = CreatePort( NULL, 0 ); if( reply_port==NULL ) puke_and_die( "Can't make a reply port" ); /* Set up standard packet */ std_pkt = (struct StandardPacket *) AllocMem( (long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR ); if( std_pkt==NULL ) puke_and_die( "Can't make a std packet" ); std_pkt->sp_Msg.mn_Node.ln_Name = (char *) &(std_pkt->sp_Pkt); std_pkt->sp_Msg.mn_Node.ln_Type = NT_MESSAGE; std_pkt->sp_Msg.mn_ReplyPort = reply_port; std_pkt->sp_Msg.mn_Length = sizeof( struct DosPacket ); std_pkt->sp_Pkt.dp_Link = &(std_pkt->sp_Msg); std_pkt->sp_Pkt.dp_Port = reply_port; /* Set up packet arguments to read from file into buffer */ std_pkt->sp_Pkt.dp_Arg1 = (LONG) in_hdl; std_pkt->sp_Pkt.dp_Type = ACTION_READ; std_pkt->sp_Pkt.dp_Arg2 = (LONG) storage; std_pkt->sp_Pkt.dp_Arg3 = 1; /* Now send the packet to the message port of the handler */ PutMsg( handler_proc, &(std_pkt->sp_Msg) ); printf( "Sent the message. Hit CR..." ); getchar(); /******** PROGRAM DIES ABOUT HERE ****************/ /* Wait for the reply and tae reply port */ WaitPort( reply_port ); GetMsg( reply_port ); printf( "Got the reply. Hit CR..." ); getchar(); /* Clean up */ free( std_pkt ); DeletePort( reply_port ); free( storage ); Close( in_hdl ); } /* end main */ /* ------------- */ puke_and_die( str ) char *str; { printf( "YEUCH GLEARCH URRRGH: %s\n", str ); printf( "You better reboot - I didn't clean up my mess!\n" ); exit( 10 ); } /* ---------- end of file ---------- */ -- (Please excuse the typos and garbage caused by line noise.)