home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / utils / asynch.lha / dos.async.example
Text File  |  1986-09-22  |  9KB  |  250 lines

  1.  
  2. From ptsfa!hoptoad!lll-crg!caip!cbmvax!phillip Sun Sep 14 00:38:56 PDT 1986 
  3. Article 4261 of net.micro.amiga: 
  4. Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site well.UUCP 
  5. Path: well!ptsfa!hoptoad!lll-crg!caip!cbmvax!phillip 
  6. >From: phillip@cbmvax.cbm.UUCP (Phillip Lindsay) 
  7. Newsgroups: net.micro.amiga 
  8. Subject: AmigaDos Asynchronous File I/O Example 
  9. Message-ID: <702@cbmvax.cbmvax.cbm.UUCP> 
  10. Date: 5 Sep 86 18:50:21 GMT 
  11. Date-Received: 6 Sep 86 11:14:55 GMT 
  12. Organization: Commodore Technology, West Chester, PA 
  13. Lines: 233 
  14.  
  15. [a line is to a line as is a line] 
  16.  
  17.    For all those people interested in implementing AmigaDos file I/O 
  18.    with an asynchronous design. 
  19.  
  20. ============================================================================== 
  21.   Phillip Lindsay - Commodore Business Machines - Amiga Technical Support 
  22.     Dirt: 1200 Wilson Drive, West Chester  PA 19380                 
  23.     uucp: {ihnp4|seismo|caip}!cbmvax!phillip 
  24.     arpa: cbmvax!phillip@seismo -or- phillip@cbmvax.UUCP@{seismo | harvard} 
  25.     Tel.: (215) 431-9180 
  26.   Disclaimer: [someone said I needed this] No warranty is implied or otherwise 
  27.    given in the form of suggestion or example. Any opinions found here are of 
  28.    my making. [unless Fred pops up (my other self)]  
  29. ============================================================================== 
  30.  
  31. /***CUT HERE***/ 
  32.  
  33. /* asendpacket.c - (asynchronous)        send multiple packets to a dos-      */ 
  34. /* 05-SEP-86                                handler                           */ 
  35. /* Phillip Lindsay - Commodore-Amiga                                          */ 
  36.  
  37. #include "exec/types.h" 
  38. #include "exec/ports.h" 
  39. #include "exec/io.h" 
  40. #include "exec/memory.h" 
  41. #include "libraries/dos.h" 
  42. #include "libraries/dosextens.h" 
  43. #include <stdio.h> 
  44. #include "functions.h"           /* aztec C include */ 
  45.  
  46.  
  47. #define DOSTRUE             -1L  /* AmigaDos TRUE */ 
  48. #define MAXARGS              7L  /* limit in packet structure (dosextens.h) */ 
  49.  
  50. /*  
  51.    asynchronous sendpkt routine  
  52.    you must supply a port for packet replies...This function returns the 
  53.    address of the pending packet.  
  54.  
  55. */  
  56. long asendpkt(replyport,pid,action,args,nargs) 
  57.  
  58. struct MsgPort *replyport; /* where all packet replies are sent */ 
  59. struct MsgPort *pid;      /* process indentifier ... (handlers message port ) */ 
  60. long action,             /* packet type ... (what you want handler to do )   */ 
  61.      args[],            /* a pointer to a argument list */ 
  62.      nargs;            /* number of arguments in list  */ 
  63.    
  64.  struct StandardPacket *packet; 
  65.   
  66.  long   count, *pargs;  
  67.  
  68.  if(nargs > MAXARGS) exit(FALSE);  
  69.   
  70.  packet = (struct StandardPacket *)  
  71.    AllocMem((long)sizeof(*packet),MEMF_PUBLIC | MEMF_CLEAR); 
  72.  if(!packet)  
  73.    { 
  74.     FreeMem(packet,(long)sizeof(*packet)); 
  75.     return(NULL); 
  76.    } 
  77.  
  78.  packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt); /* link packet- */ 
  79.  packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);        /* to message    */ 
  80.  packet->sp_Pkt.dp_Port         = replyport;         /* set-up reply port   */ 
  81.  packet->sp_Pkt.dp_Type         = action;           /* what to do... */ 
  82.  
  83.  /* move all the arguments to the packet */ 
  84.  pargs = &(packet->sp_Pkt.dp_Arg1);        /* address of first argument */ 
  85.  for(count=NULL;count < nargs;count++)  
  86.    pargs[count]=args[count]; 
  87.  
  88.  PutMsg(pid,packet); /* send packet */ 
  89.  
  90.  return((long)packet);   /* everything went ok...so far... give-em the packet */ 
  91.    
  92.  
  93. /* end of asendpkt.c */ 
  94.  
  95.  
  96. /*  
  97.    
  98.    simple packet flush with error detection ... returns ZERO for error 
  99.    or DOSTRUE (-1) for a-o-k. 
  100.     
  101.    A packet error can be detected in most cases by "Res1" being equal 
  102.    to zero--"Res2" will hold more information pertaining to the error.  
  103.    The problem with handling multiple packets is detecting an error for a  
  104.    particular packet. What makes things a little more difficult is the fact 
  105.    that the "Res1" member of the packet structure is not generally an  
  106.    indicator of an error. So depending on what type of packets you'll be 
  107.    handling you might want to deal with packet replies differently. 
  108.  
  109.    ( I was designing a elegant packet handling tool, but I found that 
  110.       AmigaDos doesn't handle ports like EXEC does. So I couldn't have 
  111.       a software interrupt generated on packet arrvial [sigh...] Tim?  )  
  112.  
  113. */ 
  114.  
  115. long pktflush(rport,pkts) 
  116. struct MsgPort *rport;      /* reply port for packets     */ 
  117. long           pkts;        /* number of packets to flush */ 
  118.  
  119.  struct StandardPacket *apkt; 
  120.  long res1,cres; 
  121.  
  122.  res1 = DOSTRUE; 
  123.  
  124.  while(pkts--)                          /* received all packets? */ 
  125.   { 
  126.    WaitPort(rport);                     /* sleep until a packet arrives */ 
  127.    apkt = (struct StandardPacket *) GetMsg(rport);       /* get packet */ 
  128.    cres = apkt->sp_Pkt.dp_Res1;         /* get result */ 
  129.    FreeMem(apkt,(long)sizeof(*apkt));   /* free packet structure from memory  */ 
  130.    res1 = (!cres ? cres : res1);        /* error?     */   
  131.   }  
  132.  
  133.  return(res1); 
  134.  
  135.    
  136. /*  
  137.    for all those people interested in implementing AmigaDos file I/O 
  138.    with an asynchronous design. 
  139. */ 
  140.   
  141.  
  142. /* start of example */ 
  143.  
  144. #define NARGS    3L                      /* number of arguments */ 
  145. #define NBUFFS   3L                      /* number of buffers   */ 
  146. #define BUFFLEN 60L                      /* buffer length       */ 
  147. #define ESC     27L 
  148.  
  149. main() 
  150.  
  151.  struct MsgPort        *filehdlr;      /* for process id  handler  */ 
  152.  struct MsgPort        *rport;         /* where all packets return */ 
  153.  long                  arg[NARGS],     /* array of arguments       */ 
  154.                        rpkt,           /* holds returned packet    */ 
  155.                        count;          /* count messages           */  
  156.  struct FileHandle     *filehandle;    /* our file handle          */ 
  157.  BPTR                  fh,             /* AmigaDos file handle     */ 
  158.                        fharg1;         /* Arg1 from filehandle     */ 
  159.  UBYTE                 *buff;          /* buffer pointer           */ 
  160.  struct StandardPacket *pkt;           /* our packet               */ 
  161.   
  162.  
  163. /* get buffers */ 
  164.  buff = (UBYTE *) AllocMem((BUFFLEN * NBUFFS),MEMF_PUBLIC | MEMF_CLEAR); 
  165.  if(!buff) exit(TRUE); 
  166.  
  167.  rport = (struct MsgPort *) CreatePort(NULL,NULL); /* make reply port */ 
  168.  if(!rport)  
  169.   {  
  170.    FreeMem(buff,(BUFFLEN * NBUFFS)); 
  171.    exit(TRUE); 
  172.   } 
  173.  
  174. /* here we open a dummy file */ 
  175.  fh = (BPTR) Open("df1:temp",MODE_NEWFILE); 
  176.  if(!fh)  
  177.   { 
  178.    FreeMem(buff,(BUFFLEN * NBUFFS)); 
  179.    DeletePort(rport); 
  180.    exit(TRUE); 
  181.   } 
  182.  
  183. /* bring our AmigaDos file handle into the real world... */ 
  184.  filehandle = (struct FileHandle *)  (fh << 2); 
  185.  
  186. /* read your AmigaDOS Technical Reference Manual for packet requirements */ 
  187.  
  188.  fharg1     = filehandle->fh_Arg1;  /* get Arg1 */ 
  189.   
  190.  filehdlr   = filehandle->fh_Type;  /* get handler for file */ 
  191.   
  192. /*  
  193.    you could get process id of the handler this way also ... 
  194.       filehdlr = (struct MsgPort *) DeviceProc("DF1:"); 
  195. */ 
  196.  
  197. /* give each buffer unique data */ 
  198.  
  199.  for(count=0;count < (BUFFLEN * NBUFFS);count ++) 
  200.   buff[count]= 0x31 + (count / BUFFLEN); 
  201.  
  202. /* set-up arguments and send packets */ 
  203.  
  204.  arg[0]= (long) fharg1;        /* file handle Arg1  */ 
  205.  arg[1]= (long) &buff[0];     /* buffer            */ 
  206.  arg[2]=        BUFFLEN;     /* buffer length     */ 
  207.  puts("one"); 
  208.  rpkt = asendpkt(rport,filehdlr,ACTION_WRITE,arg,NARGS); 
  209.  
  210.  arg[1]= (long) &buff[BUFFLEN]; 
  211.  puts("two"); 
  212.  rpkt = asendpkt(rport,filehdlr,ACTION_WRITE,arg,NARGS); 
  213.  
  214.  arg[1]= (long) &buff[BUFFLEN + BUFFLEN]; 
  215.  puts("three"); 
  216.  rpkt = asendpkt(rport,filehdlr,ACTION_WRITE,arg,NARGS); 
  217.  
  218. /* a more elegant packet flush routine would be nice */ 
  219.  
  220. if(!pktflush(rport,3L)) puts("Error in packets sent."); 
  221.  
  222. /* done clean up... */ 
  223.  Close(fh); 
  224.  FreeMem(buff,(BUFFLEN * NBUFFS)); 
  225.  DeletePort(rport); 
  226.  exit(FALSE); 
  227.   
  228.  
  229. /* eof */ 
  230. --  
  231.  
  232. ============================================================================== 
  233.   Phillip Lindsay - Commodore Business Machines - Amiga Technical Support 
  234.     Dirt: 1200 Wilson Drive, West Chester  PA 19380                 
  235.     uucp: {ihnp4|seismo|caip}!cbmvax!phillip 
  236.     arpa: cbmvax!phillip@seismo -or- phillip@cbmvax.UUCP@{seismo | harvard} 
  237.     Tel.: (215) 431-9180 
  238. Disclaimer: [someone said I needed this] No warranty is implied or otherwise 
  239.    given in the form of suggestion or example. Any opinions found here are of 
  240.    my making. [unless Fred pops up (my other self)]  
  241. ============================================================================== 
  242.  
  243.