ReactOS  0.4.14-dev-854-gb9426a3
raisecond.c
Go to the documentation of this file.
1 /* @(#)raisecond.c 1.22 09/07/10 Copyright 1985, 1989, 1995-2004 J. Schilling */
2 /*
3  * raise a condition (software signal)
4  */
5 /*
6  * The contents of this file are subject to the terms of the
7  * Common Development and Distribution License, Version 1.0 only
8  * (the "License"). You may not use this file except in compliance
9  * with the License.
10  *
11  * See the file CDDL.Schily.txt in this distribution for details.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file CDDL.Schily.txt from this distribution.
15  */
16 /*
17  * Check for installed condition handlers.
18  * If a handler is found, the function is called with the appropriate args.
19  * If no handler is found or no handler signals success,
20  * the program will be aborted.
21  *
22  * Copyright (c) 1985, 1989, 1995-2004 J. Schilling
23  */
24 #include <schily/mconfig.h>
25 #include <schily/stdio.h>
26 #include <schily/standard.h>
27 #include <schily/sigblk.h>
28 #include <schily/unistd.h>
29 #include <schily/stdlib.h>
30 #include <schily/string.h>
31 #include <schily/avoffset.h>
32 #include <schily/schily.h>
33 
34 #if !defined(AV_OFFSET) || !defined(FP_INDIR)
35 # ifdef HAVE_SCANSTACK
36 # undef HAVE_SCANSTACK
37 # endif
38 #endif
39 
40 /*
41  * Macros to print to stderr without stdio, to avoid screwing up.
42  */
43 #ifndef STDERR_FILENO
44 #define STDERR_FILENO 2
45 #endif
46 #define eprints(a) (void)write(STDERR_FILENO, (a), sizeof (a)-1)
47 #define eprintl(a) (void)write(STDERR_FILENO, (a), strlen(a))
48 
49 #define is_even(p) ((((long)(p)) & 1) == 0)
50 #define even(p) (((long)(p)) & ~1L)
51 #ifdef __future__
52 #define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */
53 #endif
54 
55 
56 LOCAL void raiseabort __PR((const char *));
57 
58 #ifdef HAVE_SCANSTACK
59 #include <schily/stkframe.h>
60 #define next_frame(vp) do { \
61  if (((struct frame *)(vp))->fr_savfp == 0) { \
62  vp = (void *)0; \
63  break; \
64  } \
65  if (((struct frame *)(vp))->fr_savpc == 0) { \
66  vp = (void *)0; \
67  break; \
68  } \
69  vp = \
70  (void *)((struct frame *)(vp))->fr_savfp; \
71  } while (vp != NULL && is_even(vp)); \
72  vp = (struct frame *)even(vp);
73 #else
74 #if defined(IS_MACOS_X)
75 /*
76  * The MAC OS X linker does not grok "common" varaibles.
77  * Make __roothandle a "data" variable.
78  */
80 #else
82 #endif
83 
84 #define next_frame(vp) vp = (((SIGBLK *)(vp))->sb_savfp);
85 #endif
86 
87 LOCAL BOOL framehandle __PR((SIGBLK *, const char *, const char *, long));
88 
89 /*
90  * Loop through the chain of procedure frames on the stack.
91  *
92  * Frame pointers normally have even values.
93  * Frame pointers of procedures with an installed handler are marked odd.
94  * The even base value, in this case actually points to a SIGBLK which
95  * holds the saved "real" frame pointer.
96  * The SIGBLK mentioned above may me the start of a chain of SIGBLK's,
97  * containing different handlers.
98  */
99 EXPORT void
100 raisecond(signame, arg2)
101  const char *signame;
102  long arg2;
103 {
104  register void *vp = NULL;
105 
106 #ifdef HAVE_SCANSTACK
107  /*
108  * As the SCO OpenServer C-Compiler has a bug that may cause
109  * the first function call to getfp() been done before the
110  * new stack frame is created, we call getfp() twice.
111  */
112  (void) getfp();
113  vp = getfp();
114  next_frame(vp);
115 #else
116  vp = __roothandle;
117 #endif
118 
119  while (vp) {
120  if (framehandle((SIGBLK *)vp, signame, signame, arg2))
121  return;
122  else if (framehandle((SIGBLK *)vp, "any_other", signame, arg2))
123  return;
124 #ifdef HAVE_SCANSTACK
125  vp = (struct frame *)((SIGBLK *)vp)->sb_savfp;
126 #endif
127  next_frame(vp);
128  }
129  /*
130  * No matching handler that signals success found.
131  * Print error message and abort.
132  */
133  raiseabort(signame);
134  /* NOTREACHED */
135 }
136 
137 /*
138  * Loop through the handler chain for a procedure frame.
139  *
140  * If no handler with matching name is found, return FALSE,
141  * otherwise the first handler with matching name is called.
142  * The return value in the latter case depends on the called function.
143  */
144 LOCAL BOOL
145 framehandle(sp, handlename, signame, arg2)
146  register SIGBLK *sp;
147  const char *handlename;
148  const char *signame;
149  long arg2;
150 {
151  for (; sp; sp = sp->sb_signext) {
152  if (sp->sb_signame != NULL &&
153  streql(sp->sb_signame, handlename)) {
154  if (sp->sb_sigfun == NULL) { /* deactivated */
155  return (FALSE);
156  } else {
157  return (*sp->sb_sigfun)(signame,
158  sp->sb_sigarg, arg2);
159  }
160  }
161  }
162  return (FALSE);
163 }
164 
165 LOCAL void
166 raiseabort(signame)
167  const char *signame;
168 {
169  eprints("Condition not caught: "); eprintl(signame); eprints(".\n");
170  abort();
171  /* NOTREACHED */
172 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define eprintl(a)
Definition: raisecond.c:47
LOCAL void raiseabort(char *signame) const
Definition: raisecond.c:166
EXPORT int streql(char *a, const char *b) const
Definition: streql.c:23
EXPORT void raisecond(char *signame, long arg2) const
Definition: raisecond.c:100
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
Definition: sigblk.h:30
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
LOCAL void raiseabort __PR((const char *))
#define LOCAL(type)
Definition: jmorecfg.h:289
LOCAL BOOL framehandle(SIGBLK *sp, const char *handlename, const char *signame, long arg2)
Definition: raisecond.c:145
#define next_frame(vp)
Definition: raisecond.c:84
#define abort()
Definition: i386-dis.c:35
#define eprints(a)
Definition: raisecond.c:46
static const WCHAR sp[]
Definition: suminfo.c:288
EXPORT SIGBLK * __roothandle
Definition: raisecond.c:81