source: git/Singular/cntrlc.cc @ 206aed

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