home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / workbench / devs / nil_handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-27  |  6.8 KB  |  294 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: nil_handler.c,v 1.7 1997/01/27 00:22:40 ldp Exp $
  4.     $Log: nil_handler.c,v $
  5.     Revision 1.7  1997/01/27 00:22:40  ldp
  6.     Include proto instead of clib
  7.  
  8.     Revision 1.6  1996/12/10 13:59:49  aros
  9.     Moved #include into first column to allow makedepend to see it.
  10.  
  11.     Revision 1.5  1996/11/14 22:33:52  aros
  12.     Fixed register conflict
  13.  
  14.     Revision 1.4  1996/10/24 15:50:21  aros
  15.     Use the official AROS macros over the __AROS versions.
  16.  
  17.     Revision 1.3  1996/10/10 13:14:54  digulla
  18.     ? (Fleischer)
  19.  
  20.     Revision 1.2  1996/09/12 14:52:00  digulla
  21.     Use correct way to access external names (was missing)
  22.  
  23.     Revision 1.1  1996/09/11 12:52:54  digulla
  24.     Two new devices by M. Fleischer: RAM: and NIL:
  25.  
  26.     Desc:
  27.     Lang:
  28. */
  29. #include <exec/errors.h>
  30. #include <exec/resident.h>
  31. #include <exec/memory.h>
  32. #include <proto/exec.h>
  33. #include <utility/tagitem.h>
  34. #include <dos/dosextens.h>
  35. #include <dos/filesystem.h>
  36. #include <proto/dos.h>
  37. #include <aros/libcall.h>
  38. #ifdef __GNUC__
  39. #include "nil_handler_gcc.h"
  40. #endif
  41.  
  42. static const char name[];
  43. static const char version[];
  44. static const APTR inittabl[4];
  45. static void *const functable[];
  46. struct nilbase *AROS_SLIB_ENTRY(init,nil_handler)();
  47. void AROS_SLIB_ENTRY(open,nil_handler)();
  48. BPTR AROS_SLIB_ENTRY(close,nil_handler)();
  49. BPTR AROS_SLIB_ENTRY(expunge,nil_handler)();
  50. int AROS_SLIB_ENTRY(null,nil_handler)();
  51. void AROS_SLIB_ENTRY(beginio,nil_handler)();
  52. LONG AROS_SLIB_ENTRY(abortio,nil_handler)();
  53. static const char end;
  54.  
  55. int nil_handler_entry(void)
  56. {
  57.     /* If the handler was executed by accident return error code. */
  58.     return -1;
  59. }
  60.  
  61. const struct Resident nil_handler_resident=
  62. {
  63.     RTC_MATCHWORD,
  64.     (struct Resident *)&nil_handler_resident,
  65.     (APTR)&end,
  66.     RTF_AUTOINIT,
  67.     1,
  68.     NT_DEVICE,
  69.     0,
  70.     (char *)name,
  71.     (char *)&version[6],
  72.     (ULONG *)inittabl
  73. };
  74.  
  75. static const char name[]="nil.handler";
  76.  
  77. static const char version[]="$VER: nil_handler 1.0 (8.6.96)\n\015";
  78.  
  79. static const APTR inittabl[4]=
  80. {
  81.     (APTR)sizeof(struct nilbase),
  82.     (APTR)functable,
  83.     NULL,
  84.     &AROS_SLIB_ENTRY(init,nil_handler)
  85. };
  86.  
  87. static void *const functable[]=
  88. {
  89.     &AROS_SLIB_ENTRY(open,nil_handler),
  90.     &AROS_SLIB_ENTRY(close,nil_handler),
  91.     &AROS_SLIB_ENTRY(expunge,nil_handler),
  92.     &AROS_SLIB_ENTRY(null,nil_handler),
  93.     &AROS_SLIB_ENTRY(beginio,nil_handler),
  94.     &AROS_SLIB_ENTRY(abortio,nil_handler),
  95.     (void *)-1
  96. };
  97.  
  98. AROS_LH2(struct nilbase *, init,
  99.  AROS_LHA(struct nilbase *, nilbase, D0),
  100.  AROS_LHA(BPTR,             segList, A0),
  101.        struct ExecBase *, sysBase, 0, nil_handler)
  102. {
  103.     AROS_LIBFUNC_INIT
  104.  
  105.     /* Store arguments */
  106.     nilbase->sysbase=sysBase;
  107.     nilbase->seglist=segList;
  108.     nilbase->dosbase=(struct DosLibrary *)OpenLibrary("dos.library",39);
  109.     if(nilbase->dosbase!=NULL)
  110.     return nilbase;
  111.  
  112.     return NULL;
  113.     AROS_LIBFUNC_EXIT
  114. }
  115.  
  116. AROS_LH3(void, open,
  117.  AROS_LHA(struct IOFileSys *, iofs, A1),
  118.  AROS_LHA(ULONG,              unitnum, D0),
  119.  AROS_LHA(ULONG,              flags, D1),
  120.        struct nilbase *, nilbase, 1, nil_handler)
  121. {
  122.     AROS_LIBFUNC_INIT
  123.     ULONG *dev;
  124.  
  125.     /* Get compiler happy */
  126.     unitnum=flags=0;
  127.  
  128.     /* I have one more opener. */
  129.     nilbase->device.dd_Library.lib_OpenCnt++;
  130.  
  131.     /* Mark Message as recently used. */
  132.     iofs->IOFS.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
  133.  
  134.     dev=AllocMem(sizeof(ULONG),MEMF_PUBLIC|MEMF_CLEAR);
  135.     if(dev!=NULL)
  136.     {
  137.         iofs->IOFS.io_Unit=(struct Unit *)dev;
  138.         iofs->IOFS.io_Device=&nilbase->device;
  139.         nilbase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
  140.         iofs->IOFS.io_Error=0;
  141.         return;
  142.     }else
  143.     iofs->io_DosError=ERROR_NO_FREE_STORE;
  144.     
  145.     iofs->IOFS.io_Error=IOERR_OPENFAIL;
  146.     nilbase->device.dd_Library.lib_OpenCnt--;
  147.  
  148.     AROS_LIBFUNC_EXIT
  149. }
  150.  
  151. AROS_LH1(BPTR, close,
  152.  AROS_LHA(struct IOFileSys *, iofs, A1),
  153.        struct nilbase *, nilbase, 2, nil_handler)
  154. {
  155.     AROS_LIBFUNC_INIT
  156.     ULONG *dev;
  157.    
  158.     dev=(ULONG *)iofs->IOFS.io_Unit;
  159.     if(*dev)
  160.     {
  161.     iofs->io_DosError=ERROR_OBJECT_IN_USE;
  162.     return 0;
  163.     }
  164.  
  165.     /* Let any following attemps to use the device crash hard. */
  166.     iofs->IOFS.io_Device=(struct Device *)-1;
  167.     FreeMem(dev,sizeof(ULONG));
  168.     iofs->io_DosError=0;
  169.  
  170.     /* I have one fewer opener. */
  171.     if(!--nilbase->device.dd_Library.lib_OpenCnt)
  172.     {
  173.     /* Delayed expunge pending? */
  174.     if(nilbase->device.dd_Library.lib_Flags&LIBF_DELEXP)
  175.         /* Then expunge the device */
  176.         return expunge();
  177.     }
  178.     return 0;
  179.     AROS_LIBFUNC_EXIT
  180. }
  181.  
  182. AROS_LH0(BPTR, expunge, struct nilbase *, nilbase, 3, nil_handler)
  183. {
  184.     AROS_LIBFUNC_INIT
  185.  
  186.     BPTR ret;
  187.     /*
  188.     This function is single-threaded by exec by calling Forbid.
  189.     Never break the Forbid() or strange things might happen.
  190.     */
  191.  
  192.     /* Test for openers. */
  193.     if(nilbase->device.dd_Library.lib_OpenCnt)
  194.     {
  195.     /* Set the delayed expunge flag and return. */
  196.     nilbase->device.dd_Library.lib_Flags|=LIBF_DELEXP;
  197.     return 0;
  198.     }
  199.  
  200.     /* Free all resources */
  201.     CloseLibrary((struct Library *)nilbase->dosbase);
  202.  
  203.     /* Get rid of the device. Remove it from the list. */
  204.     Remove(&nilbase->device.dd_Library.lib_Node);
  205.  
  206.     /* Get returncode here - FreeMem() will destroy the field. */
  207.     ret=nilbase->seglist;
  208.  
  209.     /* Free the memory. */
  210.     FreeMem((char *)nilbase-nilbase->device.dd_Library.lib_NegSize,
  211.         nilbase->device.dd_Library.lib_NegSize+nilbase->device.dd_Library.lib_PosSize);
  212.  
  213.     return ret;
  214.     AROS_LIBFUNC_EXIT
  215. }
  216.  
  217. AROS_LH0I(int, null, struct nilbase *, nilbase, 4, nil_handler)
  218. {
  219.     AROS_LIBFUNC_INIT
  220.     return 0;
  221.     AROS_LIBFUNC_EXIT
  222. }
  223.  
  224. AROS_LH1(void, beginio,
  225.  AROS_LHA(struct IOFileSys *, iofs, A1),
  226.        struct nilbase *, nilbase, 5, nil_handler)
  227. {
  228.     AROS_LIBFUNC_INIT
  229.     LONG error=0;
  230.  
  231.     /*
  232.     Do everything quick no matter what. This is possible
  233.     because I never need to Wait().
  234.     */
  235.     switch(iofs->IOFS.io_Command)
  236.     {
  237.     case FSA_OPEN:
  238.     case FSA_OPEN_FILE:
  239.         /* No names allowed on NIL: */
  240.         if(((STRPTR)iofs->io_Args[0])[0])
  241.         {
  242.         error=ERROR_OBJECT_NOT_FOUND;
  243.         break;
  244.         }
  245.         Forbid();
  246.         ++*(ULONG *)iofs->IOFS.io_Unit;
  247.         Permit();
  248.         break;
  249.  
  250.     case FSA_READ:
  251.         iofs->io_Args[1]=0;
  252.         break;
  253.  
  254.     case FSA_WRITE:
  255.         break;
  256.  
  257.     case FSA_SEEK:
  258.         iofs->io_Args[0]=0;
  259.         iofs->io_Args[1]=0;
  260.         break;
  261.  
  262.     case FSA_CLOSE:
  263.         Forbid();
  264.         --*(ULONG *)iofs->IOFS.io_Unit;
  265.         Permit();
  266.         break;
  267.  
  268.     default:
  269.         error=ERROR_NOT_IMPLEMENTED;
  270.         break;
  271.     }
  272.  
  273.     /* Set error code */
  274.     iofs->io_DosError=error;
  275.  
  276.     /* If the quick bit is not set send the message to the port */
  277.     if(!(iofs->IOFS.io_Flags&IOF_QUICK))
  278.     ReplyMsg(&iofs->IOFS.io_Message);
  279.  
  280.     AROS_LIBFUNC_EXIT
  281. }
  282.  
  283. AROS_LH1(LONG, abortio,
  284.  AROS_LHA(struct IOFileSys *, iofs, A1),
  285.        struct nilbase *, nilbase, 6, nil_handler)
  286. {
  287.     AROS_LIBFUNC_INIT
  288.     /* Everything already done. */
  289.     return 0;
  290.     AROS_LIBFUNC_EXIT
  291. }
  292.  
  293. static const char end=0;
  294.