OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [libiberty/] [strsignal.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Extended support for using signal values.
2
   Written by Fred Fish.  fnf@cygnus.com
3
   This file is in the public domain.  */
4
 
5
#include "ansidecl.h"
6
#include "libiberty.h"
7
 
8
#include "config.h"
9
 
10
/* We need to declare sys_siglist, because even if the system provides
11
   it we can't assume that it is declared in <signal.h> (for example,
12
   SunOS provides sys_siglist, but it does not declare it in any
13
   header file).  fHowever, we can't declare sys_siglist portably,
14
   because on some systems it is declared with const and on some
15
   systems it is declared without const.  If we were using autoconf,
16
   we could work out the right declaration.  Until, then we just
17
   ignore any declaration in the system header files, and always
18
   declare it ourselves.  With luck, this will always work.  */
19
#define sys_siglist no_such_symbol
20
#define sys_nsig sys_nsig__no_such_symbol
21
 
22
#include <stdio.h>
23
#include <signal.h>
24
 
25
/*  Routines imported from standard C runtime libraries. */
26
 
27
#ifdef HAVE_STDLIB_H
28
#include <stdlib.h>
29
#else
30
extern PTR malloc ();
31
#endif
32
 
33
#ifdef HAVE_STRING_H
34
#include <string.h>
35
#else
36
extern PTR memset ();
37
#endif
38
 
39
/* Undefine the macro we used to hide the definition of sys_siglist
40
   found in the system header files.  */
41
#undef sys_siglist
42
#undef sys_nsig
43
 
44
#ifndef NULL
45
#  ifdef __STDC__
46
#    define NULL (void *) 0
47
#  else
48
#    define NULL 0
49
#  endif
50
#endif
51
 
52
#ifndef MAX
53
#  define MAX(a,b) ((a) > (b) ? (a) : (b))
54
#endif
55
 
56
static void init_signal_tables PARAMS ((void));
57
 
58
/* Translation table for signal values.
59
 
60
   Note that this table is generally only accessed when it is used at runtime
61
   to initialize signal name and message tables that are indexed by signal
62
   value.
63
 
64
   Not all of these signals will exist on all systems.  This table is the only
65
   thing that should have to be updated as new signal numbers are introduced.
66
   It's sort of ugly, but at least its portable. */
67
 
68
struct signal_info
69
{
70
  int value;            /* The numeric value from <signal.h> */
71
  const char *name;     /* The equivalent symbolic value */
72
#ifndef HAVE_SYS_SIGLIST
73
  const char *msg;      /* Short message about this value */
74
#endif
75
};
76
 
77
#ifndef HAVE_SYS_SIGLIST
78
#   define ENTRY(value, name, msg)      {value, name, msg}
79
#else
80
#   define ENTRY(value, name, msg)      {value, name}
81
#endif
82
 
83
static const struct signal_info signal_table[] =
84
{
85
#if defined (SIGHUP)
86
  ENTRY(SIGHUP, "SIGHUP", "Hangup"),
87
#endif
88
#if defined (SIGINT)
89
  ENTRY(SIGINT, "SIGINT", "Interrupt"),
90
#endif
91
#if defined (SIGQUIT)
92
  ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
93
#endif
94
#if defined (SIGILL)
95
  ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
96
#endif
97
#if defined (SIGTRAP)
98
  ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
99
#endif
100
/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
101
   overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
102
#if defined (SIGIOT)
103
  ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
104
#endif
105
#if defined (SIGABRT)
106
  ENTRY(SIGABRT, "SIGABRT", "Aborted"),
107
#endif
108
#if defined (SIGEMT)
109
  ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
110
#endif
111
#if defined (SIGFPE)
112
  ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
113
#endif
114
#if defined (SIGKILL)
115
  ENTRY(SIGKILL, "SIGKILL", "Killed"),
116
#endif
117
#if defined (SIGBUS)
118
  ENTRY(SIGBUS, "SIGBUS", "Bus error"),
119
#endif
120
#if defined (SIGSEGV)
121
  ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
122
#endif
123
#if defined (SIGSYS)
124
  ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
125
#endif
126
#if defined (SIGPIPE)
127
  ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
128
#endif
129
#if defined (SIGALRM)
130
  ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
131
#endif
132
#if defined (SIGTERM)
133
  ENTRY(SIGTERM, "SIGTERM", "Terminated"),
134
#endif
135
#if defined (SIGUSR1)
136
  ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
137
#endif
138
#if defined (SIGUSR2)
139
  ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
140
#endif
141
/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
142
   overrides SIGCLD.  SIGCHLD is in POXIX.1 */
143
#if defined (SIGCLD)
144
  ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
145
#endif
146
#if defined (SIGCHLD)
147
  ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
148
#endif
149
#if defined (SIGPWR)
150
  ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
151
#endif
152
#if defined (SIGWINCH)
153
  ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
154
#endif
155
#if defined (SIGURG)
156
  ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
157
#endif
158
#if defined (SIGIO)
159
  /* "I/O pending" has also been suggested, but is misleading since the
160
     signal only happens when the process has asked for it, not everytime
161
     I/O is pending. */
162
  ENTRY(SIGIO, "SIGIO", "I/O possible"),
163
#endif
164
#if defined (SIGPOLL)
165
  ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
166
#endif
167
#if defined (SIGSTOP)
168
  ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
169
#endif
170
#if defined (SIGTSTP)
171
  ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
172
#endif
173
#if defined (SIGCONT)
174
  ENTRY(SIGCONT, "SIGCONT", "Continued"),
175
#endif
176
#if defined (SIGTTIN)
177
  ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
178
#endif
179
#if defined (SIGTTOU)
180
  ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
181
#endif
182
#if defined (SIGVTALRM)
183
  ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
184
#endif
185
#if defined (SIGPROF)
186
  ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
187
#endif
188
#if defined (SIGXCPU)
189
  ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
190
#endif
191
#if defined (SIGXFSZ)
192
  ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
193
#endif
194
#if defined (SIGWIND)
195
  ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
196
#endif
197
#if defined (SIGPHONE)
198
  ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
199
#endif
200
#if defined (SIGLOST)
201
  ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
202
#endif
203
#if defined (SIGWAITING)
204
  ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
205
#endif
206
#if defined (SIGLWP)
207
  ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
208
#endif
209
#if defined (SIGDANGER)
210
  ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
211
#endif
212
#if defined (SIGGRANT)
213
  ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
214
#endif
215
#if defined (SIGRETRACT)
216
  ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
217
#endif
218
#if defined (SIGMSG)
219
  ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
220
#endif
221
#if defined (SIGSOUND)
222
  ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
223
#endif
224
#if defined (SIGSAK)
225
  ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
226
#endif
227
  ENTRY(0, NULL, NULL)
228
};
229
 
230
/* Translation table allocated and initialized at runtime.  Indexed by the
231
   signal value to find the equivalent symbolic value. */
232
 
233
static const char **signal_names;
234
static int num_signal_names = 0;
235
 
236
/* Translation table allocated and initialized at runtime, if it does not
237
   already exist in the host environment.  Indexed by the signal value to find
238
   the descriptive string.
239
 
240
   We don't export it for use in other modules because even though it has the
241
   same name, it differs from other implementations in that it is dynamically
242
   initialized rather than statically initialized. */
243
 
244
#ifndef HAVE_SYS_SIGLIST
245
 
246
static int sys_nsig;
247
static const char **sys_siglist;
248
 
249
#else
250
 
251
#ifdef NSIG
252
static int sys_nsig = NSIG;
253
#else
254
#ifdef _NSIG
255
static int sys_nsig = _NSIG;
256
#endif
257
#endif
258
extern const char * const sys_siglist[];
259
 
260
#endif
261
 
262
 
263
/*
264
 
265
NAME
266
 
267
        init_signal_tables -- initialize the name and message tables
268
 
269
SYNOPSIS
270
 
271
        static void init_signal_tables ();
272
 
273
DESCRIPTION
274
 
275
        Using the signal_table, which is initialized at compile time, generate
276
        the signal_names and the sys_siglist (if needed) tables, which are
277
        indexed at runtime by a specific signal value.
278
 
279
BUGS
280
 
281
        The initialization of the tables may fail under low memory conditions,
282
        in which case we don't do anything particularly useful, but we don't
283
        bomb either.  Who knows, it might succeed at a later point if we free
284
        some memory in the meantime.  In any case, the other routines know
285
        how to deal with lack of a table after trying to initialize it.  This
286
        may or may not be considered to be a bug, that we don't specifically
287
        warn about this particular failure mode.
288
 
289
*/
290
 
291
static void
292
init_signal_tables ()
293
{
294
  const struct signal_info *eip;
295
  int nbytes;
296
 
297
  /* If we haven't already scanned the signal_table once to find the maximum
298
     signal value, then go find it now. */
299
 
300
  if (num_signal_names == 0)
301
    {
302
      for (eip = signal_table; eip -> name != NULL; eip++)
303
        {
304
          if (eip -> value >= num_signal_names)
305
            {
306
              num_signal_names = eip -> value + 1;
307
            }
308
        }
309
    }
310
 
311
  /* Now attempt to allocate the signal_names table, zero it out, and then
312
     initialize it from the statically initialized signal_table. */
313
 
314
  if (signal_names == NULL)
315
    {
316
      nbytes = num_signal_names * sizeof (char *);
317
      if ((signal_names = (const char **) malloc (nbytes)) != NULL)
318
        {
319
          memset (signal_names, 0, nbytes);
320
          for (eip = signal_table; eip -> name != NULL; eip++)
321
            {
322
              signal_names[eip -> value] = eip -> name;
323
            }
324
        }
325
    }
326
 
327
#ifndef HAVE_SYS_SIGLIST
328
 
329
  /* Now attempt to allocate the sys_siglist table, zero it out, and then
330
     initialize it from the statically initialized signal_table. */
331
 
332
  if (sys_siglist == NULL)
333
    {
334
      nbytes = num_signal_names * sizeof (char *);
335
      if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
336
        {
337
          memset (sys_siglist, 0, nbytes);
338
          sys_nsig = num_signal_names;
339
          for (eip = signal_table; eip -> name != NULL; eip++)
340
            {
341
              sys_siglist[eip -> value] = eip -> msg;
342
            }
343
        }
344
    }
345
 
346
#endif
347
 
348
}
349
 
350
 
351
/*
352
 
353
NAME
354
 
355
        signo_max -- return the max signo value
356
 
357
SYNOPSIS
358
 
359
        int signo_max ();
360
 
361
DESCRIPTION
362
 
363
        Returns the maximum signo value for which a corresponding symbolic
364
        name or message is available.  Note that in the case where
365
        we use the sys_siglist supplied by the system, it is possible for
366
        there to be more symbolic names than messages, or vice versa.
367
        In fact, the manual page for psignal(3b) explicitly warns that one
368
        should check the size of the table (NSIG) before indexing it,
369
        since new signal codes may be added to the system before they are
370
        added to the table.  Thus NSIG might be smaller than value
371
        implied by the largest signo value defined in <signal.h>.
372
 
373
        We return the maximum value that can be used to obtain a meaningful
374
        symbolic name or message.
375
 
376
*/
377
 
378
int
379
signo_max ()
380
{
381
  int maxsize;
382
 
383
  if (signal_names == NULL)
384
    {
385
      init_signal_tables ();
386
    }
387
  maxsize = MAX (sys_nsig, num_signal_names);
388
  return (maxsize - 1);
389
}
390
 
391
 
392
/*
393
 
394
NAME
395
 
396
        strsignal -- map a signal number to a signal message string
397
 
398
SYNOPSIS
399
 
400
        const char *strsignal (int signo)
401
 
402
DESCRIPTION
403
 
404
        Maps an signal number to an signal message string, the contents of
405
        which are implementation defined.  On systems which have the external
406
        variable sys_siglist, these strings will be the same as the ones used
407
        by psignal().
408
 
409
        If the supplied signal number is within the valid range of indices
410
        for the sys_siglist, but no message is available for the particular
411
        signal number, then returns the string "Signal NUM", where NUM is the
412
        signal number.
413
 
414
        If the supplied signal number is not a valid index into sys_siglist,
415
        returns NULL.
416
 
417
        The returned string is only guaranteed to be valid only until the
418
        next call to strsignal.
419
 
420
*/
421
 
422
#ifndef HAVE_STRSIGNAL
423
 
424
const char *
425
strsignal (signo)
426
  int signo;
427
{
428
  const char *msg;
429
  static char buf[32];
430
 
431
#ifndef HAVE_SYS_SIGLIST
432
 
433
  if (signal_names == NULL)
434
    {
435
      init_signal_tables ();
436
    }
437
 
438
#endif
439
 
440
  if ((signo < 0) || (signo >= sys_nsig))
441
    {
442
      /* Out of range, just return NULL */
443
      msg = NULL;
444
    }
445
  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
446
    {
447
      /* In range, but no sys_siglist or no entry at this index. */
448
      sprintf (buf, "Signal %d", signo);
449
      msg = (const char *) buf;
450
    }
451
  else
452
    {
453
      /* In range, and a valid message.  Just return the message. */
454
      msg = (const char *) sys_siglist[signo];
455
    }
456
 
457
  return (msg);
458
}
459
 
460
#endif /* ! HAVE_STRSIGNAL */
461
 
462
/*
463
 
464
NAME
465
 
466
        strsigno -- map an signal number to a symbolic name string
467
 
468
SYNOPSIS
469
 
470
        const char *strsigno (int signo)
471
 
472
DESCRIPTION
473
 
474
        Given an signal number, returns a pointer to a string containing
475
        the symbolic name of that signal number, as found in <signal.h>.
476
 
477
        If the supplied signal number is within the valid range of indices
478
        for symbolic names, but no name is available for the particular
479
        signal number, then returns the string "Signal NUM", where NUM is
480
        the signal number.
481
 
482
        If the supplied signal number is not within the range of valid
483
        indices, then returns NULL.
484
 
485
BUGS
486
 
487
        The contents of the location pointed to are only guaranteed to be
488
        valid until the next call to strsigno.
489
 
490
*/
491
 
492
const char *
493
strsigno (signo)
494
  int signo;
495
{
496
  const char *name;
497
  static char buf[32];
498
 
499
  if (signal_names == NULL)
500
    {
501
      init_signal_tables ();
502
    }
503
 
504
  if ((signo < 0) || (signo >= num_signal_names))
505
    {
506
      /* Out of range, just return NULL */
507
      name = NULL;
508
    }
509
  else if ((signal_names == NULL) || (signal_names[signo] == NULL))
510
    {
511
      /* In range, but no signal_names or no entry at this index. */
512
      sprintf (buf, "Signal %d", signo);
513
      name = (const char *) buf;
514
    }
515
  else
516
    {
517
      /* In range, and a valid name.  Just return the name. */
518
      name = signal_names[signo];
519
    }
520
 
521
  return (name);
522
}
523
 
524
 
525
/*
526
 
527
NAME
528
 
529
        strtosigno -- map a symbolic signal name to a numeric value
530
 
531
SYNOPSIS
532
 
533
        int strtosigno (char *name)
534
 
535
DESCRIPTION
536
 
537
        Given the symbolic name of a signal, map it to a signal number.
538
        If no translation is found, returns 0.
539
 
540
*/
541
 
542
int
543
strtosigno (name)
544
     const char *name;
545
{
546
  int signo = 0;
547
 
548
  if (name != NULL)
549
    {
550
      if (signal_names == NULL)
551
        {
552
          init_signal_tables ();
553
        }
554
      for (signo = 0; signo < num_signal_names; signo++)
555
        {
556
          if ((signal_names[signo] != NULL) &&
557
              (strcmp (name, signal_names[signo]) == 0))
558
            {
559
              break;
560
            }
561
        }
562
      if (signo == num_signal_names)
563
        {
564
          signo = 0;
565
        }
566
    }
567
  return (signo);
568
}
569
 
570
 
571
/*
572
 
573
NAME
574
 
575
        psignal -- print message about signal to stderr
576
 
577
SYNOPSIS
578
 
579
        void psignal (unsigned signo, char *message);
580
 
581
DESCRIPTION
582
 
583
        Print to the standard error the message, followed by a colon,
584
        followed by the description of the signal specified by signo,
585
        followed by a newline.
586
*/
587
 
588
#ifndef HAVE_PSIGNAL
589
 
590
void
591
psignal (signo, message)
592
  unsigned signo;
593
  char *message;
594
{
595
  if (signal_names == NULL)
596
    {
597
      init_signal_tables ();
598
    }
599
  if ((signo <= 0) || (signo >= sys_nsig))
600
    {
601
      fprintf (stderr, "%s: unknown signal\n", message);
602
    }
603
  else
604
    {
605
      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
606
    }
607
}
608
 
609
#endif  /* ! HAVE_PSIGNAL */
610
 
611
 
612
/* A simple little main that does nothing but print all the signal translations
613
   if MAIN is defined and this file is compiled and linked. */
614
 
615
#ifdef MAIN
616
 
617
#include <stdio.h>
618
 
619
int
620
main ()
621
{
622
  int signo;
623
  int maxsigno;
624
  const char *name;
625
  const char *msg;
626
 
627
  maxsigno = signo_max ();
628
  printf ("%d entries in names table.\n", num_signal_names);
629
  printf ("%d entries in messages table.\n", sys_nsig);
630
  printf ("%d is max useful index.\n", maxsigno);
631
 
632
  /* Keep printing values until we get to the end of *both* tables, not
633
     *either* table.  Note that knowing the maximum useful index does *not*
634
     relieve us of the responsibility of testing the return pointer for
635
     NULL. */
636
 
637
  for (signo = 0; signo <= maxsigno; signo++)
638
    {
639
      name = strsigno (signo);
640
      name = (name == NULL) ? "<NULL>" : name;
641
      msg = strsignal (signo);
642
      msg = (msg == NULL) ? "<NULL>" : msg;
643
      printf ("%-4d%-18s%s\n", signo, name, msg);
644
    }
645
 
646
  return 0;
647
}
648
 
649
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.