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

Subversion Repositories or1200_soc

[/] [or1200_soc/] [trunk/] [sw/] [Meansoffreedom/] [C_plus_hack/] [strsignal.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 qaztronic
/* 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 ANSI_PROTOTYPES
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
  const int value;              /* The numeric value from <signal.h> */
71
  const char *const name;       /* The equivalent symbolic value */
72
#ifndef HAVE_SYS_SIGLIST
73
  const char *const 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
@deftypefn Extension int signo_max (void)
354
 
355
Returns the maximum signal value for which a corresponding symbolic
356
name or message is available.  Note that in the case where we use the
357
@code{sys_siglist} supplied by the system, it is possible for there to
358
be more symbolic names than messages, or vice versa.  In fact, the
359
manual page for @code{psignal(3b)} explicitly warns that one should
360
check the size of the table (@code{NSIG}) before indexing it, since
361
new signal codes may be added to the system before they are added to
362
the table.  Thus @code{NSIG} might be smaller than value implied by
363
the largest signo value defined in @code{<signal.h>}.
364
 
365
We return the maximum value that can be used to obtain a meaningful
366
symbolic name or message.
367
 
368
@end deftypefn
369
 
370
*/
371
 
372
int
373
signo_max ()
374
{
375
  int maxsize;
376
 
377
  if (signal_names == NULL)
378
    {
379
      init_signal_tables ();
380
    }
381
  maxsize = MAX (sys_nsig, num_signal_names);
382
  return (maxsize - 1);
383
}
384
 
385
 
386
/*
387
 
388
@deftypefn Supplemental {const char *} strsignal (int @var{signo})
389
 
390
Maps an signal number to an signal message string, the contents of
391
which are implementation defined.  On systems which have the external
392
variable @code{sys_siglist}, these strings will be the same as the
393
ones used by @code{psignal()}.
394
 
395
If the supplied signal number is within the valid range of indices for
396
the @code{sys_siglist}, but no message is available for the particular
397
signal number, then returns the string @samp{Signal @var{num}}, where
398
@var{num} is the signal number.
399
 
400
If the supplied signal number is not a valid index into
401
@code{sys_siglist}, returns @code{NULL}.
402
 
403
The returned string is only guaranteed to be valid only until the next
404
call to @code{strsignal}.
405
 
406
@end deftypefn
407
 
408
*/
409
 
410
#ifndef HAVE_STRSIGNAL
411
 
412
const char *
413
strsignal (signo)
414
  int signo;
415
{
416
  const char *msg;
417
  static char buf[32];
418
 
419
#ifndef HAVE_SYS_SIGLIST
420
 
421
  if (signal_names == NULL)
422
    {
423
      init_signal_tables ();
424
    }
425
 
426
#endif
427
 
428
  if ((signo < 0) || (signo >= sys_nsig))
429
    {
430
      /* Out of range, just return NULL */
431
      msg = NULL;
432
    }
433
  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
434
    {
435
      /* In range, but no sys_siglist or no entry at this index. */
436
      sprintf (buf, "Signal %d", signo);
437
      msg = (const char *) buf;
438
    }
439
  else
440
    {
441
      /* In range, and a valid message.  Just return the message. */
442
      msg = (const char *) sys_siglist[signo];
443
    }
444
 
445
  return (msg);
446
}
447
 
448
#endif /* ! HAVE_STRSIGNAL */
449
 
450
/*
451
 
452
@deftypefn Extension {const char*} strsigno (int @var{signo})
453
 
454
Given an signal number, returns a pointer to a string containing the
455
symbolic name of that signal number, as found in @code{<signal.h>}.
456
 
457
If the supplied signal number is within the valid range of indices for
458
symbolic names, but no name is available for the particular signal
459
number, then returns the string @samp{Signal @var{num}}, where
460
@var{num} is the signal number.
461
 
462
If the supplied signal number is not within the range of valid
463
indices, then returns @code{NULL}.
464
 
465
The contents of the location pointed to are only guaranteed to be
466
valid until the next call to @code{strsigno}.
467
 
468
@end deftypefn
469
 
470
*/
471
 
472
const char *
473
strsigno (signo)
474
  int signo;
475
{
476
  const char *name;
477
  static char buf[32];
478
 
479
  if (signal_names == NULL)
480
    {
481
      init_signal_tables ();
482
    }
483
 
484
  if ((signo < 0) || (signo >= num_signal_names))
485
    {
486
      /* Out of range, just return NULL */
487
      name = NULL;
488
    }
489
  else if ((signal_names == NULL) || (signal_names[signo] == NULL))
490
    {
491
      /* In range, but no signal_names or no entry at this index. */
492
      sprintf (buf, "Signal %d", signo);
493
      name = (const char *) buf;
494
    }
495
  else
496
    {
497
      /* In range, and a valid name.  Just return the name. */
498
      name = signal_names[signo];
499
    }
500
 
501
  return (name);
502
}
503
 
504
 
505
/*
506
 
507
@deftypefn Extension int strtosigno (const char *@var{name})
508
 
509
Given the symbolic name of a signal, map it to a signal number.  If no
510
translation is found, returns 0.
511
 
512
@end deftypefn
513
 
514
*/
515
 
516
int
517
strtosigno (name)
518
     const char *name;
519
{
520
  int signo = 0;
521
 
522
  if (name != NULL)
523
    {
524
      if (signal_names == NULL)
525
        {
526
          init_signal_tables ();
527
        }
528
      for (signo = 0; signo < num_signal_names; signo++)
529
        {
530
          if ((signal_names[signo] != NULL) &&
531
              (strcmp (name, signal_names[signo]) == 0))
532
            {
533
              break;
534
            }
535
        }
536
      if (signo == num_signal_names)
537
        {
538
          signo = 0;
539
        }
540
    }
541
  return (signo);
542
}
543
 
544
 
545
/*
546
 
547
@deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message})
548
 
549
Print @var{message} to the standard error, followed by a colon,
550
followed by the description of the signal specified by @var{signo},
551
followed by a newline.
552
 
553
@end deftypefn
554
 
555
*/
556
 
557
#ifndef HAVE_PSIGNAL
558
 
559
void
560
psignal (signo, message)
561
  int  signo;
562
  const char *message;
563
{
564
  if (signal_names == NULL)
565
    {
566
      init_signal_tables ();
567
    }
568
  if ((signo <= 0) || (signo >= sys_nsig))
569
    {
570
      fprintf (stderr, "%s: unknown signal\n", message);
571
    }
572
  else
573
    {
574
      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
575
    }
576
}
577
 
578
#endif  /* ! HAVE_PSIGNAL */
579
 
580
 
581
/* A simple little main that does nothing but print all the signal translations
582
   if MAIN is defined and this file is compiled and linked. */
583
 
584
#ifdef MAIN
585
 
586
#include <stdio.h>
587
 
588
int
589
main ()
590
{
591
  int signo;
592
  int maxsigno;
593
  const char *name;
594
  const char *msg;
595
 
596
  maxsigno = signo_max ();
597
  printf ("%d entries in names table.\n", num_signal_names);
598
  printf ("%d entries in messages table.\n", sys_nsig);
599
  printf ("%d is max useful index.\n", maxsigno);
600
 
601
  /* Keep printing values until we get to the end of *both* tables, not
602
     *either* table.  Note that knowing the maximum useful index does *not*
603
     relieve us of the responsibility of testing the return pointer for
604
     NULL. */
605
 
606
  for (signo = 0; signo <= maxsigno; signo++)
607
    {
608
      name = strsigno (signo);
609
      name = (name == NULL) ? "<NULL>" : name;
610
      msg = strsignal (signo);
611
      msg = (msg == NULL) ? "<NULL>" : msg;
612
      printf ("%-4d%-18s%s\n", signo, name, msg);
613
    }
614
 
615
  return 0;
616
}
617
 
618
#endif

powered by: WebSVN 2.1.0

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