waldmann@exunido.uucp (Uwe Waldmann) (03/07/90)
I am trying to write an interrupt handler for Quintus Prolog (Rel. 2.4.2 on
a Sun-3 and/or a Sun-4). I wanted to take the demo example from the
"Quintus Prolog System-dependent Features Manual" (p. 15) as a starting
point, but unfortunately even this (unmodified) example does not work
properly:
/* ------ interrupt.c from "QP System-dependent Features Manual" ------ */
#include <signal.h>
#include "/usr/local/q2.4.2/library/qpaction.h"
int my_handler()
{
char c;
for (;;) {
printf("\nWell? ");
c = getchar();
if (c != '\n')
while (getchar() != '\n') {};
switch (c) {
case 'a': QP_action(QP_ABORT); /* abort */
case 'e': QP_action(QP_EXIT); /* exit */
case 'c': return; /* continue */
default: printf("a, c or e, please");
}
}
}
void establish_handler()
{
signal(SIGINT, my_handler);
}
% ------- interrupt.pl from "QP System-dependent Features Manual" --------
foreign_file('interrupt.o', [establish_handler]).
foreign(establish_handler, establish_handler).
:- load_foreign_files(['interrupt.o'], []).
:- establish_handler.
% ------- test -----------------------------------------------------------
uwe@issan(1)% cc -c interrupt.c
uwe@issan(2)% qprolog
Quintus Prolog Release 2.4.2 (Sun-4, SunOS 4.0)
Copyright (C) 1988, Quintus Computer Systems, Inc. All rights reserved.
1310 Villa Street, Mountain View, California (415) 965-7700
| ?- compile(interrupt).
[compiling /home/helga/uwe/testdir/qp-interrupts/interrupt.pl...]
[foreign file /home/helga/uwe/testdir/qp-interrupts/interrupt.o loaded]
[interrupt.pl compiled 0.100 sec 21,312 bytes]
yes
| ?- ^C % type interrupt character ^C
Well? a % new interrupt handler is invoked
[ Execution aborted ] % okay, abort command is handled properly
| ?- ^C % type interrupt character ^C again
Well? c % now try the "continue" command
% type <return>: nothing happens
% once more <return>: still no prompt
true. % now type in a goal
** Syntax error: **
m % where does this "m" come from???
** here **
true
% ------- end of test ----------------------------------------------------
If I repeat the last part, I get a "u" insted of an "m". It looks, as if
the input buffer gets corrupted somehow. On a Sun-3 and a Sun-4 the results
are the same.
Has somebody already noted this strange behaviour? Is there a bug in
"interrupt.c"? (Well, I know that declaring "my_handler" as "int" is bad
style, but with "void" I get the same result. I have also tried to put a
"return" after the "a" and "e" cases, but this didn't fix it either.)
Or is it a bug in Quintus Prolog? Is there any workaround known?
--
Uwe Waldmann
LS Informatik V
Universitaet Dortmund
Postfach 50 05 00
4600 Dortmund 50
West Germany
e-mail: uwe@ls5.informatik.uni-dortmund.dedon@quintus.UUCP (Don Ferguson) (03/09/90)
In article <2030@laura.UUCP> waldmann@exunido.UUCP (Uwe Waldmann) writes: >I am trying to write an interrupt handler for Quintus Prolog (Rel. 2.4.2 on >a Sun-3 and/or a Sun-4). I wanted to take the demo example from the >"Quintus Prolog System-dependent Features Manual" (p. 15) as a starting >point, but unfortunately even this (unmodified) example does not work >properly: The problem you report refects a SunOS bug. Apparently getc() is no longer re-entrant. If getc() is interrupted and the interrupt handler calls getc(), then, on return, the original getc() will yield bad values - it's internal buffer has become corrupted. I proved this to myself by modifying the example to contain only C code. The code ran correctly under SunOS 2.3, but not under SunOS 3.2 or 4.0.3. Avoid the problem by calling read() from the interrupt handler instead of getchar. (NOTE: getchar is just a macro that calls getc(stdin)). #include <signal.h> #include <stdio.h> #include "/goedel/quintus/install/q2.4.2/library/qpaction.h" int my_handler() { char c, c1; for (;;) { printf("\nWell? "); fflush(stdin); read(0, &c, 1); c1 = c; while (c1 != '\n') { read(0, &c1, 1); } fflush(stdin); switch (c) { case 'a': QP_action(QP_ABORT); /* abort */ case 'e': QP_action(QP_EXIT); /* exit */ case 'c': return; /* continue */ default: printf("a, c or e, please"); } } } Thanks for pointing out this discrepancy in our manual. We will update our documenatation accordingly. -Don Ferguson Manager, Technical Services