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.de
don@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