diff options
Diffstat (limited to 'newlib/libc/signal')
-rw-r--r-- | newlib/libc/signal/Makefile.am | 26 | ||||
-rw-r--r-- | newlib/libc/signal/Makefile.in | 297 | ||||
-rw-r--r-- | newlib/libc/signal/raise.c | 80 | ||||
-rw-r--r-- | newlib/libc/signal/signal.c | 269 | ||||
-rw-r--r-- | newlib/libc/signal/signal.tex | 70 |
5 files changed, 742 insertions, 0 deletions
diff --git a/newlib/libc/signal/Makefile.am b/newlib/libc/signal/Makefile.am new file mode 100644 index 0000000..038948b --- /dev/null +++ b/newlib/libc/signal/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = raise.c signal.c + +CHEWOUT_FILES = raise.def signal.def + +SUFFIXES = .def + +CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str + +.c.def: + $(CHEW) < $< > $*.def 2> $*.ref + touch stmp-def + +TARGETDOC = ../tmp.texi + +doc: $(CHEWOUT_FILES) + cat $(srcdir)/signal.tex >> $(TARGETDOC) + +CLEANFILES = $(CHEWOUT_FILES) *.ref diff --git a/newlib/libc/signal/Makefile.in b/newlib/libc/signal/Makefile.in new file mode 100644 index 0000000..9d2cb1e --- /dev/null +++ b/newlib/libc/signal/Makefile.in @@ -0,0 +1,297 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +CRT0 = @CRT0@ +EXEEXT = @EXEEXT@ +LIBC_MACHINE_LIB = @LIBC_MACHINE_LIB@ +LIBC_POSIX_LIB = @LIBC_POSIX_LIB@ +LIBC_SIGNAL_DEF = @LIBC_SIGNAL_DEF@ +LIBC_SIGNAL_LIB = @LIBC_SIGNAL_LIB@ +LIBC_SYSCALL_LIB = @LIBC_SYSCALL_LIB@ +LIBC_SYS_LIB = @LIBC_SYS_LIB@ +LIBC_UNIX_LIB = @LIBC_UNIX_LIB@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +machine_dir = @machine_dir@ +newlib_basedir = @newlib_basedir@ +sys_dir = @sys_dir@ + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = raise.c signal.c + +CHEWOUT_FILES = raise.def signal.def + +SUFFIXES = .def + +CHEW = ../../doc/makedoc -f $(srcdir)/../../doc/doc.str + +TARGETDOC = ../tmp.texi + +CLEANFILES = $(CHEWOUT_FILES) *.ref +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +lib_a_LIBADD = +lib_a_OBJECTS = raise.o signal.o +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(lib_a_SOURCES) +OBJECTS = $(lib_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .def .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus signal/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) + -rm -f lib.a + $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) + $(RANLIB) lib.a + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = signal + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: +check: check-am +installcheck-am: +installcheck: installcheck-am +install-info-am: +install-info: install-info-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-info-am install-info \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +.c.def: + $(CHEW) < $< > $*.def 2> $*.ref + touch stmp-def + +doc: $(CHEWOUT_FILES) + cat $(srcdir)/signal.tex >> $(TARGETDOC) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/signal/raise.c b/newlib/libc/signal/raise.c new file mode 100644 index 0000000..bc47864 --- /dev/null +++ b/newlib/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/newlib/libc/signal/signal.c b/newlib/libc/signal/signal.c new file mode 100644 index 0000000..fc52bba --- /dev/null +++ b/newlib/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 */ diff --git a/newlib/libc/signal/signal.tex b/newlib/libc/signal/signal.tex new file mode 100644 index 0000000..08c15be --- /dev/null +++ b/newlib/libc/signal/signal.tex @@ -0,0 +1,70 @@ +@node Signals +@chapter Signal Handling (@file{signal.h}) + +A @dfn{signal} is an event that interrupts the normal flow of control +in your program. Your operating environment normally defines the full +set of signals available (see @file{sys/signal.h}), as well as the +default means of dealing with them---typically, either printing an +error message and aborting your program, or ignoring the signal. + +All systems support at least the following signals: +@table @code +@item SIGABRT +Abnormal termination of a program; raised by the <<abort>> function. + +@item SIGFPE +A domain error in arithmetic, such as overflow, or division by zero. + +@item SIGILL +Attempt to execute as a function data that is not executable. + +@item SIGINT +Interrupt; an interactive attention signal. + +@item SIGSEGV +An attempt to access a memory location that is not available. + +@item SIGTERM +A request that your program end execution. +@end table + +Two functions are available for dealing with asynchronous +signals---one to allow your program to send signals to itself (this is +called @dfn{raising} a signal), and one to specify subroutines (called +@dfn{handlers} to handle particular signals that you anticipate may +occur---whether raised by your own program or the operating environment. + +To support these functions, @file{signal.h} defines three macros: + +@table @code +@item SIG_DFL +Used with the @code{signal} function in place of a pointer to a +handler subroutine, to select the operating environment's default +handling of a signal. + +@item SIG_IGN +Used with the @code{signal} function in place of a pointer to a +handler, to ignore a particular signal. + +@item SIG_ERR +Returned by the @code{signal} function in place of a pointer to a +handler, to indicate that your request to set up a handler could not +be honored for some reason. +@end table + +@file{signal.h} also defines an integral type, @code{sig_atomic_t}. +This type is not used in any function declarations; it exists only to +allow your signal handlers to declare a static storage location where +they may store a signal value. (Static storage is not otherwise +reliable from signal handlers.) + +@menu +* raise:: Send a signal +* signal:: Specify handler subroutine for a signal +@end menu + +@page +@include signal/raise.def + +@page +@include signal/signal.def |