Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. FUNCTION
  3. <<signal>>---specify handler subroutine for a signal
  4.  
  5. INDEX
  6.         signal
  7. INDEX
  8.         _signal_r
  9.  
  10. ANSI_SYNOPSIS
  11.         #include <signal.h>
  12.         void (*signal(int <[sig]>, void(*<[func]>)(int))) (int);
  13.  
  14.         void (*_signal_r(void *<[reent]>, int <[sig]>, void(*<[func]>)(int))) (int);
  15.  
  16. TRAD_SYNOPSIS
  17.         #include <signal.h>
  18.         char ( * signal(<[sig]>, <[func]>) )()
  19.         int <[sig]>;
  20.         char ( * <[func]> )();
  21.  
  22.         char ( * _signal_r(<[reent]>, <[sig]>, <[func]>) )()
  23.         char *<[reent]>;
  24.         int <[sig]>;
  25.         char ( * <[func]> )();
  26.  
  27. DESCRIPTION
  28. <<signal>> provides a simple signal-handling implementation for embedded
  29. targets.
  30.  
  31. <<signal>> allows you to request changed treatment for a particular
  32. signal <[sig]>.  You can use one of the predefined macros <<SIG_DFL>>
  33. (select system default handling) or <<SIG_IGN>> (ignore this signal)
  34. as the value of <[func]>; otherwise, <[func]> is a function pointer
  35. that identifies a subroutine in your program as the handler for this signal.
  36.  
  37. Some of the execution environment for signal handlers is
  38. unpredictable; notably, the only library function required to work
  39. correctly from within a signal handler is <<signal>> itself, and
  40. only when used to redefine the handler for the current signal value.
  41.  
  42. Static storage is likewise unreliable for signal handlers, with one
  43. exception: if you declare a static storage location as `<<volatile
  44. sig_atomic_t>>', then you may use that location in a signal handler to
  45. store signal values.
  46.  
  47. If your signal handler terminates using <<return>> (or implicit
  48. return), your program's execution continues at the point
  49. where it was when the signal was raised (whether by your program
  50. itself, or by an external event).  Signal handlers can also
  51. use functions such as <<exit>> and <<abort>> to avoid returning.
  52.  
  53. The alternate function <<_signal_r>> is the reentrant version.
  54. The extra argument <[reent]> is a pointer to a reentrancy structure.
  55.  
  56. @c FIXME: do we have setjmp.h and assoc fns?
  57.  
  58. RETURNS
  59. If your request for a signal handler cannot be honored, the result is
  60. <<SIG_ERR>>; a specific error number is also recorded in <<errno>>.
  61.  
  62. Otherwise, the result is the previous handler (a function pointer or
  63. one of the predefined macros).
  64.  
  65. PORTABILITY
  66. ANSI C requires <<signal>>.
  67.  
  68. No supporting OS subroutines are required to link with <<signal>>, but
  69. it will not have any useful effects, except for software generated signals,
  70. without an operating system that can actually raise exceptions.
  71. */
  72.  
  73. /*
  74.  * signal.c
  75.  * Original Author:     G. Haley
  76.  *
  77.  * signal associates the function pointed to by func with the signal sig. When
  78.  * a signal occurs, the value of func determines the action taken as follows:
  79.  * if func is SIG_DFL, the default handling for that signal will occur; if func
  80.  * is SIG_IGN, the signal will be ignored; otherwise, the default handling for
  81.  * the signal is restored (SIG_DFL), and the function func is called with sig
  82.  * as its argument. Returns the value of func for the previous call to signal
  83.  * for the signal sig, or SIG_ERR if the request fails.
  84.  */
  85.  
  86. /* _init_signal initialises the signal handlers for each signal. This function
  87.    is called by crt0 at program startup.  */
  88.  
  89. #ifdef SIGNAL_PROVIDED
  90.  
  91. int _dummy_simulated_signal;
  92.  
  93. #else
  94.  
  95. #include <errno.h>
  96. #include <signal.h>
  97. #include <stddef.h>
  98. #include <stdlib.h>
  99. #include <reent.h>
  100. #include <_syslist.h>
  101.  
  102. int
  103. _DEFUN (_init_signal_r, (ptr),
  104.         struct _reent *ptr)
  105. {
  106.   int i;
  107.  
  108.   if (ptr->_sig_func == NULL)
  109.     {
  110.       ptr->_sig_func = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG);
  111.       if (ptr->_sig_func == NULL)
  112.         return -1;
  113.  
  114.       for (i = 0; i < NSIG; i++)
  115.         ptr->_sig_func[i] = SIG_DFL;
  116.     }
  117.  
  118.   return 0;
  119. }
  120.  
  121. _sig_func_ptr
  122. _DEFUN (_signal_r, (ptr, sig, func),
  123.         struct _reent *ptr _AND
  124.         int sig _AND
  125.         _sig_func_ptr func)
  126. {
  127.   _sig_func_ptr old_func;
  128.  
  129.   if (sig < 0 || sig >= NSIG)
  130.     {
  131.       ptr->_errno = EINVAL;
  132.       return SIG_ERR;
  133.     }
  134.  
  135.   if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
  136.     return SIG_ERR;
  137.  
  138.   old_func = ptr->_sig_func[sig];
  139.   ptr->_sig_func[sig] = func;
  140.  
  141.   return old_func;
  142. }
  143.  
  144. int
  145. _DEFUN (_raise_r, (ptr, sig),
  146.      struct _reent *ptr _AND
  147.      int sig)
  148. {
  149.   _sig_func_ptr func;
  150.  
  151.   if (sig < 0 || sig >= NSIG)
  152.     {
  153.       ptr->_errno = EINVAL;
  154.       return -1;
  155.     }
  156.  
  157.   if (ptr->_sig_func == NULL)
  158.     func = SIG_DFL;
  159.   else
  160.     func = ptr->_sig_func[sig];
  161.  
  162.   if (func == SIG_DFL)
  163.     return _kill_r (ptr, _getpid_r (ptr), sig);
  164.   else if (func == SIG_IGN)
  165.     return 0;
  166.   else if (func == SIG_ERR)
  167.     {
  168.       ptr->_errno = EINVAL;
  169.       return 1;
  170.     }
  171.   else
  172.     {
  173.       ptr->_sig_func[sig] = SIG_DFL;
  174.       func (sig);
  175.       return 0;
  176.     }
  177. }
  178.  
  179. int
  180. _DEFUN (__sigtramp_r, (ptr, sig),
  181.      struct _reent *ptr _AND
  182.      int sig)
  183. {
  184.   _sig_func_ptr func;
  185.  
  186.   if (sig < 0 || sig >= NSIG)
  187.     {
  188.       return -1;
  189.     }
  190.  
  191.   if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
  192.     return -1;
  193.  
  194.   func = ptr->_sig_func[sig];
  195.   if (func == SIG_DFL)
  196.     return 1;
  197.   else if (func == SIG_ERR)
  198.     return 2;
  199.   else if (func == SIG_IGN)
  200.     return 3;
  201.   else
  202.     {
  203.       ptr->_sig_func[sig] = SIG_DFL;
  204.       func (sig);
  205.       return 0;
  206.     }
  207. }
  208.  
  209.  
  210. int _DEFUN (_kill_r, (ptr, pid, sig),
  211.      struct _reent *ptr _AND
  212.      int pid _AND
  213.      int sig)
  214. {
  215. //  int ret;
  216.  
  217. //  errno = 0;
  218. //  if ((ret = _kill (pid, sig)) == -1 && errno != 0)
  219. //    ptr->_errno = errno;
  220. //  return ret;
  221.  
  222. /* sorry, guys */
  223.  
  224.   ptr->_errno = EPERM;
  225.   return -1;
  226. }
  227.  
  228.  
  229. #ifndef _REENT_ONLY
  230.  
  231. int
  232. _DEFUN (raise, (sig),
  233.      int sig)
  234. {
  235.   return _raise_r (_REENT, sig);
  236. }
  237.  
  238. _sig_func_ptr
  239. _DEFUN (signal, (sig, func),
  240.         int sig _AND
  241.         _sig_func_ptr func)
  242. {
  243.   return _signal_r (_REENT, sig, func);
  244. }
  245.  
  246. int
  247. _DEFUN_VOID (_init_signal)
  248. {
  249.   return _init_signal_r (_REENT);
  250. }
  251.  
  252. int
  253. _DEFUN (__sigtramp, (sig), int sig)
  254. {
  255.   return __sigtramp_r (_REENT, sig);
  256. }
  257.  
  258. #endif
  259.  
  260. #endif /* !SIGNAL_PROVIDED */
  261.