source: git/Singular/cntrlc.cc @ 5480da

spielwiese
Last change on this file since 5480da was 057e93c, checked in by Hans Schönemann <hannes@…>, 26 years ago
* Fri Feb 27 15:02:10 MET 1998 hannes new input scheme: many modifications to febase.h, febase.inc, febase.cc, scanner.l, grammar.y, iplib.cc, ipshell.{h,cc} git-svn-id: file:///usr/local/Singular/svn/trunk@1183 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: cntrlc.cc,v 1.17 1998-02-27 14:06:04 Singular Exp $ */
5/*
6* ABSTRACT - interupt handling
7*/
8
9/* includes */
10#include <stdio.h>
11#include <stddef.h>
12#include <stdlib.h>
13#include <signal.h>
14#include "mod2.h"
15#include "tok.h"
16#include "ipshell.h"
17#include "mmemory.h"
18#include "febase.h"
19#include "cntrlc.h"
20#include "version.h"
21#include "polys.h"
22#ifdef PAGE_TEST
23#include "page.h"
24#endif
25
26#ifdef unix
27#ifndef hpux
28#include <unistd.h>
29#include <sys/types.h>
30
31#ifdef TIME_WITH_SYS_TIME
32# include <time.h>
33# ifdef HAVE_SYS_TIME_H
34#   include <sys/time.h>
35# endif
36#else
37# ifdef HAVE_SYS_TIME_H
38#   include <sys/time.h>
39# else
40#   include <time.h>
41# endif
42#endif
43#ifdef HAVE_SYS_TIMES_H
44#include <sys/times.h>
45#endif
46
47#define INTERACTIVE 0
48#define STACK_TRACE 1
49#ifndef __OPTIMIZE__
50static void debug (int);
51static void debug_stop (char **);
52static void stack_trace (char **);
53static void stack_trace_sigchld (int);
54#endif
55#endif
56#endif
57
58/* data */
59jmp_buf si_start_jmpbuf;
60int siRandomStart;
61short si_restart=0;
62BOOLEAN siCntrlc = FALSE;
63
64/*0 implementation*/
65#ifndef MSDOS
66/* signals are not implemented in DJGCC */
67#ifndef macintosh
68/* signals are not right implemented in macintosh */
69typedef void (*si_hdl_typ)(int);
70void sigint_handler(int sig);
71#endif
72#endif
73
74#if defined(linux) && defined(__i386__)
75struct sigcontext_struct {
76        unsigned short gs, __gsh;
77        unsigned short fs, __fsh;
78        unsigned short es, __esh;
79        unsigned short ds, __dsh;
80        unsigned long edi;
81        unsigned long esi;
82        unsigned long ebp;
83        unsigned long esp;
84        unsigned long ebx;
85        unsigned long edx;
86        unsigned long ecx;
87        unsigned long eax;
88        unsigned long trapno;
89        unsigned long err;
90        unsigned long eip;
91        unsigned short cs, __csh;
92        unsigned long eflags;
93        unsigned long esp_at_signal;
94        unsigned short ss, __ssh;
95        unsigned long i387;
96        unsigned long oldmask;
97        unsigned long cr2;
98};
99typedef struct sigcontext_struct sigcontext;
100
101/*2
102* signal handler for run time errors, linux/i386 version
103*/
104void sigsegv_handler(int sig, sigcontext s)
105{
106  fprintf(stderr,"Singular : signal %d (v: %d/%d):\n",sig,SINGULAR_VERSION,SINGULAR_VERSION_ID);
107  if (sig!=SIGINT)
108  {
109    fprintf(stderr,"Segment fault/Bus error occurred at %x because of %x (r:%d)\n"
110                   "please inform the authors\n",
111                   (int)s.eip,(int)s.cr2,siRandomStart);
112  }
113#ifdef __OPTIMIZE__
114  if(si_restart<3)
115  {
116    si_restart++;
117    fprintf(stderr,"trying to restart...\n");
118    init_signals();
119    longjmp(si_start_jmpbuf,1);
120  }
121#endif
122#ifdef HAVE_FEREAD
123  fe_reset_input_mode();
124#endif
125#ifndef __OPTIMIZE__
126  if (sig!=SIGINT) debug(INTERACTIVE);
127#endif
128  exit(0);
129}
130
131#ifdef PAGE_TEST
132#ifdef PAGE_COUNT
133  static int page_segv_count=0;
134#endif
135void sig11_handler(int sig, sigcontext s)
136{
137#ifdef PAGE_COUNT
138  page_segv_count++;
139#endif
140  long base =s.cr2&(~4095);
141  int i=page_tab_ind-1;
142  for(;i>=0;i--)
143  {
144    if (page_tab[i]==base) { use_tab[i]='X'; break; }
145  }
146  Page_AllowAccess((void *)base, 4096);
147  signal(SIGSEGV,(si_hdl_typ)sig11_handler);
148}
149
150void sigalarm_handler(int sig, sigcontext s)
151{
152  int i=page_tab_ind-1;
153#ifdef PAGE_COUNT
154  write(2,use_tab,page_segv_count);
155  page_segv_count=0;
156#else
157  write(2,use_tab,page_tab_ind);
158#endif
159  write(2,"<\n",2);
160  for(;i>=0;i--)
161  {
162    Page_DenyAccess((void *)page_tab[i],4096);
163#ifndef PAGE_COUNT
164    use_tab[i]=' ';
165#endif
166  }
167  struct itimerval t,o;
168  memset(&t,0,sizeof(t));
169  t.it_value.tv_sec     =(unsigned)0;
170  t.it_value.tv_usec    =(unsigned)200;
171  o.it_value.tv_sec     =(unsigned)0;
172  o.it_value.tv_usec    =(unsigned)200;
173  setitimer(ITIMER_VIRTUAL,&t,&o);
174  signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
175}
176
177#endif
178
179/*2
180* init signal handlers, linux/i386 version
181*/
182void init_signals()
183{
184/*4 signal handler: linux*/
185#ifdef PAGE_TEST
186  signal(SIGSEGV,(si_hdl_typ)sig11_handler);
187  page_tab_ind=0;
188  struct itimerval t,o;
189  memset(&t,0,sizeof(t));
190  t.it_value.tv_sec     =(unsigned)0;
191  t.it_value.tv_usec    =(unsigned)100;
192  o.it_value.tv_sec     =(unsigned)0;
193  o.it_value.tv_usec    =(unsigned)200;
194  setitimer(ITIMER_VIRTUAL,&t,&o);
195  signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
196#else
197  if (SIG_ERR==signal(SIGSEGV,(si_hdl_typ)sigsegv_handler))
198  {
199    PrintS("cannot set signal handler for SEGV\n");
200  }
201#endif
202  if (SIG_ERR==signal(SIGFPE, (si_hdl_typ)sigsegv_handler))
203  {
204    PrintS("cannot set signal handler for FPE\n");
205  }
206  if (SIG_ERR==signal(SIGILL, (si_hdl_typ)sigsegv_handler))
207  {
208    PrintS("cannot set signal handler for ILL\n");
209  }
210  if (SIG_ERR==signal(SIGIOT, (si_hdl_typ)sigsegv_handler))
211  {
212    PrintS("cannot set signal handler for IOT\n");
213  }
214  if (SIG_ERR==signal(SIGINT ,sigint_handler))
215  {
216    PrintS("cannot set signal handler for INT\n");
217  }
218}
219
220#else
221#ifdef SPARC_SUNOS_4
222/*2
223* signal handler for run time errors, sparc sunos 4 version
224*/
225void sigsegv_handler(int sig, int code, struct sigcontext *scp, char *addr)
226{
227  fprintf(stderr,"Singular : signal %d, code %d (v: %d/%d):\n",
228    sig,code,SINGULAR_VERSION,SINGULAR_VERSION_ID);
229  if ((sig!=SIGINT)&&(sig!=SIGABRT))
230  {
231    fprintf(stderr,"Segment fault/Bus error occurred at %x (r:%d)\n"
232                   "please inform the authors\n",
233                   (int)addr,siRandomStart);
234  }
235#ifdef __OPTIMIZE__
236  if(si_restart<3)
237  {
238    si_restart++;
239    fprintf(stderr,"trying to restart...\n");
240    init_signals();
241    longjmp(si_start_jmpbuf,1);
242  }
243#endif
244#ifdef HAVE_FEREAD
245  fe_reset_input_mode(0,NULL);
246#endif
247#ifndef __OPTIMIZE__
248  if (sig!=SIGINT) debug(STACK_TRACE);
249#endif
250  exit(0);
251}
252
253/*2
254* init signal handlers, sparc sunos 4 version
255*/
256void init_signals()
257{
258/*4 signal handler:*/
259  signal(SIGSEGV,sigsegv_handler);
260  signal(SIGBUS, sigsegv_handler);
261  signal(SIGFPE, sigsegv_handler);
262  signal(SIGILL, sigsegv_handler);
263  signal(SIGIOT, sigsegv_handler);
264  signal(SIGINT ,sigint_handler);
265}
266#else
267
268/*2
269* signal handler for run time errors, general version
270*/
271#ifndef macintosh
272void sigsegv_handler(int sig)
273{
274  fprintf(stderr,"Singular : signal %d (v: %d/%d):\n",
275    sig,SINGULAR_VERSION,SINGULAR_VERSION_ID);
276  if (sig!=SIGINT)
277  {
278    fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
279                   "please inform the authors\n",
280                   siRandomStart);
281  }
282#ifdef __OPTIMIZE__
283  if(si_restart<3)
284  {
285    si_restart++;
286    fprintf(stderr,"trying to restart...\n");
287    init_signals();
288    longjmp(si_start_jmpbuf,1);
289  }
290#endif
291#ifdef HAVE_FEREAD
292#ifdef HAVE_ATEXIT
293  fe_reset_input_mode();
294#else
295  fe_reset_input_mode(0,NULL);
296#endif
297#endif
298#ifdef unix
299#ifndef hpux
300/* debug(..) does not work under HPUX (because ptrace does not work..) */
301#ifndef __OPTIMIZE__
302#ifndef MSDOS
303  if (sig!=SIGINT) debug(STACK_TRACE);
304#endif
305#endif
306#endif
307#endif
308  exit(0);
309}
310#endif
311
312/*2
313* init signal handlers, general version
314*/
315void init_signals()
316{
317#ifndef MSDOS
318/* signals are not implemented in DJGCC */
319#ifndef macintosh
320/* signals are temporaliy removed for macs. */
321/*4 signal handler:*/
322  signal(SIGSEGV,(void (*) (int))sigsegv_handler);
323#ifdef SIGBUS
324  signal(SIGBUS, sigsegv_handler);
325#endif
326#ifdef SIGFPE
327  signal(SIGFPE, sigsegv_handler);
328#endif
329#ifdef SIGILL
330  signal(SIGILL, sigsegv_handler);
331#endif
332#ifdef SIGIOT
333  signal(SIGIOT, sigsegv_handler);
334#endif
335#ifdef SIGXCPU
336  signal(SIGXCPU, (void (*)(int))SIG_IGN);
337#endif
338  signal(SIGINT ,sigint_handler);
339#endif
340#endif
341}
342#endif
343#endif
344
345#ifndef MSDOS
346#ifndef macintosh
347/*2
348* signal handler for SIGINT
349*/
350void sigint_handler(int sig)
351{
352  mflush();
353  loop
354  {
355    int cnt=0;
356    fprintf(stderr,"\n(last cmd:%d: `%s` in line\n>>%s<<)",
357      iiOp,Tok2Cmdname(iiOp),my_yylinebuf);
358    fputs("\nabort command(a), continue(c) or quit Singular(q) ?",stderr);fflush(stderr);
359    switch(fgetc(stdin))
360    {
361#if defined(MONOM_COUNT) || defined(DIV_COUNT)
362              case 'e':
363#ifdef MONOM_COUNT
364                extern void ResetMonomCount();
365                ResetMonomCount();
366#endif
367#ifdef DIV_COUNT
368                extern void ResetDivCount();
369                ResetDivCount();
370#endif
371                break;
372              case 'o':
373#ifdef MONOM_COUNT
374                extern void OutputMonomCount();
375                OutputMonomCount();
376#endif
377#ifdef DIV_COUNT
378                extern void OutputDivCount();
379                OutputDivCount();
380#endif
381                break;
382#endif // defined(MONOM_COUNT) || defined(DIV_COUNT)
383      case 'q':
384                m2_end(2);
385      case 'r':
386                longjmp(si_start_jmpbuf,1);
387      case 'a':
388                siCntrlc++;
389      case 'c':
390                fgetc(stdin);
391                signal(SIGINT ,(si_hdl_typ)sigint_handler);
392                return;
393                //siCntrlc ++;
394                //if (siCntrlc>2) signal(SIGINT,(si_hdl_typ) sigsegv_handler);
395                //else            signal(SIGINT,(si_hdl_typ) sigint_handler);
396    }
397    cnt++;
398    if(cnt>5) m2_end(2);
399  }
400}
401#endif
402#endif
403
404//#ifdef macintosh
405//#include <Types.h>
406//#include <Events.h>
407//#include <OSEvents.h>
408//#include <CursorCtl.h>
409//
410///*3
411//* macintosh only:
412//* side effect of ^C is to insert EOF at the end of the current
413//* input selection. We must drain input, reach this EOF, then clear it
414//*/
415//static void flush_intr(void)
416//{
417//  int c;
418//
419//  while ((c=getchar())!=EOF);
420//  clearerr(stdin);
421//}
422//
423///*3
424//* macintosh only:
425//* spin beach ball in MPW, allows MPW-tool to go to the background
426//* so you can use the finder and interrupts
427//*/
428//static void beachball(void)
429//{
430//  Show_Cursor(HIDDEN_CURSOR);
431//  SpinCursor(10);
432//}
433//#endif
434
435#ifndef MSDOS
436// /*2
437// * test for SIGINT, start an interpreter
438// */
439// void test_int_std(leftv v)
440// {
441// #ifndef macintosh
442// //#ifdef macintosh
443// //  beachball();
444// //#endif
445//   if (siCntrlc>1)
446//   {
447//     int saveecho = si_echo;
448//     siCntrlc = FALSE;
449//     signal(SIGINT ,sigint_handler);
450// //#ifdef macintosh
451// //    flush_intr();
452// //#endif
453//     //si_echo = 2;
454//     printf("\n//inside a computation, continue with `exit;`\n");
455//     iiPStart("STDIN","STDIN",NULL);
456//     si_echo = saveecho;
457//   }
458// #endif
459// }
460#endif
461
462#ifndef MSDOS
463//void test_int()
464//{
465//#ifndef macintosh
466//  if (siCntrlc!=0)
467//  {
468//    int saveecho = si_echo;
469//    siCntrlc = FALSE;
470//    signal(SIGINT ,sigint_handler);
471////#ifdef macintosh
472////    flush_intr();
473////#endif
474//    iiDebug();
475//    si_echo = saveecho;
476//  }
477//#endif
478//}
479#endif
480
481#ifdef unix
482#ifndef hpux
483#ifndef __OPTIMIZE__
484#ifndef MSDOS
485int si_stop_stack_trace_x;
486
487static void debug (int method)
488{
489  int pid;
490  char buf[16];
491  char *args[4] = { "gdb", "Singularg", NULL, NULL };
492
493  sprintf (buf, "%d", getpid ());
494
495  args[2] = buf;
496
497  pid = fork ();
498  if (pid == 0)
499  {
500    switch (method)
501    {
502      case INTERACTIVE:
503        fprintf (stderr, "debug_stop\n");
504        debug_stop (args);
505        break;
506      case STACK_TRACE:
507        fprintf (stderr, "stack_trace\n");
508        stack_trace (args);
509        break;
510    }
511  }
512  else if (pid == -1)
513  {
514    perror ("could not fork");
515    return;
516  }
517
518  si_stop_stack_trace_x = 1;
519  while (si_stop_stack_trace_x) ;
520}
521
522static void debug_stop ( char **args)
523{
524  execvp (args[0], args);
525  perror ("exec failed");
526  _exit (0);
527}
528
529static int stack_trace_done;
530
531static void stack_trace (char **args)
532{
533  int pid;
534  int in_fd[2];
535  int out_fd[2];
536  fd_set fdset;
537  fd_set readset;
538  struct timeval tv;
539  int sel, index, state;
540  char buffer[256];
541  char c;
542
543  stack_trace_done = 0;
544
545  signal (SIGCHLD, stack_trace_sigchld);
546
547  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
548  {
549    perror ("could open pipe");
550    _exit (0);
551  }
552
553  pid = fork ();
554  if (pid == 0)
555  {
556    close (0); dup2 (in_fd[0],0);   /* set the stdin to the in pipe */
557    close (1); dup2 (out_fd[1],1);  /* set the stdout to the out pipe */
558    close (2); dup2 (out_fd[1],2);  /* set the stderr to the out pipe */
559
560    execvp (args[0], args);      /* exec gdb */
561    perror ("exec failed");
562    _exit (0);
563  }
564  else if (pid == -1)
565  {
566    perror ("could not fork");
567    _exit (0);
568  }
569
570  FD_ZERO (&fdset);
571  FD_SET (out_fd[0], &fdset);
572
573  write (in_fd[1], "backtrace\n", 10);
574  write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
575  write (in_fd[1], "quit\n", 5);
576
577  index = 0;
578  state = 0;
579
580  loop
581  {
582    readset = fdset;
583    tv.tv_sec = 1;
584    tv.tv_usec = 0;
585
586#ifdef hpux
587    sel = select (FD_SETSIZE, (int *)readset.fds_bits, NULL, NULL, &tv);
588#else
589    sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
590#endif
591    if (sel == -1)
592      break;
593
594    if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
595    {
596      if (read (out_fd[0], &c, 1))
597      {
598        switch (state)
599        {
600          case 0:
601            if (c == '#')
602            {
603              state = 1;
604              index = 0;
605              buffer[index++] = c;
606            }
607            break;
608          case 1:
609            buffer[index++] = c;
610            if ((c == '\n') || (c == '\r'))
611            {
612              buffer[index] = 0;
613              fprintf (stderr, "%s", buffer);
614              state = 0;
615              index = 0;
616            }
617            break;
618          default:
619            break;
620        }
621      }
622    }
623    else if (stack_trace_done)
624      break;
625  }
626
627  close (in_fd[0]);
628  close (in_fd[1]);
629  close (out_fd[0]);
630  close (out_fd[1]);
631  _exit (0);
632}
633
634static void stack_trace_sigchld (int signum)
635{
636  stack_trace_done = 1;
637}
638
639#endif
640#endif
641#endif
642#endif
Note: See TracBrowser for help on using the repository browser.