summaryrefslogtreecommitdiff
path: root/libc/signal
diff options
context:
space:
mode:
authorProjectRevoTPP <projectrevotpp@hotmail.com>2017-12-20 16:34:35 -0500
committerProjectRevoTPP <projectrevotpp@hotmail.com>2017-12-20 16:34:35 -0500
commit48ef7704c03e7e554c05de01bf8d1d70c16cb6f4 (patch)
tree34d52513de6c903b4f52ef87d885c73472daf469 /libc/signal
parentf49e7cbb33e6e27b0ce5eb35244d7241c800a7c1 (diff)
add libc building to agbcc.
Diffstat (limited to 'libc/signal')
-rw-r--r--libc/signal/raise.c80
-rw-r--r--libc/signal/signal.c269
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 */