home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / filesys / nil_handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  6.9 KB  |  317 lines

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