home *** CD-ROM | disk | FTP | other *** search
- /*
- halt_library.c --- halt library interface.
-
- (c) Copyright 1995 SHW Wabnitz
- Written by Bernhard Fastenrath (fasten@shw.com)
-
- This file may be distributed under the terms
- of the GNU General Public License.
- */
-
- #if defined (__GNUC__)
- #include <stabs.h>
- #endif
-
- #include "halt_library.h"
-
- struct ExecBase *SysBase = NULL;
- struct DosLibrary *DOSBase = NULL;
- struct Library *HaltBase = NULL;
- struct List Clients;
- ULONG ClientsListBusy = 0;
-
- #if defined (__GNUC__)
- const BYTE LibName[] = "halt.library";
- const BYTE LibIdString[] = "$VER: halt.library 2.0 (10-6-95)";
- const UWORD LibVersion = 2;
- const UWORD LibRevision = 0;
- #endif
-
- #if defined (__GNUC__)
- #define LIBRT
- #define REG_a6
- #define REG_d1
- #define STRUCT_MYLIB struct Library
- #else
- #define LIBRT __saveds __asm
- #define REG_a6 register __a6
- #define REG_d1 register __d1
- #define ADDTABL_1(name,arg1);
- #define ADDTABL_END();
- #define STRUCT_MYLIB struct MyLibrary
- #endif
-
- static void
- cleanup (void)
- {
- if (DOSBase)
- CloseLibrary ((struct Library *) DOSBase);
- DOSBase = NULL;
- }
-
- int LIBRT
- __UserLibInit (REG_a6 STRUCT_MYLIB *libbase)
- {
- SysBase = *(struct ExecBase **)4;
- HaltBase = (struct Library *) libbase;
-
- if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
- return 1;
- NewList (&Clients);
- return 0; /* success */
- }
-
- void LIBRT
- __UserLibCleanup (REG_a6 STRUCT_MYLIB *libbase)
- {
- cleanup ();
- }
-
- ADDTABL_1(LIBReboot,d1);
-
- int LIBRT
- LIBReboot (REG_d1 int flags)
- {
- if (flags)
- {
- Disable ();
- while (1);
- }
- ColdReboot ();
- return 1;
- }
-
- ADDTABL_1(LIBUnmount,d1);
-
- int LIBRT
- LIBUnmount (REG_d1 char *filesystem)
- {
- return unmount (NULL, filesystem);
- }
-
- ADDTABL_1(LIBAddShutdownPort,d1);
-
- int LIBRT
- LIBAddShutdownPort (REG_d1 MsgPort *prt)
- {
- ShutdownClient *scl;
-
- if (((struct Process *) prt -> mp_SigTask) -> pr_WindowPtr != (void *) -1)
- return 0;
-
- if (!(scl = (ShutdownClient *) AllocMem (sizeof (ShutdownClient), MEMF_PUBLIC)))
- return 0;
-
- scl -> port = prt;
- scl -> done = 0;
- Forbid ();
- AddHead (&Clients, (Node *) scl);
- Permit ();
- return 1;
- }
-
- ADDTABL_1(LIBRemShutdownPort,d1);
-
- int LIBRT
- LIBRemShutdownPort (REG_d1 MsgPort *prt)
- {
- MinNode *mln;
- int ret = 0;
-
- Forbid ();
- for (mln = (MinNode *) Clients.lh_Head; mln -> mln_Succ; mln = mln -> mln_Succ)
- if (((ShutdownClient *) mln) -> port == prt)
- {
- if (ClientsListBusy)
- ((ShutdownClient *) mln) -> done = 1;
- else
- {
- Remove ((Node *) mln);
- FreeMem (mln, sizeof (ShutdownClient));
- }
- ret = 1;
- break;
- }
- Permit ();
- return ret;
- }
-
- ADDTABL_1(LIBShutdownStatus,d1);
-
- int LIBRT
- LIBShutdownStatus (REG_d1 ShutdownMessage *smsg)
- {
- ShutdownClient *scl, *next;
- ULONG abortable = 0;
- MsgPort *prt;
- Task *me;
- ULONG mp_mask, mask, rmask;
-
- smsg -> sm_Context -> sc_rMask = 0;
- smsg -> sm_Context -> sc_Port = NULL;
-
- if (IsListEmpty (&Clients))
- return 1;
-
- me = FindTask (0);
- prt = smsg -> sm_Msg.mn_ReplyPort;
- if (smsg -> sm_Status != SHUTDOWN_HALT &&
- smsg -> sm_Status != SHUTDOWN_ABORT &&
- smsg -> sm_Status != SHUTDOWN_UMOUNT)
- {
- abortable = smsg -> sm_Flags & SDMF_ABORTABLE;
- }
- Forbid ();
- ClientsListBusy ++;
- Permit ();
- mp_mask = 1 << prt -> mp_SigBit;
- mask = mp_mask | SIGBREAKF_CTRL_C | smsg -> sm_Context -> sc_Mask;
-
- scl = (ShutdownClient *) Clients.lh_Head;
- while (next = (ShutdownClient *) scl -> node.mln_Succ)
- {
- if (scl -> done)
- {
- Forbid ();
- if (ClientsListBusy == 1)
- {
- Remove ((Node *) scl);
- FreeMem (scl, sizeof (ShutdownClient));
- }
- Permit ();
- }
- else
- {
- if (scl -> port -> mp_SigTask != me)
- {
- PutMsg (scl -> port, (Message *) smsg);
- for (;;)
- {
- if ((rmask = Wait (mask)) & mp_mask)
- {
- if (GetMsg (prt) == (Message *) smsg)
- break;
- else
- smsg -> sm_Context -> sc_TimeOuts --;
- }
- if (rmask & SIGBREAKF_CTRL_C)
- {
- smsg -> sm_Flags |= (SDMF_CANCEL | SDMF_CTRL_C);
- smsg -> sm_Context -> sc_Port = scl -> port;
- smsg -> sm_Context -> sc_TimeOuts ++;
- break;
- }
- if (rmask & smsg -> sm_Context -> sc_Mask)
- {
- /* Usually this is a timeout so we put the nasty
- program at the end of the list.
- */
- Remove ((Node *) scl);
- AddTail (&Clients, (Node *) scl);
- smsg -> sm_Flags |= SDMF_SIG_MASK;
- smsg -> sm_Context -> sc_Port = scl -> port;
- smsg -> sm_Context -> sc_TimeOuts ++;
- break;
- }
- }
- if (abortable && smsg -> sm_Flags & (SDMF_CANCEL | SDMF_SIG_MASK))
- break;
- }
- }
- scl = next;
- }
- smsg -> sm_Context -> sc_rMask = rmask;
- if (!abortable)
- smsg -> sm_Flags &= ~(SDMF_CANCEL | SDMF_CTRL_C);
-
- Forbid ();
- ClientsListBusy --;
- Permit ();
- return 1;
- }
-
- ADDTABL_END();
-
-