Article View: comp.sys.atari.st
Article #31348Re: <Control> C and autostarting GEM programs
From: Allan Pratt
Date: Thu, 17 Mar 1988 19:15
Date: Thu, 17 Mar 1988 19:15
83 lines
3200 bytes
3200 bytes
From article <176@bdt.UUCP>, by david@bdt.UUCP (David Beckemeyer):
> In article <1008@atari.UUCP> apratt@atari.UUCP (Allan Pratt) writes:
>>It *is* just a simple longjmp! (Except that it gets executed in Super
>>mode -- but the handler can just consist of a longjmp.) If you have a...
>
> If the Pterm handler consists of just a longjmp, doesn't that mean that the
> supervisor stack is permanently shrinking, and that the program thereafter
> runs in supervisor mode, even if it was started in user mode? Wouldn't
> that mean that a lot (maybe not so many) ^C's would use up all the supervisor
> stack?
You misunderstand me. By "Pterm handler" I meant the thing YOU might
install to catch bombs, Pterm's, and ^C's yourself. *Of course* Pterm
is more complicated than that in Gemdos: it has to free your memory,
close your files, and so on.
If you want to execute some procedure (like removing your vblank routine)
when you get ^C, bombs, or Pterm, you should install the address of that
procedure as the terminate vector. When Pterm gets hit (for any of these
reasons), your handler will get called (via jsr, in super mode), and
when it returns, the Pterm continues and terminates the process. This
is what Sid does when it says "Bye!" -- that's the terminate handler
talking.
If you are a shell and you want to return to your command prompt when
the user hits ^C, you have to be a little more clever: you make the
terminate vector point to a routine which does a go-to-user-mode-and-longjmp
operation. The target of the longjmp is responsible for recovering from
the problem. Simply put, it could look like this:
#include <osbind.h>
#include <longjmp.h>
jmp_buf err_buf;
long old_terminate_value;
main_loop()
{
char cmdbuf[258];
int terminate_handler();
old_terminate_value = Setexc(0x102,terminate_handler);
if (setjmp(err_buf)) {
/* this code is target of longjmp */
Cconws("*Break*\r\n");
}
/* normal flow and longjmp both end up here */
cmdbuf[0] = 255;
while (1) {
Cconws(prompt_string);
Cconrs(cmdbuf);
cmdbuf[cmdbuf[1]+2] = 0; /* null-terminate the string */
do_cmdline(&cmdbuf[2]);
}
}
terminate_handler()
{
longjmp(err_buf,-1);
}
exit_command()
{
Setexc(0x102,old_terminate_value);
Pterm(0);
}
The above fragments assume that setjmp saves the SR of the caller and
restores it for the longjmp... This is a nontrivial thing to do because
you can't just use RTE from user mode.
The exit_command fragment is here to show that you have to UN-install the
vector before you Pterm, because otherwise it'll just get hit again.
Does this make anything more clear?
============================================
Opinions expressed above do not necessarily -- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else. ...ames!atari!apratt
Technical Details
Message-ID:
<1018@atari.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!portal!atari!aprattReferences:
<176@bdt.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!portal!atari!apratt From: apratt@atari.UUCP (Allan Pratt) Newsgroups: comp.sys.atari.st Subject: Re: <Control> C and autostarting GEM programs Message-ID: <1018@atari.UUCP> Date: 17 Mar 88 19:15:47 GMT References: <176@bdt.UUCP> Organization: Atari Corp., Sunnyvale CA Lines: 83