/* at_kill.c */ /************************************************************************* *** AskTask Kill Process Module *** *** Date begun: 2/4/89. *** *** Last modified: 2/4/89. *** *************************************************************************/ /*** The idea is to reset the task's PC to the address of the code *** *** array, which calls the DOS function Exit(). This works! It should *** *** not be used while the task owns say, the blitter. Also, using the *** *** abort signal is better if the task cares about such things (say a *** *** Lattice C program during level 2(?) IO). It works best on pure *** *** processing tasks, for example during an infinite loop that does *** *** not do drawing or IO. *** *** Cut rmv(), changepri() & setsignal() into this module. *** *************************************************************************/ #include "asktask.h" extern struct Window *Window; extern int ct; extern struct Task *task[NUM_TASKS]; extern char *notaskerror; extern char mypri; extern struct Task *me; extern void putmessage(char *,int); extern int yesno(); extern void gettasks(); extern void puttasks(); extern void puttaskdata(); extern unsigned long bitsput(char *); extern void putbits(char *,unsigned long); extern char getchfromw(); static UWORD code[6] = { 0x721e, /* moveq #30,d1 */ 0x2c7c,0x0000,0x0000, /* movea.l #00000000,a6 */ 0x4eee,0xff70 /* jmp $ff70(a6) */ /* I would like to know how Exit() finds out which process this * task belongs to. */ }; void rmv(); /* Remove current task with RemTask() */ void kill(); /* Remove a task with Exit() function */ void setsignal(); /* Alter signal values for current task */ void changepri(); /* Change task's priority */ void rmv() /*=========================================================*/ { if (ct < 0) { putmessage(notaskerror,3); return; } putmessage("Are you sure you want to RemTask() the current task (y/n)?",3); if (!yesno()) { putmessage("",1); return; } RemTask(task[ct]); gettasks(); puttasks(); puttaskdata(); putmessage("RemTask() completed.",1); } void setsignal() /*===================================================*/ { unsigned long *l,lv; int loop; char ch,buf[40]; putmessage("",1); if (ct < 0) { putmessage(notaskerror,3); return; } putmessage("Which signal (Alloc/Wait/Recvd/Except/None) ?",3); loop = 1; while (loop) { ch = getchfromw(); switch (ch) { case (0x20): l = &(task[ct]->tc_SigAlloc); loop = 0; break; case (0x11): l = &(task[ct]->tc_SigWait); loop = 0; break; case (0x13): l = &(task[ct]->tc_SigRecvd); loop = 0; break; case (0x12): l = &(task[ct]->tc_SigExcept); loop = 0; break; case (0x45): case (0x36): putmessage("",1); return; /* n */ } } putbits(&buf[0],*l); putmessage("Enter the signal bit values:",1); input(Window,buf,buf,"01",236,135,32,1,0); lv = bitsput(buf); *l = lv; puttaskdata(); } void changepri() /*===================================================*/ { int pri,newpri; char buf[11]; putmessage("",1); if (ct < 0) { putmessage(notaskerror,3); return; } pri = (int)task[ct]->tc_Node.ln_Pri; newpri = pri; sprintf(buf,"%d",pri); putmessage("Change priority to :",1); input(Window,buf,buf,"0123456789-+",172,135,4,1,0); putmessage("",1); if (!buf[0]) return; sscanf(buf,"%d",&newpri); if (newpri == pri) return; if (newpri < -128) newpri = -128; else if (newpri > 122) newpri = 122; if (newpri > mypri) { mypri = newpri + 5; /* Don't block myself with task's priority. */ SetTaskPri(me,mypri); } SetTaskPri(task[ct],(char)newpri); puttaskdata(); } void kill() /*========================================================*/ { unsigned long *lp; ULONG *stk; if (ct < 0) { putmessage(notaskerror,3); return;} putmessage("Are you sure you want to try Exit()ing this process (y/n)?",3); if (!yesno()) { putmessage("",1); return;} lp = (unsigned long *)&code[2]; /* Set up code for dosbase value */ *lp = (unsigned long)DOSBase; Disable(); /* Now get at task's pc */ stk = (ULONG *)task[ct]->tc_SPReg; /* Have stack pointer... */ stk[0] = (ULONG)&code[0]; /* ...will travel. Here I go.... */ Enable(); putmessage("",1); } /******************** CONTEXT SWITCH STACK CONTENTS ********************** *** As far as I can tell, the data on the stack is: *** *** 0 = (long) pc *** *** 1 = (word) status reg *** *** 2... = other registers. *** *************************************************************************/