diff options
author | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-12-20 16:34:35 -0500 |
---|---|---|
committer | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-12-20 16:34:35 -0500 |
commit | 48ef7704c03e7e554c05de01bf8d1d70c16cb6f4 (patch) | |
tree | 34d52513de6c903b4f52ef87d885c73472daf469 /libc/signal | |
parent | f49e7cbb33e6e27b0ce5eb35244d7241c800a7c1 (diff) |
add libc building to agbcc.
Diffstat (limited to 'libc/signal')
-rw-r--r-- | libc/signal/raise.c | 80 | ||||
-rw-r--r-- | libc/signal/signal.c | 269 |
2 files changed, 349 insertions, 0 deletions
diff --git a/libc/signal/raise.c b/libc/signal/raise.c new file mode 100644 index 0000000..bc47864 --- /dev/null +++ b/libc/signal/raise.c @@ -0,0 +1,80 @@ +/* Embedded systems may want the simulated signals if no other form exists, + but UNIX versions will want to use the host facilities. + Define SIMULATED_SIGNALS when you want to use the simulated versions. +*/ + +/* +FUNCTION +<<raise>>---send a signal + +INDEX + raise +INDEX + _raise_r + +ANSI_SYNOPSIS + #include <signal.h> + int raise(int <[sig]>); + + int _raise_r(void *<[reent]>, int <[sig]>); + +TRAD_SYNOPSIS + #include <signal.h> + int raise(<[sig]>) + int <[sig]>; + + int _raise_r(<[reent]>, <[sig]>) + char *<[reent]>; + int <[sig]>; + +DESCRIPTION +Send the signal <[sig]> (one of the macros from `<<sys/signal.h>>'). +This interrupts your program's normal flow of execution, and allows a signal +handler (if you've defined one, using <<signal>>) to take control. + +The alternate function <<_raise_r>> is a reentrant version. The extra +argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS +The result is <<0>> if <[sig]> was successfully raised, <<1>> +otherwise. However, the return value (since it depends on the normal +flow of execution) may not be visible, unless the signal handler for +<[sig]> terminates with a <<return>> or unless <<SIG_IGN>> is in +effect for this signal. + +PORTABILITY +ANSI C requires <<raise>>, but allows the full set of signal numbers +to vary from one implementation to another. + +Required OS subroutines: <<getpid>>, <<kill>>. +*/ + +#ifndef SIGNAL_PROVIDED + +int _dummy_raise; + +#else + +#include <reent.h> +#include <signal.h> + +#ifndef _REENT_ONLY + +int +_DEFUN (raise, (sig), + int sig) +{ + return _raise_r (_REENT, sig); +} + +#endif + +int +_DEFUN (_raise_r, (reent, sig), + struct _reent *reent _AND + int sig) +{ + return _kill_r (reent, _getpid_r (reent), sig); +} + +#endif /* SIGNAL_PROVIDED */ diff --git a/libc/signal/signal.c b/libc/signal/signal.c new file mode 100644 index 0000000..fc52bba --- /dev/null +++ b/libc/signal/signal.c @@ -0,0 +1,269 @@ +/* +FUNCTION +<<signal>>---specify handler subroutine for a signal + +INDEX + signal +INDEX + _signal_r +INDEX + raise +INDEX + _raise_r + +ANSI_SYNOPSIS + #include <signal.h> + void ( * signal(int <[sig]>, void(*<[func]>)(int)) )(int); + + void ( * _signal_r(void *<[reent]>, + int <[sig]>, void(*<[func]>)(int)) )(int); + + int raise (int <[sig]>); + + int _raise_r (void *<[reent]>, int <[sig]>); + +TRAD_SYNOPSIS + #include <signal.h> + char ( * signal(<[sig]>, <[func]>) )() + int <[sig]>; + char ( * <[func]> )(); + + char ( * _signal_r(<[reent]>, <[sig]>, <[func]>) )() + char *<[reent]>; + int <[sig]>; + char ( * <[func]> )(); + + int raise (<[sig]>)() + int <[sig]>; + + int _raise_r (<[reent]>, <[sig]>)() + char *<[reent]>; + int <[sig]>; + +DESCRIPTION +<<signal, raise>> provide a simple signal/raise implementation for embedded +targets. + +<<signal>> allows you to request changed treatment for a particular +signal <[sig]>. You can use one of the predefined macros <<SIG_DFL>> +(select system default handling) or <<SIG_IGN>> (ignore this signal) +as the value of <[func]>; otherwise, <[func]> is a function pointer +that identifies a subroutine in your program as the handler for this signal. + +Some of the execution environment for signal handlers is +unpredictable; notably, the only library function required to work +correctly from within a signal handler is @code{signal} itself, and +only when used to redefine the handler for the current signal value. + +Static storage is likewise unreliable for signal handlers, with one +exception: if you declare a static storage location as `<<volatile +sig_atomic_t>>', then you may use that location in a signal handler to +store signal values. + +If your signal handler terminates using <<return>> (or implicit +return), your program's execution continues at the point +where it was when the signal was raised (whether by your program +itself, or by an external event). Signal handlers can also +use functions such as <<exit>> and <<abort>> to avoid returning. + +<<raise>> sends the signal sig to the executing program. It returns zero if +successful, non-zero if unsuccessful. + +The alternate functions <<_signal_r, _raise_r>> are the reentrant versions. +The extra argument <[reent]> is a pointer to a reentrancy structure. + + +@c FIXME: do we have setjmp.h and assoc fns? + +RETURNS +If your request for a signal handler cannot be honored, the result is +<<SIG_ERR>>; a specific error number is also recorded in <<errno>>. + +Otherwise, the result is the previous handler (a function pointer or +one of the predefined macros). + +PORTABILITY +ANSI C requires <<raise>>, <<signal>>. + +No supporting OS subroutines are required to link with <<signal>>, but +it will not have any useful effects, except for software generated signals, +without an operating system that can actually raise exceptions. +*/ + +/* + * signal.c + * Original Author: G. Haley + * + * signal associates the function pointed to by func with the signal sig. When + * a signal occurs, the value of func determines the action taken as follows: + * if func is SIG_DFL, the default handling for that signal will occur; if func + * is SIG_IGN, the signal will be ignored; otherwise, the default handling for + * the signal is restored (SIG_DFL), and the function func is called with sig + * as its argument. Returns the value of func for the previous call to signal + * for the signal sig, or SIG_ERR if the request fails. + */ + +/* _init_signal initialises the signal handlers for each signal. This function + is called by crt0 at program startup. */ + +#ifdef SIGNAL_PROVIDED + +int _dummy_simulated_signal; + +#else + +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <stdlib.h> +#include <reent.h> +#include <_syslist.h> + +int +_DEFUN (_init_signal_r, (ptr), + struct _reent *ptr) +{ + int i; + + if (ptr->_sig_func == NULL) + { + ptr->_sig_func = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG); + if (ptr->_sig_func == NULL) + return -1; + + for (i = 0; i < NSIG; i++) + ptr->_sig_func[i] = SIG_DFL; + } + + return 0; +} + +_sig_func_ptr +_DEFUN (_signal_r, (ptr, sig, func), + struct _reent *ptr _AND + int sig _AND + _sig_func_ptr func) +{ + _sig_func_ptr old_func, *temp; + + if (sig < 0 || sig >= NSIG) + { + ptr->_errno = EINVAL; + return SIG_ERR; + } + + if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0) + return SIG_ERR; + + old_func = ptr->_sig_func[sig]; + ptr->_sig_func[sig] = func; + + return old_func; +} + +int +_raise_r (ptr, sig) + struct _reent *ptr; + int sig; +{ + _sig_func_ptr func; + int result = 0; + + if (sig < 0 || sig >= NSIG) + { + ptr->_errno = EINVAL; + return -1; + } + + if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0) + return -1; + + switch ((_POINTER_INT) ptr->_sig_func[sig]) + { + case SIG_DFL: + return _kill_r (ptr, _getpid_r (ptr), sig); + + case SIG_IGN: + break; + + case SIG_ERR: + ptr->_errno = EINVAL; + result = 1; + break; + + default: + func = ptr->_sig_func[sig]; + ptr->_sig_func[sig] = SIG_DFL; + func (sig); + break; + } + + return result; +} + +int +__sigtramp_r (ptr, sig) + struct _reent *ptr; + int sig; +{ + _sig_func_ptr func; + + if (sig < 0 || sig >= NSIG) + { + return -1; + } + + if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0) + return -1; + + switch ((_POINTER_INT) ptr->_sig_func[sig]) + { + case SIG_DFL: + return 1; + + case SIG_ERR: + return 2; + + case SIG_IGN: + return 3; + + default: + func = ptr->_sig_func[sig]; + ptr->_sig_func[sig] = SIG_DFL; + func (sig); + return 0; + } +} + +#ifndef _REENT_ONLY + +int +raise (sig) + int sig; +{ + return _raise_r (_REENT, sig); +} + +_sig_func_ptr +_DEFUN (signal, (sig, func), + int sig _AND + _sig_func_ptr func) +{ + return _signal_r (_REENT, sig, func); +} + +int +_init_signal () +{ + return _init_signal_r (_REENT); +} + +int +__sigtramp (int sig) +{ + return __sigtramp_r (_REENT, sig); +} + +#endif + +#endif /* !SIGNAL_PROVIDED */ |