source: git/Singular/cntrlc.cc @ d5bd816

spielwiese
Last change on this file since d5bd816 was d5bd816, checked in by Kai Krüger <krueger@…>, 19 years ago
replace call of signal() by meta-function set_signal() (easier for different platforms, added comments at pre-pross-defines git-svn-id: file:///usr/local/Singular/svn/trunk@7889 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.5 KB
RevLine 
[0e1846]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[d5bd816]4/* $Id: cntrlc.cc,v 1.44 2005-04-24 08:43:16 krueger Exp $ */
[0e1846]5/*
6* ABSTRACT - interupt handling
7*/
8
9/* includes */
[502ea2]10#ifdef DecAlpha_OSF1
11#define _XOPEN_SOURCE_EXTENDED
[d5bd816]12#endif /* MP3-Y2 0.022UF */
[0e1846]13#include <stdio.h>
14#include <stddef.h>
15#include <stdlib.h>
[502ea2]16#include <strings.h>
[0e1846]17#include <signal.h>
18#include "mod2.h"
[512a2b]19#include "omalloc.h"
[0e1846]20#include "tok.h"
21#include "ipshell.h"
22#include "febase.h"
23#include "cntrlc.h"
[51c163]24#include "polys.h"
[2272c33]25#include "feOpt.h"
[a3705ae]26#include "version.h"
[0e1846]27#ifdef PAGE_TEST
28#include "page.h"
[d5bd816]29#endif /* PAGE_TEST */
[0e1846]30
[dc0898]31
[d6681d]32/* undef, if you don't want GDB to come up on error */
[b39d4d]33
34#if !defined(__alpha)
35#define CALL_GDB
36#endif
[d6681d]37
38#if defined(__OPTIMIZE__) && defined(CALL_GDB)
39#undef CALL_GDB
40#endif
41
[0e1846]42#ifdef unix
[1e8e9c]43# ifndef hpux
44#  include <unistd.h>
45#  include <sys/types.h>
[40edb03]46
[1e8e9c]47#  ifdef TIME_WITH_SYS_TIME
[40edb03]48#   include <time.h>
[1e8e9c]49#   ifdef HAVE_SYS_TIME_H
50#     include <sys/time.h>
51#   endif
52#  else
53#   ifdef HAVE_SYS_TIME_H
54#     include <sys/time.h>
55#   else
56#     include <time.h>
57#   endif
58#  endif
59#  ifdef HAVE_SYS_TIMES_H
60#   include <sys/times.h>
61#  endif
[0e1846]62
[1e8e9c]63#  define INTERACTIVE 0
64#  define STACK_TRACE 1
65#  ifdef CALL_GDB
[577d19f]66static void debug (int);
[0e1846]67static void debug_stop (char **);
[1e8e9c]68#  endif
69#  ifndef __OPTIMIZE__
[0e1846]70static void stack_trace (char **);
71static void stack_trace_sigchld (int);
[1e8e9c]72#  endif
73# endif /* !hpux */
74#endif  /* unix */
[0e1846]75
[d5bd816]76/*---------------------------------------------------------------------*
77 * File scope Variables (Variables share by several functions in
78 *                       the same file )
79 *
80 *---------------------------------------------------------------------*/
[0e1846]81/* data */
[07dacd]82jmp_buf si_start_jmpbuf;
[0e1846]83int siRandomStart;
[07dacd]84short si_restart=0;
85BOOLEAN siCntrlc = FALSE;
[0e1846]86
[5812c69]87typedef void (*si_hdl_typ)(int);
88
[0e1846]89/*0 implementation*/
[d5bd816]90/*---------------------------------------------------------------------*
91 * Functions declarations
92 *
93 *---------------------------------------------------------------------*/
[0e1846]94#ifndef MSDOS
95/* signals are not implemented in DJGCC */
[1e8e9c]96# ifndef macintosh
[0e1846]97/* signals are not right implemented in macintosh */
98void sigint_handler(int sig);
[1e8e9c]99# endif /* !macintosh */
[d5bd816]100#endif /* MSDOS */
101
102extern sighandler_t set_signal ( int sig, sighandler_t signal_handler);
103
104/*---------------------------------------------------------------------*/
105/**
106 * @brief meta function for binding a signal to an handler
107
108 @param[in] sig             Signal number
109 @param[in] signal_handler  Pointer to signal handler
110
111 @return value of signal()
112**/
113/*---------------------------------------------------------------------*/
114sighandler_t set_signal (
115  int sig,
116  sighandler_t signal_handler
117  )
118{
119  sighandler_t retval;
120  if ((retval=signal (sig, (si_hdl_typ)signal_handler)) == SIG_ERR) {
121     fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
122  }
123  siginterrupt(sig, 1);
124  return retval;
125}                               /* set_signal */
126
[0e1846]127
[d5bd816]128/*---------------------------------------------------------------------*/
129/*-- linux and i386 ---*/
[97eb91]130#if defined(linux) && defined(__i386__)
[1e8e9c]131# if defined(HAVE_SIGCONTEXT) || defined(HAVE_ASM_SIGCONTEXT_H)
132#  include <asm/sigcontext.h>
133# else
[0e1846]134struct sigcontext_struct {
135        unsigned short gs, __gsh;
136        unsigned short fs, __fsh;
137        unsigned short es, __esh;
138        unsigned short ds, __dsh;
139        unsigned long edi;
140        unsigned long esi;
141        unsigned long ebp;
142        unsigned long esp;
143        unsigned long ebx;
144        unsigned long edx;
145        unsigned long ecx;
146        unsigned long eax;
147        unsigned long trapno;
148        unsigned long err;
149        unsigned long eip;
150        unsigned short cs, __csh;
151        unsigned long eflags;
152        unsigned long esp_at_signal;
153        unsigned short ss, __ssh;
154        unsigned long i387;
155        unsigned long oldmask;
156        unsigned long cr2;
157};
[1e8e9c]158# endif
[0e1846]159typedef struct sigcontext_struct sigcontext;
160
[d5bd816]161
162/*2---------------------------------------------------------------------*/
163/**
164 * @brief signal handler for run time errors, linux/i386 version
165
166 @param[in] sig     
167 @param[in] s   
168**/
169/*---------------------------------------------------------------------*/
[0e1846]170void sigsegv_handler(int sig, sigcontext s)
171{
[50cbdc]172  fprintf(stderr,"Singular : signal %d (v: %d/%u):\n",sig,SINGULAR_VERSION,feVersionId);
[0e1846]173  if (sig!=SIGINT)
174  {
175    fprintf(stderr,"Segment fault/Bus error occurred at %x because of %x (r:%d)\n"
176                   "please inform the authors\n",
177                   (int)s.eip,(int)s.cr2,siRandomStart);
178  }
[1e8e9c]179# ifdef __OPTIMIZE__
[07dacd]180  if(si_restart<3)
181  {
182    si_restart++;
183    fprintf(stderr,"trying to restart...\n");
184    init_signals();
185    longjmp(si_start_jmpbuf,1);
186  }
[d5bd816]187# endif /* __OPTIMIZE__ */
[1e8e9c]188# ifdef CALL_GDB
[0e1846]189  if (sig!=SIGINT) debug(INTERACTIVE);
[d5bd816]190# endif /* CALL_GDB */
[0e1846]191  exit(0);
192}
193
[d5bd816]194/*---------------------------------------------------------------------*/
195/**
196 * @brief additional default signal handler
197
[6b02bf2]198  // some newer Linux version cannot have SIG_IGN for SIGCHLD,
199  // so use this nice routine here:
200  //  SuSe 9.x reports -1 always
201  //  Redhat 9.x/FC x reports sometimes -1
202  // see also: hpux_system
[d5bd816]203
204 @param[in] sig     
205**/
206/*---------------------------------------------------------------------*/
207void sig_ign_hdl(int sig)
208{
[6b02bf2]209}
210
[1e8e9c]211# ifdef PAGE_TEST
212#  ifndef PAGE_INTERRUPT_TIME
213#   define PAGE_INTERRUPT_TIME 1
214#  endif
[d5bd816]215
216/*---------------------------------------------------------------------*/
217/**
218 * @brief signal handler for segmentation faults
219
220 @param[in] sig     
221 @param[in] s   
222**/
223/*---------------------------------------------------------------------*/
[0e1846]224void sig11_handler(int sig, sigcontext s)
225{
[93266c5]226  unsigned long base =(unsigned long)(s.cr2&(~4095));
227  int i;
228  i=mmPage_tab_ind-1;
229  while (mmPage_tab[i]!=base) i--;
230  mmUse_tab[i]='1';
231  mmPage_tab_acc++;
232  mmPage_AllowAccess((void *)base);
[d5bd816]233  set_signal(SIGSEGV,(si_hdl_typ)sig11_handler);
[0e1846]234}
235
[d5bd816]236/*---------------------------------------------------------------------*/
237/**
238 * @brief signal handler for alarm signals
239
240 @param[in] sig     
241 @param[in] s   
242**/
243/*---------------------------------------------------------------------*/
[0e1846]244void sigalarm_handler(int sig, sigcontext s)
245{
[93266c5]246  int i=mmPage_tab_ind-1;
247  mmWriteStat();
[0e1846]248  for(;i>=0;i--)
249  {
[93266c5]250    mmPage_DenyAccess((void *)mmPage_tab[i]);
[0e1846]251  }
252  struct itimerval t,o;
253  memset(&t,0,sizeof(t));
254  t.it_value.tv_sec     =(unsigned)0;
[fff984]255  t.it_value.tv_usec    =(unsigned) PAGE_INTERRUPT_TIME;
[0e1846]256  o.it_value.tv_sec     =(unsigned)0;
[fff984]257  o.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
[0e1846]258  setitimer(ITIMER_VIRTUAL,&t,&o);
[d5bd816]259  set_signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
[0e1846]260}
[1e8e9c]261# endif /* PAGE_TEST */
[0e1846]262
263/*2
[97eb91]264* init signal handlers, linux/i386 version
[0e1846]265*/
266void init_signals()
267{
268/*4 signal handler: linux*/
[1e8e9c]269# ifdef PAGE_TEST
[d5bd816]270  set_signal(SIGSEGV,(si_hdl_typ)sig11_handler);
[0e1846]271  struct itimerval t,o;
272  memset(&t,0,sizeof(t));
273  t.it_value.tv_sec     =(unsigned)0;
[fff984]274  t.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
[0e1846]275  o.it_value.tv_sec     =(unsigned)0;
[fff984]276  o.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
[0e1846]277  setitimer(ITIMER_VIRTUAL,&t,&o);
[d5bd816]278  set_signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
[1e8e9c]279# else /* PAGE_TEST */
[d5bd816]280  if (SIG_ERR==set_signal(SIGSEGV,(si_hdl_typ)sigsegv_handler))
[057e93c]281  {
282    PrintS("cannot set signal handler for SEGV\n");
283  }
[1e8e9c]284# endif /* PAGE_TEST */
[d5bd816]285  if (SIG_ERR==set_signal(SIGFPE, (si_hdl_typ)sigsegv_handler))
[057e93c]286  {
287    PrintS("cannot set signal handler for FPE\n");
288  }
[d5bd816]289  if (SIG_ERR==set_signal(SIGILL, (si_hdl_typ)sigsegv_handler))
[057e93c]290  {
291    PrintS("cannot set signal handler for ILL\n");
292  }
[d5bd816]293  if (SIG_ERR==set_signal(SIGIOT, (si_hdl_typ)sigsegv_handler))
[057e93c]294  {
295    PrintS("cannot set signal handler for IOT\n");
296  }
[d5bd816]297  if (SIG_ERR==set_signal(SIGINT ,(si_hdl_typ)sigint_handler))
[057e93c]298  {
299    PrintS("cannot set signal handler for INT\n");
300  }
[d5bd816]301  //set_signal(SIGCHLD, (void (*)(int))SIG_IGN);
302  set_signal(SIGCHLD, (si_hdl_typ)sig_ign_hdl);
[0e1846]303}
304
[1e8e9c]305#else /* linux && __i386__ */
[d5bd816]306/*---------------------------------------------------------------------*/
307/*-- SPARC_SUNOS_4 ---*/
[1e8e9c]308# ifdef SPARC_SUNOS_4
[0e1846]309/*2
310* signal handler for run time errors, sparc sunos 4 version
311*/
312void sigsegv_handler(int sig, int code, struct sigcontext *scp, char *addr)
313{
[50cbdc]314  fprintf(stderr,"Singular : signal %d, code %d (v: %d/%u):\n",
[c06a32]315    sig,code,SINGULAR_VERSION,feVersionId);
[0e1846]316  if ((sig!=SIGINT)&&(sig!=SIGABRT))
317  {
318    fprintf(stderr,"Segment fault/Bus error occurred at %x (r:%d)\n"
319                   "please inform the authors\n",
320                   (int)addr,siRandomStart);
321  }
[1e8e9c]322#  ifdef __OPTIMIZE__
[97eb91]323  if(si_restart<3)
324  {
325    si_restart++;
326    fprintf(stderr,"trying to restart...\n");
327    init_signals();
328    longjmp(si_start_jmpbuf,1);
329  }
[1e8e9c]330#  endif /* __OPTIMIZE__ */
331#  ifdef CALL_GDB
[0e1846]332  if (sig!=SIGINT) debug(STACK_TRACE);
[1e8e9c]333#  endif /* CALL_GDB */
[0e1846]334  exit(0);
335}
336
337/*2
338* init signal handlers, sparc sunos 4 version
339*/
340void init_signals()
341{
342/*4 signal handler:*/
[d5bd816]343  set_signal(SIGSEGV,sigsegv_handler);
344  set_signal(SIGBUS, sigsegv_handler);
345  set_signal(SIGFPE, sigsegv_handler);
346  set_signal(SIGILL, sigsegv_handler);
347  set_signal(SIGIOT, sigsegv_handler);
348  set_signal(SIGINT ,sigint_handler);
349  set_signal(SIGCHLD, (void (*)(int))SIG_IGN);
[0e1846]350}
[1e8e9c]351# else /* SPARC_SUNOS_4 */
[0e1846]352
[d5bd816]353/*---------------------------------------------------------------------*/
[0e1846]354/*2
355* signal handler for run time errors, general version
356*/
[d5bd816]357#  ifndef macintosh
[0e1846]358void sigsegv_handler(int sig)
359{
[50cbdc]360  fprintf(stderr,"Singular : signal %d (v: %d/%u):\n",
[c06a32]361    sig,SINGULAR_VERSION,feVersionId);
[0e1846]362  if (sig!=SIGINT)
363  {
364    fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
365                   "please inform the authors\n",
366                   siRandomStart);
367  }
[d5bd816]368#   ifdef __OPTIMIZE__
[97eb91]369  if(si_restart<3)
370  {
371    si_restart++;
372    fprintf(stderr,"trying to restart...\n");
373    init_signals();
374    longjmp(si_start_jmpbuf,1);
375  }
[d5bd816]376#   endif /* __OPTIMIZE__ */
377#   ifdef unix
378#    ifndef hpux
[97eb91]379/* debug(..) does not work under HPUX (because ptrace does not work..) */
[d5bd816]380#     ifdef CALL_GDB
381#      ifndef MSDOS
[0e1846]382  if (sig!=SIGINT) debug(STACK_TRACE);
[d5bd816]383#      endif /* MSDOS */
384#     endif /* CALL_GDB */
385#    endif /* !hpux */
386#   endif /* unix */
[0e1846]387  exit(0);
388}
[d5bd816]389#  endif /* !macintosh */
[0e1846]390
391/*2
392* init signal handlers, general version
393*/
394void init_signals()
395{
[d5bd816]396#  ifndef MSDOS
[0e1846]397/* signals are not implemented in DJGCC */
[d5bd816]398#   ifndef macintosh
[0e1846]399/* signals are temporaliy removed for macs. */
400/*4 signal handler:*/
[d5bd816]401  set_signal(SIGSEGV,(void (*) (int))sigsegv_handler);
402#    ifdef SIGBUS
403  set_signal(SIGBUS, sigsegv_handler);
404#    endif /* SIGBUS */
405#    ifdef SIGFPE
406  set_signal(SIGFPE, sigsegv_handler);
407#    endif /* SIGFPE */
408#    ifdef SIGILL
409  set_signal(SIGILL, sigsegv_handler);
410#    endif /* SIGILL */
411#    ifdef SIGIOT
412  set_signal(SIGIOT, sigsegv_handler);
413#    endif /* SIGIOT */
414#    ifdef SIGXCPU
415  set_signal(SIGXCPU, (void (*)(int))SIG_IGN);
416#    endif /* SIGIOT */
417  set_signal(SIGINT ,sigint_handler);
418  set_signal(SIGCHLD, (void (*)(int))SIG_IGN);
419#   endif /* !macintosh */
420#  endif /* !MSDOS */
[0e1846]421}
[d5bd816]422# endif /* SPARC_SUNOS_4 */
423#endif /* linux && __i386__ */
424
[0e1846]425
426#ifndef MSDOS
[d5bd816]427# ifndef macintosh
[0e1846]428/*2
429* signal handler for SIGINT
430*/
431void sigint_handler(int sig)
432{
[66415e1]433  mflush();
[d5bd816]434#  ifdef HAVE_FEREAD
[0fa9018]435  if (fe_is_raw_tty) fe_temp_reset();
[d5bd816]436#  endif /* HAVE_FEREAD */
[66415e1]437  loop
438  {
[e8a30d]439    int cnt=0;
[2272c33]440    int c;
441    fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
442      Tok2Cmdname(iiOp),my_yylinebuf);
443    if (feGetOptValue(FE_OPT_EMACS) == NULL)
444    {
445      fputs("abort command(a), continue(c) or quit Singular(q) ?",stderr);fflush(stderr);
446      c = fgetc(stdin);
447    }
448    else
449    {
450      c = 'a';
451    }
[502ea2]452   
[2272c33]453    switch(c)
[66415e1]454    {
[d5bd816]455#  if defined(MONOM_COUNT) || defined(DIV_COUNT)
[09e228]456              case 'e':
[d5bd816]457#   ifdef MONOM_COUNT
[09e228]458                extern void ResetMonomCount();
459                ResetMonomCount();
[d5bd816]460#   endif /* MONOM_COUNT */
461#   ifdef DIV_COUNT
[09e228]462                extern void ResetDivCount();
463                ResetDivCount();
[d5bd816]464#   endif /* DIV_COUNT */
[09e228]465                break;
466              case 'o':
[d5bd816]467#   ifdef MONOM_COUNT
[09e228]468                extern void OutputMonomCount();
469                OutputMonomCount();
[d5bd816]470#   endif /* COUNT */
471#   ifdef DIV_COUNT
[09e228]472                extern void OutputDivCount();
473                OutputDivCount();
[d5bd816]474#   endif /* DIV_COUNT */
[09e228]475                break;
[d5bd816]476#  endif /* defined(MONOM_COUNT) || defined(DIV_COUNT) */
[66415e1]477      case 'q':
478                m2_end(2);
[07dacd]479      case 'r':
480                longjmp(si_start_jmpbuf,1);
[09e228]481      case 'b':
482                VoiceBackTrack();
483                break;
[e8a30d]484      case 'a':
485                siCntrlc++;
[66415e1]486      case 'c':
[2272c33]487                if (feGetOptValue(FE_OPT_EMACS) == NULL) fgetc(stdin);
[d5bd816]488                set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
[07dacd]489                return;
[50b2df]490                //siCntrlc ++;
[d5bd816]491                //if (siCntrlc>2) set_signal(SIGINT,(si_hdl_typ) sigsegv_handler);
492                //else            set_signal(SIGINT,(si_hdl_typ) sigint_handler);
[66415e1]493    }
[e8a30d]494    cnt++;
495    if(cnt>5) m2_end(2);
[66415e1]496  }
[0e1846]497}
[d5bd816]498# endif /* !macintosh */
499#endif /* !MSDOS */
[0e1846]500
501//#ifdef macintosh
502//#include <Types.h>
503//#include <Events.h>
504//#include <OSEvents.h>
505//#include <CursorCtl.h>
506//
507///*3
508//* macintosh only:
509//* side effect of ^C is to insert EOF at the end of the current
510//* input selection. We must drain input, reach this EOF, then clear it
511//*/
512//static void flush_intr(void)
513//{
514//  int c;
515//
516//  while ((c=getchar())!=EOF);
517//  clearerr(stdin);
518//}
519//
520///*3
521//* macintosh only:
522//* spin beach ball in MPW, allows MPW-tool to go to the background
523//* so you can use the finder and interrupts
524//*/
525//static void beachball(void)
526//{
527//  Show_Cursor(HIDDEN_CURSOR);
528//  SpinCursor(10);
529//}
530//#endif
531
532#ifndef MSDOS
[e8a30d]533//void test_int()
534//{
535//#ifndef macintosh
536//  if (siCntrlc!=0)
537//  {
538//    int saveecho = si_echo;
539//    siCntrlc = FALSE;
[d5bd816]540//    set_signal(SIGINT ,sigint_handler);
[e8a30d]541////#ifdef macintosh
542////    flush_intr();
543////#endif
544//    iiDebug();
545//    si_echo = saveecho;
546//  }
[0e1846]547//#endif
[e8a30d]548//}
[d5bd816]549#endif /* !MSDOS */
[0e1846]550
551#ifdef unix
[d5bd816]552# ifndef hpux
553#  ifndef __OPTIMIZE__
554#   ifndef MSDOS
[0e1846]555int si_stop_stack_trace_x;
[d5bd816]556#    ifdef CALL_GDB
[577d19f]557static void debug (int method)
[0e1846]558{
[8a6c6a]559  if (feOptValue(FE_OPT_NO_TTY))
560  {
561    dReportError("Caught Signal 11");
562    return;
563  }
[0e1846]564  int pid;
565  char buf[16];
[cc0296]566  char *args[4] = { "gdb", "Singularg", NULL, NULL };
[577d19f]567
[d5bd816]568#     ifdef HAVE_FEREAD
[0fa9018]569  if (fe_is_raw_tty) fe_temp_reset();
[d5bd816]570#     endif /* HAVE_FEREAD */
[0fa9018]571
[0e1846]572  sprintf (buf, "%d", getpid ());
573
574  args[2] = buf;
575
576  pid = fork ();
577  if (pid == 0)
578  {
579    switch (method)
580    {
581      case INTERACTIVE:
582        fprintf (stderr, "debug_stop\n");
583        debug_stop (args);
584        break;
585      case STACK_TRACE:
586        fprintf (stderr, "stack_trace\n");
587        stack_trace (args);
588        break;
[5687c9]589      default:
590        // should not be reached:
591        exit(1);
[0e1846]592    }
593  }
594  else if (pid == -1)
595  {
596    perror ("could not fork");
597    return;
598  }
599
600  si_stop_stack_trace_x = 1;
601  while (si_stop_stack_trace_x) ;
602}
603
604static void debug_stop ( char **args)
605{
606  execvp (args[0], args);
607  perror ("exec failed");
608  _exit (0);
609}
[d5bd816]610#    endif /* CALL_GDB */
[0e1846]611
612static int stack_trace_done;
613
614static void stack_trace (char **args)
615{
616  int pid;
617  int in_fd[2];
618  int out_fd[2];
619  fd_set fdset;
620  fd_set readset;
621  struct timeval tv;
622  int sel, index, state;
623  char buffer[256];
624  char c;
625
626  stack_trace_done = 0;
627
628  signal (SIGCHLD, stack_trace_sigchld);
629
630  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
631  {
632    perror ("could open pipe");
[0fa9018]633    m2_end(999);
[0e1846]634  }
635
636  pid = fork ();
637  if (pid == 0)
638  {
639    close (0); dup2 (in_fd[0],0);   /* set the stdin to the in pipe */
640    close (1); dup2 (out_fd[1],1);  /* set the stdout to the out pipe */
641    close (2); dup2 (out_fd[1],2);  /* set the stderr to the out pipe */
642
643    execvp (args[0], args);      /* exec gdb */
644    perror ("exec failed");
[0fa9018]645    m2_end(999);
[0e1846]646  }
647  else if (pid == -1)
648  {
649    perror ("could not fork");
[0fa9018]650    m2_end(999);
[0e1846]651  }
652
653  FD_ZERO (&fdset);
654  FD_SET (out_fd[0], &fdset);
655
656  write (in_fd[1], "backtrace\n", 10);
657  write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
658  write (in_fd[1], "quit\n", 5);
659
660  index = 0;
661  state = 0;
662
663  loop
664  {
665    readset = fdset;
666    tv.tv_sec = 1;
667    tv.tv_usec = 0;
668
[d5bd816]669#    ifdef hpux
[0e1846]670    sel = select (FD_SETSIZE, (int *)readset.fds_bits, NULL, NULL, &tv);
[d5bd816]671#    else /* hpux */
[0e1846]672    sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
[d5bd816]673#    endif /* hpux */
[0e1846]674    if (sel == -1)
675      break;
676
677    if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
678    {
679      if (read (out_fd[0], &c, 1))
680      {
681        switch (state)
682        {
683          case 0:
684            if (c == '#')
685            {
686              state = 1;
687              index = 0;
688              buffer[index++] = c;
689            }
690            break;
691          case 1:
692            buffer[index++] = c;
693            if ((c == '\n') || (c == '\r'))
694            {
695              buffer[index] = 0;
696              fprintf (stderr, "%s", buffer);
697              state = 0;
698              index = 0;
699            }
700            break;
701          default:
702            break;
703        }
704      }
705    }
706    else if (stack_trace_done)
707      break;
708  }
709
710  close (in_fd[0]);
711  close (in_fd[1]);
712  close (out_fd[0]);
713  close (out_fd[1]);
[0fa9018]714  m2_end(0);
[0e1846]715}
716
717static void stack_trace_sigchld (int signum)
718{
719  stack_trace_done = 1;
720}
721
[d5bd816]722#   endif /* !MSDOS */
723#  endif /* !__OPTIMIZE__ */
724# endif /* !hpux */
725#endif /* unix */
[dc0898]726
727/* Under HPUX 9, system(...) returns -1 if SIGCHLD does not equal
728   SIG_DFL. However, if it stays at SIG_DFL we get zombie processes
[502ea2]729   for terminated childs generated by fork. Therefors some special treatment
[dc0898]730   is necessary */
731#ifdef HPUX_9
[d5bd816]732# undef system
[dc0898]733extern "C" {
734  int  hpux9_system(const char* call)
735  {
736    int ret;
[d5bd816]737    set_signal(SIGCHLD, (void (*)(int))SIG_DFL);
[dc0898]738    ret = system(call);
[d5bd816]739    set_signal(SIGCHLD, (void (*)(int))SIG_IGN);
[dc0898]740    return ret;
741  }
742}
743#endif /* HPUX_9 */
Note: See TracBrowser for help on using the repository browser.