⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sigact.c

📁 一个开放源代码的 AT&T 的 Korn Shell 的复制品, 支持大多数 ksh89 的特性。
💻 C
字号:
/* NAME: *      sigact.c - fake sigaction(2) * * SYNOPSIS: *      #include "sigact.h" *  *      int sigaction(int sig, struct sigaction *act,  *                      struct sigaction *oact); *      int sigaddset(sigset_t *mask, int sig); *      int sigdelset(sigset_t *mask, int sig); *      int sigemptyset(sigset_t *mask); *      int sigfillset(sigset_t *mask); *      int sigismember(sigset_t *mask, int sig); *      int sigpending(sigset_t *set); *      int sigprocmask(int how, sigset_t *set, sigset_t *oset); *      int sigsuspend(sigset_t *mask); *       *      RETSIGTYPE (*Signal(int sig, RETSIGTYPE (*disp)(int)))(int); * * DESCRIPTION: *      This is a fake sigaction implementation.  It uses  *      sigsetmask(2) et al or sigset(2) and friends if  *      available, otherwise it just uses signal(2).  If it  *      thinks sigaction(2) really exists it compiles to "almost"  *      nothing.  *       *      In any case it provides a Signal() function that is  *      implemented in terms of sigaction(). *      If not using signal(2) as part of the underlying  *      implementation (USE_SIGNAL or USE_SIGMASK), and  *      NO_SIGNAL is not defined, it also provides a signal()  *      function that calls Signal().  * *      The need for all this mucking about is the problems  *      caused by mixing various signal handling mechanisms in  *      the one process.  This module allows for a consistent  *      POSIX compliant interface to whatever is actually  *      available.  *       *      sigaction() allows the caller to examine and/or set the  *      action to be associated with a given signal. "act" and  *      "oact" are pointers to 'sigaction structs': *.nf *  *      struct sigaction  *      { *             RETSIGTYPE  (*sa_handler)(); *             sigset_t  sa_mask; *             int       sa_flags; *      }; *.fi *  *      RETSIGTYPE is normally 'void' in the POSIX implementation  *      and for most current systems.  On some older UNIX  *      systems, signal handlers do not return 'void', so   *      this implementation keeps 'sa_handler' inline with the  *      hosts normal signal handling conventions. *      'sa_mask' controls which signals will be blocked while  *      the selected signal handler is active.  It is not used  *      in this implementation. *      'sa_flags' controls various semantics such as whether  *      system calls should be automagically restarted  *      (SA_RESTART) etc.  It is not used in this  *      implementation.  *      Either "act" or "oact" may be NULL in which case the  *      appropriate operation is skipped. *       *      sigaddset() adds "sig" to the sigset_t pointed to by "mask". *       *      sigdelset() removes "sig" from the sigset_t pointed to  *      by "mask".  *       *      sigemptyset() makes the sigset_t pointed to by "mask" empty. *       *      sigfillset() makes the sigset_t pointed to by "mask"  *      full ie. match all signals. *       *      sigismember() returns true if "sig" is found in "*mask". *       *      sigpending() is supposed to return "set" loaded with the  *      set of signals that are blocked and pending for the  *      calling process.  It does nothing in this impementation. *       *      sigprocmask() is used to examine and/or change the  *      signal mask for the calling process.  Either "set" or  *      "oset" may be NULL in which case the appropriate  *      operation is skipped.  "how" may be one of SIG_BLOCK,  *      SIG_UNBLOCK or SIG_SETMASK.  If this package is built  *      with USE_SIGNAL, then this routine achieves nothing. *       *      sigsuspend() sets the signal mask to "*mask" and waits  *      for a signal to be delivered after which the previous  *      mask is restored. *       *       * RETURN VALUE: *      0==success, -1==failure * * BUGS: *      Since we fake most of this, don't expect fancy usage to  *      work. * * AUTHOR: *      Simon J. Gerraty <sjg@zen.void.oz.au> */     /* COPYRIGHT: *      @(#)Copyright (c) 1992 Simon J. Gerraty * *      This is free software.  It comes with NO WARRANTY. *      Permission to use, modify and distribute this source code *      is granted subject to the following conditions. *      1/ that that the above copyright notice and this notice  *      are preserved in all copies and that due credit be given  *      to the author.   *      2/ that any changes to this code are clearly commented  *      as such so that the author does get blamed for bugs  *      other than his own. *       *      Please send copies of changes and bug-fixes to: *      sjg@zen.void.oz.au * *//* Changes to sigact.c for pdksh, Michael Rendell <michael@cs.mun.ca>: *	- sigsuspend(): pass *mask to bsd4.2 sigpause instead of mask. *	- changed SIG_HDLR to RETSIGTYPE for use with GNU autoconf *	- added and used RETSIGVAL *	- include sh.h instead of signal.h (to get *_SIGNALS macros) *	- changed if !SA_NOCLDSTOP ... to USE_FAKE_SIGACT to avoid confusion *	- set the USE_* defines using the *_SIGNALS defines from autoconf *	- sigaction(): if using BSD signals, use sigvec() (used to use *	  signal()) and set the SV_INTERRUPT flag (POSIX says syscalls *	  are interrupted and pdksh needs this behaviour). *	- define IS_KSH before including anything; ifdef out routines *	  not used in ksh if IS_KSH is defined (same in sigact.h). *	- use ARGS() instead of __P() *	- sigaction(),sigsuspend(),Signal(),signal(): use handler_t typedef *	  instead of explicit type. *//*    #include <signal.h>*/#define IS_KSH#include "sh.h"/*    #ifndef __P    # if defined(__STDC__) || defined(__cplusplus)    #   define	__P(p)	p    # else    #   define	__P(p)	()    # endif    #endif*//* * some systems have a faulty sigaction() implementation! * Allow us to bypass it. * Or they may have installed sigact.h as signal.h which is why  * we have SA_NOCLDSTOP defined. */#ifdef USE_FAKE_SIGACT /* let autoconf decide.. *//* #if !defined(SA_NOCLDSTOP) || defined(_SIGACT_H) || defined(USE_SIGNAL) || defined(USE_SIGSET) || defined(USE_SIGMASK) *//* Let autoconf decide which to use */#ifdef BSD42_SIGNALS# define USE_SIGMASK#else# ifdef BSD41_SIGNALS#  define USE_SIGSET# else#  define USE_SIGNAL# endif#endif /* BSD42_SIGNALS *//* * if we haven't been told, * try and guess what we should implement with. */#if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)# if defined(sigmask) || defined(BSD) || defined(_BSD) && !defined(BSD41)#   define USE_SIGMASK# else#   ifndef NO_SIGSET#     define USE_SIGSET#   else#     define USE_SIGNAL#   endif# endif#endif/* * if we still don't know, we're in trouble */#if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)error must know what to implement with#endif#include "sigact.h"/* * in case signal() has been mapped to our Signal(). */#undef signal intsigaction(sig, act, oact)  int sig;  struct sigaction *act, *oact;{  handler_t oldh;  if (act)  {#ifdef USE_SIGSET    oldh = sigset(sig, act->sa_handler);#else# ifdef USE_SIGMASK    struct sigvec nsv,osv;    nsv.sv_handler = act->sa_handler;    nsv.sv_mask = 0;			/* punt */    nsv.sv_flags = SV_INTERRUPT;	/* punt */    sigvec(sig, &nsv, &osv);    oldh = osv.sv_handler;# else /* USE_SIGMASK */    oldh = signal(sig, act->sa_handler);# endif /* USE_SIGMASK */#endif  }  else  {    if (oact)    {      #ifdef USE_SIGSET      oldh = sigset(sig, SIG_IGN);#else      oldh = signal(sig, SIG_IGN);#endif      if (oldh != SIG_IGN && oldh !=  SIG_ERR)      {#ifdef USE_SIGSET	(void) sigset(sig, oldh);#else	(void) signal(sig, oldh);#endif      }    }  }  if (oact)  {    oact->sa_handler = oldh;  }  return 0;				/* hey we're faking it */}intsigaddset(mask, sig)  sigset_t *mask;  int sig;{  *mask |= sigmask(sig);  return 0;}#ifndef IS_KSHintsigdelset(mask, sig)  sigset_t *mask;  int sig;{  *mask &= ~(sigmask(sig));  return 0;}#endif /* IS_KSH */intsigemptyset(mask)  sigset_t *mask;{  *mask = 0;  return 0;}#ifndef IS_KSHintsigfillset(mask)  sigset_t *mask;{  *mask = ~0;  return 0;}#endif /* IS_KSH */#ifndef IS_KSHintsigismember(mask, sig)  sigset_t *mask;  int sig;{  return ((*mask) & sigmask(sig));}#endif /* IS_KSH */#ifndef IS_KSHintsigpending(set)  sigset_t *set;{  return 0;				/* faking it! */}#endif /* IS_KSH */intsigprocmask(how, set, oset)  int how;  sigset_t *set, *oset;{#ifdef USE_SIGSET  register int i;#endif  static sigset_t sm;  static int once = 0;  if (!once)  {    /*     * initally we clear sm,     * there after, it represents the last     * thing we did.     */    once++;#ifdef USE_SIGMASK    sm = sigblock(0);#else    sm = 0;#endif  }    if (oset)    *oset = sm;  if (set)  {    switch (how)    {    case SIG_BLOCK:      sm |= *set;      break;    case SIG_UNBLOCK:      sm &= ~(*set);      break;    case SIG_SETMASK:      sm = *set;      break;    }#ifdef USE_SIGMASK    (void) sigsetmask(sm);#else# ifdef USE_SIGSET    for (i = 1; i < NSIG; i++)    {      if (how == SIG_UNBLOCK)      {	if (*set & sigmask(i))	  sigrelse(i);      }      else	if (sm & sigmask(i))	{	  sighold(i);	}    }# endif#endif  }  return 0;}intsigsuspend(mask)  sigset_t *mask;{#ifdef USE_SIGMASK  sigpause(*mask);#else  register int i;# ifdef USE_SIGSET  for (i = 1; i < NSIG; i++)  {    if (*mask & sigmask(i))    {      /* not the same sigpause() as above! */      sigpause(i);			      break;    }  }# else /* signal(2) only */  handler_t oldh;  /*   * make sure that signals in mask will not   * be ignored.   */  for (i = 1; i < NSIG; i++)  {    if (*mask & sigmask(i))    {      if ((oldh = signal(i, SIG_DFL)) !=  SIG_ERR &&	  oldh != SIG_IGN &&	  oldh != SIG_DFL)	(void) signal(i, oldh);		/* restore handler */    }  }  pause();				/* wait for a signal */# endif#endif  return 0;}#endif /* USE_FAKE_SIGACT (was ! SA_NOCLDSTOP) */#if !defined(RETSIGTYPE)# define RETSIGTYPE void# define RETSIGVAL#endif#if !defined(SIG_ERR)# define SIG_ERR	(RETSIGTYPE (*)())-1#endif/* * an implementation of signal() using sigaction(). */#ifndef IS_KSHhandler_t Signal(sig, handler)  int sig;  handler_t handler;{  struct sigaction act, oact;  act.sa_handler = handler;  sigemptyset(&act.sa_mask);  act.sa_flags = 0;  if (sigaction(sig, &act, &oact) < 0)    return (SIG_ERR);  return (oact.sa_handler);}#endif /* IS_KSH */#ifndef IS_KSH#if !defined(USE_SIGNAL) && !defined(USE_SIGMASK) && !defined(NO_SIGNAL)/* * ensure we avoid signal mayhem */handler_t signal(sig, handler)  int sig;  handler_t handler;{  return (Signal(sig, handler));}#endif#endif /* IS_KSH *//* This lot (for GNU-Emacs) goes at the end of the file. *//*  * Local Variables: * version-control:t * comment-column:40 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -