ReactOS 0.4.15-dev-7704-gc07eb9f
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
56LOCAL 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
87LOCAL 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 */
99EXPORT void
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 */
145framehandle(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
165LOCAL void
167 const char *signame;
168{
169 eprints("Condition not caught: "); eprintl(signame); eprints(".\n");
170 abort();
171 /* NOTREACHED */
172}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define abort()
Definition: i386-dis.c:34
#define LOCAL(type)
Definition: jmorecfg.h:289
static const WCHAR sp[]
Definition: suminfo.c:287
#define __PR(a)
Definition: prototyp.h:106
EXPORT SIGBLK * __roothandle
Definition: raisecond.c:81
LOCAL BOOL framehandle(SIGBLK *sp, const char *handlename, const char *signame, long arg2)
Definition: raisecond.c:145
#define eprints(a)
Definition: raisecond.c:46
LOCAL void raiseabort(char *signame) const
Definition: raisecond.c:166
EXPORT void raisecond(char *signame, long arg2) const
Definition: raisecond.c:100
#define next_frame(vp)
Definition: raisecond.c:84
#define eprintl(a)
Definition: raisecond.c:47
EXPORT int streql(char *a, const char *b) const
Definition: streql.c:23
Definition: sigblk.h:30