[comp.sys.atari.st] Ctrl-C

steven@cwi.nl (Steven Pemberton) (08/16/88)

Gemdos only registers a ctrl-c when something is written to the
screen, or read from the keyboard (and then only non-raw I/O).

I've struggled to find a way of getting Gemdos to react at other
times, but all with failure.  I've tried testing to see if a character
is available, writing zero characters with Cconws, and a dozen other
ways, all to no avail.

With MS-DOS (on which Gemdos is modelled), there is a way of polling
to see if a ctrl-c has been typed, by telling Dos that you also want
ctrl-c checked when non I/O system calls are called, and then doing
some benign system call, like reading the time.

Unfortunately, with Gemdos they apparently forgot to allow this.

So it seems to me that the only way of allowing ctrl-c when you're not
doing I/O is the following:

	If output is not redirected: periodically write a NUL;
		this seems to have no effect on the screen, but does
		generate a ctrl-c trap if one has been typed. (If the
		output is redirected, the NUL's end up in the file.)

	If output is redirected, but input is not redirected:
		periodically read and buffer the input yourself.
		You could also do this in the above case.

	If both are redirected: read and discard raw characters from
		the keyboard, checking for ctrl-c.

My question is: does anybody know of a simpler method?

Steven Pemberton, CWI, Amsterdam; steven@cwi.nl

rosenkra@Alliant.COM (Bill Rosenkranz) (08/17/88)

In article <7620@boring.cwi.nl> steven@cwi.nl (or try mcvax!steven.uucp) writes:
->Gemdos only registers a ctrl-c when something is written to the
->screen, or read from the keyboard (and then only non-raw I/O).

 [ stuff deleted ]

->My question is: does anybody know of a simpler method?
->
->Steven Pemberton, CWI, Amsterdam; steven@cwi.nl

you could modify the entry into any of the gemdos/bios/xbios traps (see
osbind.o) to check for ^C. in this way, when any system call was made, a check
is first performed. this is not really equivalent to signal(3) under unix, but
is better than what's there now. MWC has a signal(3) function but i don't
know how/if it works. alcyon's does not seem to work.

-bill

leo@philmds.UUCP (Leo de Wit) (08/19/88)

In article <7620@boring.cwi.nl> steven@cwi.nl (or try mcvax!steven.uucp) writes:
>Gemdos only registers a ctrl-c when something is written to the
>screen, or read from the keyboard (and then only non-raw I/O).

Gemdos ctrl-c's are so to say synchronous, while you'd like them to be
asynchronous.

   [some lines deleted]...
>So it seems to me that the only way of allowing ctrl-c when you're not
>doing I/O is the following:
>
>	If output is not redirected: periodically write a NUL;
>		this seems to have no effect on the screen, but does
>		generate a ctrl-c trap if one has been typed. (If the
>		output is redirected, the NUL's end up in the file.)
>
>	If output is redirected, but input is not redirected:
>		periodically read and buffer the input yourself.
>		You could also do this in the above case.
>
>	If both are redirected: read and discard raw characters from
>		the keyboard, checking for ctrl-c.
>
>My question is: does anybody know of a simpler method?

As you have indicated more or less, you have to do a lot of work
yourself.  Having to distinguish between redirection and no
redirection, as well as writing null characters sounds terrible to me.
Take a large calculation - little I/O - ; you would have to add
Cconws's or similar stuff throughout the code (not too few so you have
a convenient response time, not too much so the performance won't
suffer).

A year or so ago I had the same problem; solved it by using a VBL
routine.  The solution was to check for control C in the keyboard input
buffer; if this was found, the return address on the supervisor stack
(pointing mostly in the user program or somewhere in the O.S.) was made
to point to a Pterm GEMDOS call. The routine distinguished between user
and supervisor mode and whether the program at hand was the desktop or
something like that. It worked most of the time; there were some
problems when trying to interrupt a GEMDOS call or something. I didn't
take the effort to solve this; maybe it's simple when taking a fresh
look at it again.  The main advantage is that control-c's are
asynchronous, and your program does not have to be cluttered by dummy
console output garbage, or other magic if raw I/O is being used.

I could post/mail what I have now, or try to solve the last bugs and post
it to the binaries/sources groups (will be an AUTO folder program).
Anyone interested?
                    Leo.

B.T.W. It might also be very handy to disable/enable control C's at
will (for example by keyboard control: after pressing some magic key,
or by program control: after executing a special trap). This could also
fix the problem of disabling ^C for inexperienced users hitting ^C by
accident whilst in the GEMDOS readline function (0xa I thought it was).
Any suggestions?

leo@philmds.UUCP (Leo de Wit) (08/22/88)

In article <2239@alliant.Alliant.COM> rosenkra@alliant.UUCP (Bill Rosenkranz) writes:
  [Steven Pemberton's question omitted]...

>you could modify the entry into any of the gemdos/bios/xbios traps (see
>osbind.o) to check for ^C. in this way, when any system call was made, a check
>is first performed. this is not really equivalent to signal(3) under unix, but
>is better than what's there now. MWC has a signal(3) function but i don't
>know how/if it works. alcyon's does not seem to work.

Although it is better than the current situation, this woun't stop a
non-I/O process. Try to break into this program:

main() { for (;;); } /* now, isn't this small 8-) */

Since no system call is made within the for loop it will go on forever,
even if ^C is hit.

Before the weekend I promised to look into an old break version I had
laying somewhere, that used a VBL interrupt routine to check for ^C. A
problem with this scheme was that it could not always get the ^C before
a bios call did.  After some puzzling I got the solution: the keyboard
interrupt vector (#$46) is changed to my own routine (in a memory
resident program). After this one has executed first the old code, a
check for the break character is done.  This is an airtight way to
intercept a special character and do with it whatever you like.

The original was a C program I wrote a year ago; it has been changed to
an assembler program (this must be an improvement 8-) and mailed to
Steven Grimm today in both an uuencoded binary and a source form.

B.T.W. If you don't mind bill, signal is (2) in unix, being a system
call ((3) is the library functions department).

                       Leo.

bader@spice.cs.cmu.edu (Miles Bader) (08/22/88)

In article <608@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
>B.T.W. If you don't mind bill, signal is (2) in unix, being a system
>call ((3) is the library functions department).

In BSD, signal(3) is a library routine that calls sigvec(2)...

-Miles

rosenkra@Alliant.COM (Bill Rosenkranz) (08/22/88)

In article <608@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
->In article i wrote:
->  [Steven Pemberton's question omitted]...
->

  [ my osbind.o mod here... (i know it's not the best, but is the easiest :^)]

->Although it is better than the current situation, this woun't stop a
->non-I/O process. Try to break into this program:

not all system calls are i/o but you are essentially correct...

->main() { for (;;); } /* now, isn't this small 8-) */

yes, i know...but then again, who writes a program like this?

->Since no system call is made within the for loop it will go on forever,
->even if ^C is hit.

yes, yes...

->Before the weekend I promised to look into an old break version I had
->laying somewhere, that used a VBL interrupt routine to check for ^C. A

next best solution...

->problem with this scheme was that it could not always get the ^C before
->a bios call did.  

ok...

->           After some puzzling I got the solution: the keyboard
->interrupt vector (#$46) is changed to my own routine (in a memory
->resident program). After this one has executed first the old code, a
->check for the break character is done.  This is an airtight way to
->intercept a special character and do with it whatever you like.

sounds good...

->B.T.W. If you don't mind bill, signal is (2) in unix, being a system
->call ((3) is the library functions department).
->
->                       Leo.

sorry, leo, but on our system (BSD4.2) signal is in fact (3), not (2).
signal actually uses sigvec(2) and other related calls to the os.

-bill