/* * DCMD-HANDLER.C * * DICE COMPILATION */ #include "defs.h" void _main() { XMsgPort *port; MsgPort *privatePort; long fh; { Process *proc = FindTask(NULL); port = FindPort(proc->pr_Task.tc_Node.ln_Name); } if (port == NULL) /* fall through */ return; privatePort = CreatePort(NULL, 0); /* * The RAM disk has the unique ability that when writing to a file * with a shared lock (1005), another process can load the file at * any time getting the most up to date information. */ if ((fh = Open(port->FileName, 1005)) == NULL) { if (fh = Open(port->FileName, 1006)) { Close(fh); fh = Open(port->FileName, 1005); } } if (fh) { Seek(fh, 0L, 1); Write(fh, "HANDLER-RUNNING\n", 16); } /* * set-up */ { Process *proc = port->Proc; /* CLI process */ port->Port.mp_Flags = PA_SIGNAL; port->Port.mp_SigBit= SIGBREAKB_CTRL_E; port->Port.mp_SigTask = FindTask(NULL); } for (;;) { Message *msg = GetMsg(port); DosPacket *packet; if (msg == NULL) { long mask = Wait((1 << port->Port.mp_SigBit) | SIGBREAKF_CTRL_F | SIGBREAKF_CTRL_D); if (mask & SIGBREAKF_CTRL_F) break; if (mask & SIGBREAKF_CTRL_D) { /* close-re-open */ if (fh) Close(fh); if (fh = Open(port->FileName, 1005)) Seek(fh, 0L, 1); continue; } continue; } packet = (DosPacket *)msg->mn_Node.ln_Name; switch(packet->dp_Type) { case ACTION_WRITE: if (fh) Write(fh, packet->dp_Arg2, packet->dp_Arg3); break; case ACTION_READ: /* re-arrange return path */ { MsgPort *replyPort = packet->dp_Port; /* return port */ packet->dp_Port = privatePort; /* redirect */ PutMsg(port->OldConsoleTask, msg); WaitPort(privatePort); GetMsg(privatePort); if (packet->dp_Res2 == 0 && packet->dp_Res1 > 0) { if (fh) Write(fh, packet->dp_Arg2, packet->dp_Res1); } PutMsg(replyPort, packet->dp_Link); /* -> original */ packet = NULL; } break; } if (packet) PutMsg(port->OldConsoleTask, msg); } if (fh) Close(fh); /* * Until receive SIGBREAKF_CTRL_F, then handshake/exit */ port->Proc->pr_ConsoleTask = port->OldConsoleTask; { FileHandle *fh; CLI *cli = BTOC(port->Proc->pr_CLI); if ((fh = BTOC(cli->cli_CurrentOutput)) && fh->fh_Type == (MsgPort *)port) fh->fh_Type = port->OldConsoleTask; if ((fh = BTOC(cli->cli_CurrentInput)) && fh->fh_Type == (MsgPort *)port) fh->fh_Type = port->OldConsoleTask; } DeletePort(privatePort); Forbid(); { Task *task = port->Port.mp_SigTask; port->Port.mp_SigTask = NULL; Signal(task, SIGBREAKF_CTRL_E); } }