raisecond.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:4k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)raisecond.c 1.11 99/09/11 Copyright 1985 J. Schilling */
  2. /*
  3.  * raise a condition (software signal)
  4.  */
  5. /*
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2, or (at your option)
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; see the file COPYING.  If not, write to
  18.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20. /*
  21.  * Check for installed condition handlers.
  22.  * If a handler is found, the function is called with the appropriate args.
  23.  * If no handler is found or no handler signals success,
  24.  * the program will be aborted.
  25.  *
  26.  * Copyright (c) 1985 J. Schilling
  27.  */
  28. #include <mconfig.h>
  29. #include <stdio.h>
  30. #include <standard.h>
  31. #include <sigblk.h>
  32. #include <unixstd.h>
  33. #include <stdxlib.h>
  34. #include <strdefs.h>
  35. #include <avoffset.h>
  36. #if !defined(AV_OFFSET) || !defined(FP_INDIR)
  37. # ifdef HAVE_SCANSTACK
  38. # undef HAVE_SCANSTACK
  39. # endif
  40. #endif
  41. #ifdef NO_SCANSTACK
  42. # ifdef HAVE_SCANSTACK
  43. # undef HAVE_SCANSTACK
  44. # endif
  45. #endif
  46. /*
  47.  * Macros to print to stderr without stdio, to avoid screwing up.
  48.  */
  49. #ifndef STDERR_FILENO
  50. #define STDERR_FILENO 2
  51. #endif
  52. #define eprints(a) (void)write(STDERR_FILENO, (a), sizeof(a)-1)
  53. #define eprintl(a) (void)write(STDERR_FILENO, (a), strlen(a))
  54. #define is_even(p) ((((long)(p)) & 1) == 0)
  55. #define even(p) (((long)(p)) & ~1L)
  56. #ifdef __future__
  57. #define even(p) (((long)(p)) - 1)/* will this work with 64 bit ?? */
  58. #endif
  59. LOCAL void raiseabort  __PR((const char *));
  60. #ifdef HAVE_SCANSTACK
  61. #include <stkframe.h>
  62. LOCAL BOOL framehandle __PR((SIGBLK *, const char *, const char *, long));
  63. /*
  64.  * Loop through the chain of procedure frames on the stack.
  65.  *
  66.  * Frame pointers normally have even values.
  67.  * Frame pointers of procedures with an installed handler are marked odd.
  68.  * The even base value, in this case actually points to a SIGBLK which
  69.  * holds the saved "real" frame pointer.
  70.  * The SIGBLK mentioned above may me the start of a chain of SIGBLK's,
  71.  * containing different handlers.
  72.  */
  73. void raisecond(signame, arg2)
  74. const char *signame;
  75. long arg2;
  76. {
  77. register struct frame *fp = (struct frame *)getfp();
  78. for(; fp; fp = (struct frame *)fp->fr_savfp) {
  79. if (is_even(fp))
  80. continue;
  81. fp = (struct frame *)even(fp); /* really is (SIGBLK *) */
  82. if (framehandle((SIGBLK *)fp, signame, signame, arg2))
  83. return;
  84. else if (framehandle((SIGBLK *)fp, "any_other", signame, arg2))
  85. return;
  86. fp = (struct frame *)((SIGBLK *)fp)->sb_savfp;
  87. }
  88. /*
  89.  * No matching handler that signals success found.
  90.  * Print error message and abort.
  91.  */
  92. raiseabort(signame);
  93. /* NOTREACHED */
  94. }
  95. /*
  96.  * Loop through the handler chain for a procedure frame.
  97.  *
  98.  * If no handler with matching name is found, return FALSE,
  99.  * otherwise the first handler with matching name is called.
  100.  * The return value in the latter case depends on the called function.
  101.  */
  102. LOCAL BOOL framehandle(sp, handlename, signame, arg2)
  103. register SIGBLK *sp;
  104. const char *handlename;
  105. const char *signame;
  106. long arg2;
  107. {
  108. for(; sp; sp = sp->sb_signext) {
  109. if (streql(sp->sb_signame, handlename)) {
  110. if (sp->sb_sigfun == NULL) { /* deactivated */
  111. return (FALSE);
  112. } else {
  113. return (*sp->sb_sigfun)(signame,
  114. sp->sb_sigarg, arg2);
  115. }
  116. }
  117. }
  118. return (FALSE);
  119. }
  120. #else /* HAVE_SCANSTACK */
  121. void raisecond(signame, arg2)
  122. const char *signame;
  123. long arg2;
  124. {
  125. /*
  126.  * Print error message and abort.
  127.  */
  128. raiseabort(signame);
  129. /* NOTREACHED */
  130. }
  131. #endif /* HAVE_SCANSTACK */
  132. LOCAL void raiseabort(signame)
  133. const char *signame;
  134. {
  135. eprints("Condition not caught: "); eprintl(signame); eprints(".n");
  136. #ifndef HAVE_SCANSTACK
  137. eprints("Raisecond: not implemented.n");
  138. #endif
  139. abort();
  140. /* NOTREACHED */
  141. }