2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)raisecond.c 1.18 04/05/09 Copyright 1985, 1989, 1995-2004 J. Schilling */
15 * raise a condition (software signal)
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2
20 * as published by the Free Software Foundation.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License along with
28 * this program; see the file COPYING. If not, write to the Free Software
29 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 * Check for installed condition handlers.
33 * If a handler is found, the function is called with the appropriate args.
34 * If no handler is found or no handler signals success,
35 * the program will be aborted.
37 * Copyright (c) 1985, 1989, 1995-2004 J. Schilling
49 #if !defined(AV_OFFSET) || !defined(FP_INDIR)
50 # ifdef HAVE_SCANSTACK
51 # undef HAVE_SCANSTACK
56 * Macros to print to stderr without stdio, to avoid screwing up.
59 #define STDERR_FILENO 2
61 #define eprints(a) do { int ret; ret = write(STDERR_FILENO, (a), sizeof (a)-1); } while (0)
62 #define eprintl(a) do { int ret; ret = write(STDERR_FILENO, (a), strlen(a)); } while (0)
64 #define is_even(p) ((((long)(p)) & 1) == 0)
65 #define even(p) (((long)(p)) & ~1L)
67 #define even(p) (((long)(p)) - 1) /* will this work with 64 bit ?? */
71 LOCAL void raiseabort __PR((const char *));
75 #define next_frame(vp) do { \
76 if (((struct frame *)(vp))->fr_savfp == 0) { \
80 if (((struct frame *)(vp))->fr_savpc == 0) { \
85 (void *)((struct frame *)(vp))->fr_savfp; \
86 } while (vp != NULL && is_even(vp)); \
87 vp = (struct frame *)even(vp);
89 EXPORT SIGBLK *__roothandle;
91 #define next_frame(vp) vp = (((SIGBLK *)(vp))->sb_savfp);
94 LOCAL BOOL framehandle __PR((SIGBLK *, const char *, const char *, long));
97 * Loop through the chain of procedure frames on the stack.
99 * Frame pointers normally have even values.
100 * Frame pointers of procedures with an installed handler are marked odd.
101 * The even base value, in this case actually points to a SIGBLK which
102 * holds the saved "real" frame pointer.
103 * The SIGBLK mentioned above may me the start of a chain of SIGBLK's,
104 * containing different handlers.
107 raisecond(signame, arg2)
111 register void *vp = NULL;
113 #ifdef HAVE_SCANSTACK
115 * As the SCO OpenServer C-Compiler has a bug that may cause
116 * the first function call to getfp() been done before the
117 * new stack frame is created, we call getfp() twice.
127 if (framehandle((SIGBLK *)vp, signame, signame, arg2))
129 else if (framehandle((SIGBLK *)vp, "any_other", signame, arg2))
131 #ifdef HAVE_SCANSTACK
132 vp = (struct frame *)((SIGBLK *)vp)->sb_savfp;
137 * No matching handler that signals success found.
138 * Print error message and abort.
145 * Loop through the handler chain for a procedure frame.
147 * If no handler with matching name is found, return FALSE,
148 * otherwise the first handler with matching name is called.
149 * The return value in the latter case depends on the called function.
152 framehandle(sp, handlename, signame, arg2)
154 const char *handlename;
158 for (; sp; sp = sp->sb_signext) {
159 if (sp->sb_signame != NULL &&
160 streql(sp->sb_signame, handlename)) {
161 if (sp->sb_sigfun == NULL) { /* deactivated */
164 return (*sp->sb_sigfun)(signame,
165 sp->sb_sigarg, arg2);
176 eprints("Condition not caught: "); eprintl(signame); eprints(".\n");