+++ /dev/null
-/* $Id$ */
-
-/* Signal handling <string.h>
-
- This file is part of the Public Domain C Library (PDCLib).
- Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-#ifndef _PDCLIB_SIGNAL_H
-#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H
-
-#ifndef _PDCLIB_CONFIG_H
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
-#include <_PDCLIB_config.h>
-#endif
-
-typedef _PDCLIB_sig_atomic sig_atomic_t;
-
-#define SIG_DFL _PDCLIB_SIG_DFL
-#define SIG_ERR _PDCLIB_SIG_ERR
-#define SIG_IGN _PDCLIB_SIG_IGN
-
-#define SIGABRT _PDCLIB_SIGABRT
-#define SIGFPE _PDCLIB_SIGFPE
-#define SIGILL _PDCLIB_SIGILL
-#define SIGINT _PDCLIB_SIGINT
-#define SIGSEGV _PDCLIB_SIGSEGV
-#define SIGTERM _PDCLIB_SIGTERM
-
-/* Returns the value of func for the most recent successful call to signal()
- for the signal sig. Returns SIG_ERR and sets errno to a positive value
- otherwise.
-*/
-void (*signal( int sig, void (*func)( int ) ) )( int );
-
-/* Returns zero if successful, nonzero otherwise. */
-int raise( int sig );
-
-#endif
#ifndef REGTEST
+#include <stdlib.h>
+
extern void (*_PDCLIB_sigabrt)( int );
extern void (*_PDCLIB_sigfpe)( int );
extern void (*_PDCLIB_sigill)( int );
int raise( int sig )
{
+ void (*sighandler)( int );
switch ( sig )
{
case SIGABRT:
- _PDCLIB_sigabrt( sig );
+ sighandler = _PDCLIB_sigabrt;
break;
case SIGFPE:
- _PDCLIB_sigfpe( sig );
+ sighandler = _PDCLIB_sigfpe;
break;
case SIGILL:
- _PDCLIB_sigill( sig );
+ sighandler = _PDCLIB_sigill;
break;
case SIGINT:
- _PDCLIB_sigint( sig );
+ sighandler = _PDCLIB_sigint;
break;
case SIGSEGV:
- _PDCLIB_sigsegv( sig );
+ sighandler = _PDCLIB_sigsegv;
break;
case SIGTERM:
- _PDCLIB_sigterm( sig );
+ sighandler = _PDCLIB_sigterm;
break;
default:
/* TODO: Implement. */
break;
}
- /* TODO: Implement. */
+ if ( sighandler == SIG_DFL )
+ {
+ _Exit( EXIT_FAILURE );
+ }
+ else if ( sighandler != SIG_IGN )
+ {
+ sighandler = signal( sig, SIG_DFL );
+ sighandler( sig );
+ }
return 0;
}
#include <stdlib.h>
-static void default_handler( int sig )
-{
- /* TODO: Implement error message */
- exit( EXIT_FAILURE );
-}
-
-void (*_PDCLIB_sigabrt)( int ) = default_handler;
-void (*_PDCLIB_sigfpe)( int ) = default_handler;
-void (*_PDCLIB_sigill)( int ) = default_handler;
-void (*_PDCLIB_sigint)( int ) = default_handler;
-void (*_PDCLIB_sigsegv)( int ) = default_handler;
-void (*_PDCLIB_sigterm)( int ) = default_handler;
+void (*_PDCLIB_sigabrt)( int ) = SIG_DFL;
+void (*_PDCLIB_sigfpe)( int ) = SIG_DFL;
+void (*_PDCLIB_sigill)( int ) = SIG_DFL;
+void (*_PDCLIB_sigint)( int ) = SIG_DFL;
+void (*_PDCLIB_sigsegv)( int ) = SIG_DFL;
+void (*_PDCLIB_sigterm)( int ) = SIG_DFL;
void (*signal( int sig, void (*func)( int ) ) )( int )
{
_PDCLIB_sigterm = func;
break;
default:
- /* TODO: Implement. */
- break;
+ /* The standard calls for an unspecified "positive value". You
+ will probably want to define a specific value for this.
+ */
+ _PDCLIB_errno = 1;
+ return SIG_ERR;
}
return oldhandler;
}
--- /dev/null
+/* $Id$ */
+
+/* Signal handling <string.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_SIGNAL_H
+#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H
+
+#ifndef _PDCLIB_CONFIG_H
+#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
+#include <_PDCLIB_config.h>
+#endif
+
+/* Signals ------------------------------------------------------------------ */
+
+/* A word on signals, to the people using PDCLib in their OS projects.
+
+ The definitions of the C standard leave about everything that *could* be
+ useful to be "implementation defined". Without additional, non-standard
+ arrangements, it is not possible to turn them into a useful tool.
+
+ This example implementation chose to "not generate any of these signals,
+ except as a result of explicit calls to the raise function", which is
+ allowed by the standard but of course does nothing for the usefulness of
+ <signal.h>.
+
+ A useful signal handling would:
+ 1) make signal() a system call that registers the signal handler with the OS
+ 2) make raise() a system call triggering an OS signal to the running process
+ 3) make provisions that further signals of the same type are blocked until
+ the signal handler returns (optional for SIGILL)
+*/
+
+/* These are the values used by Linux. */
+
+/* Abnormal termination / abort() */
+#define SIGABRT 6
+/* Arithmetic exception / division by zero / overflow */
+#define SIGFPE 8
+/* Illegal instruction */
+#define SIGILL 4
+/* Interactive attention signal */
+#define SIGINT 2
+/* Invalid memory access */
+#define SIGSEGV 11
+/* Termination request */
+#define SIGTERM 15
+
+/* The following should be defined to pointer values that could NEVER point to
+ a valid signal handler function. (They are used as special arguments to
+ signal().) Again, these are the values used by Linux.
+*/
+#define SIG_DFL (void (*)( int ))0
+#define SIG_ERR (void (*)( int ))-1
+#define SIG_IGN (void (*)( int ))1
+
+typedef _PDCLIB_sig_atomic sig_atomic_t;
+
+/* Installs a signal handler "func" for the given signal.
+ A signal handler is a function that takes an integer as argument (the signal
+ number) and returns void.
+
+ Note that a signal handler can do very little else than:
+ 1) assign a value to a static object of type "volatile sig_atomic_t",
+ 2) call signal() with the value of sig equal to the signal received,
+ 3) call _Exit(),
+ 4) call abort().
+ Virtually everything else is undefind.
+
+ The signal() function returns the previous installed signal handler, which
+ at program start may be SIG_DFL or SIG_ILL. (This implementation uses
+ SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is
+ returned and errno is set to an unspecified positive value.
+*/
+void (*signal( int sig, void (*func)( int ) ) )( int );
+
+/* Raises the given signal (executing the registered signal handler with the
+ given signal number as parameter).
+ This implementation does not prevent further signals of the same time from
+ occuring, but executes signal( sig, SIG_DFL ) before entering the signal
+ handler (i.e., a second signal before the signal handler re-registers itself
+ or SIG_IGN will end the program).
+ Returns zero if successful, nonzero otherwise. */
+int raise( int sig );
+
+#endif
+
this capability dependent on implementation-defined behaviour (not good).
*/
#define _PDCLIB_UNGETCBUFSIZE 1
-
-/* Signals ------------------------------------------------------------------ */
-
-/* A word on signals, to the people using PDCLib in their OS projects.
-
- The way they are defined by the C standard severely limits their usefulness,
- to the point where a library implementation need not interface with the OS'
- signals at all (which is what the PDCLib example implementation does).
- (Other issues include, for example, that signal handlers are not re-entrant.)
-
- Thus, it is strongly discouraged to try bolting on a signal handling infra-
- structure onto <signal.h>. Since C's signal handling is so limited to begin
- with, and code using it is pretty much non-portable anyway, it would be
- smarter to keep <signal.h> in the barely functional state it is in, and
- instead create a better, OS-specific API.
-
- That being said, the below signals require to be defined to a positive int
- value. I took what my Linux box defined them to; if you have to change them,
- and what value to change them *to*, depends heavily on your environment and
- what you are expecting <signal.h> to accomplish (see above).
-*/
-#define _PDCLIB_SIGABRT 6
-#define _PDCLIB_SIGFPE 8
-#define _PDCLIB_SIGILL 4
-#define _PDCLIB_SIGINT 2
-#define _PDCLIB_SIGSEGV 11
-#define _PDCLIB_SIGTERM 15
-
-/* The following should be defined to pointer values that could NEVER point to
- a valid function. (They are used as special arguments to signal().) Again, I
- took the values of my Linux box, which should be as good as any other value.
-*/
-#define _PDCLIB_SIG_DFL (void (*)( int ))0
-#define _PDCLIB_SIG_ERR (void (*)( int ))-1
-#define _PDCLIB_SIG_IGN (void (*)( int ))1
-
this capability dependent on implementation-defined behaviour (not good).
*/
#define _PDCLIB_UNGETCBUFSIZE 1
-
-/* Signals ------------------------------------------------------------------ */
-
-/* A word on signals, to the people using PDCLib in their OS projects.
-
- The way they are defined by the C standard severely limits their usefulness,
- to the point where a library implementation need not interface with the OS'
- signals at all (which is what the PDCLib example implementation does).
- (Other issues include, for example, that signal handlers are not re-entrant.)
-
- Thus, it is strongly discouraged to try bolting on a signal handling infra-
- structure onto <signal.h>. Since C's signal handling is so limited to begin
- with, and code using it is pretty much non-portable anyway, it would be
- smarter to keep <signal.h> in the barely functional state it is in, and
- instead create a better, OS-specific API.
-
- That being said, the below signals require to be defined to a positive int
- value. I took what my Linux box defined them to; if you have to change them,
- and what value to change them *to*, depends heavily on your environment and
- what you are expecting <signal.h> to accomplish (see above).
-*/
-#define _PDCLIB_SIGABRT 6
-#define _PDCLIB_SIGFPE 8
-#define _PDCLIB_SIGILL 4
-#define _PDCLIB_SIGINT 2
-#define _PDCLIB_SIGSEGV 11
-#define _PDCLIB_SIGTERM 15
-
-/* The following should be defined to pointer values that could NEVER point to
- a valid function. (They are used as special arguments to signal().) Again, I
- took the values of my Linux box, which should be as good as any other value.
-*/
-#define _PDCLIB_SIG_DFL (void (*)( int ))0
-#define _PDCLIB_SIG_ERR (void (*)( int ))-1
-#define _PDCLIB_SIG_IGN (void (*)( int ))1
-
--- /dev/null
+/* $Id$ */
+
+/* raise( int )
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <signal.h>
+
+#ifndef REGTEST
+
+#include <stdlib.h>
+
+extern void (*_PDCLIB_sigabrt)( int );
+extern void (*_PDCLIB_sigfpe)( int );
+extern void (*_PDCLIB_sigill)( int );
+extern void (*_PDCLIB_sigint)( int );
+extern void (*_PDCLIB_sigsegv)( int );
+extern void (*_PDCLIB_sigterm)( int );
+
+int raise( int sig )
+{
+ void (*sighandler)( int );
+ switch ( sig )
+ {
+ case SIGABRT:
+ sighandler = _PDCLIB_sigabrt;
+ break;
+ case SIGFPE:
+ sighandler = _PDCLIB_sigfpe;
+ break;
+ case SIGILL:
+ sighandler = _PDCLIB_sigill;
+ break;
+ case SIGINT:
+ sighandler = _PDCLIB_sigint;
+ break;
+ case SIGSEGV:
+ sighandler = _PDCLIB_sigsegv;
+ break;
+ case SIGTERM:
+ sighandler = _PDCLIB_sigterm;
+ break;
+ default:
+ /* TODO: Implement. */
+ break;
+ }
+ if ( sighandler == SIG_DFL )
+ {
+ _Exit( EXIT_FAILURE );
+ }
+ else if ( sighandler != SIG_IGN )
+ {
+ sighandler = signal( sig, SIG_DFL );
+ sighandler( sig );
+ }
+ return 0;
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+ TESTCASE( NO_TESTDRIVER );
+ return TEST_RESULTS;
+}
+#endif
--- /dev/null
+/* $Id$ */
+
+/* signal( int sig, void (*func)( int ) )
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <signal.h>
+
+#ifndef REGTEST
+
+#include <stdlib.h>
+
+void (*_PDCLIB_sigabrt)( int ) = SIG_DFL;
+void (*_PDCLIB_sigfpe)( int ) = SIG_DFL;
+void (*_PDCLIB_sigill)( int ) = SIG_DFL;
+void (*_PDCLIB_sigint)( int ) = SIG_DFL;
+void (*_PDCLIB_sigsegv)( int ) = SIG_DFL;
+void (*_PDCLIB_sigterm)( int ) = SIG_DFL;
+
+void (*signal( int sig, void (*func)( int ) ) )( int )
+{
+ void (*oldhandler)( int );
+ switch ( sig )
+ {
+ case SIGABRT:
+ oldhandler = _PDCLIB_sigabrt;
+ _PDCLIB_sigabrt = func;
+ break;
+ case SIGFPE:
+ oldhandler = _PDCLIB_sigfpe;
+ _PDCLIB_sigfpe = func;
+ break;
+ case SIGILL:
+ oldhandler = _PDCLIB_sigill;
+ _PDCLIB_sigill = func;
+ break;
+ case SIGINT:
+ oldhandler = _PDCLIB_sigint;
+ _PDCLIB_sigint = func;
+ break;
+ case SIGSEGV:
+ oldhandler = _PDCLIB_sigsegv;
+ _PDCLIB_sigsegv = func;
+ break;
+ case SIGTERM:
+ oldhandler = _PDCLIB_sigterm;
+ _PDCLIB_sigterm = func;
+ break;
+ default:
+ /* The standard calls for an unspecified "positive value". You
+ will probably want to define a specific value for this.
+ */
+ _PDCLIB_errno = 1;
+ return SIG_ERR;
+ }
+ return oldhandler;
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+ TESTCASE( NO_TESTDRIVER );
+ return TEST_RESULTS;
+}
+#endif
--- /dev/null
+/* $Id$ */
+
+/* Signal handling <string.h>
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_SIGNAL_H
+#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H
+
+#ifndef _PDCLIB_CONFIG_H
+#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
+#include <_PDCLIB_config.h>
+#endif
+
+/* Signals ------------------------------------------------------------------ */
+
+/* A word on signals, to the people using PDCLib in their OS projects.
+
+ The definitions of the C standard leave about everything that *could* be
+ useful to be "implementation defined". Without additional, non-standard
+ arrangements, it is not possible to turn them into a useful tool.
+
+ This example implementation chose to "not generate any of these signals,
+ except as a result of explicit calls to the raise function", which is
+ allowed by the standard but of course does nothing for the usefulness of
+ <signal.h>.
+
+ A useful signal handling would:
+ 1) make signal() a system call that registers the signal handler with the OS
+ 2) make raise() a system call triggering an OS signal to the running process
+ 3) make provisions that further signals of the same type are blocked until
+ the signal handler returns (optional for SIGILL)
+*/
+
+/* These are the values used by Linux. */
+
+/* Abnormal termination / abort() */
+#define SIGABRT 6
+/* Arithmetic exception / division by zero / overflow */
+#define SIGFPE 8
+/* Illegal instruction */
+#define SIGILL 4
+/* Interactive attention signal */
+#define SIGINT 2
+/* Invalid memory access */
+#define SIGSEGV 11
+/* Termination request */
+#define SIGTERM 15
+
+/* The following should be defined to pointer values that could NEVER point to
+ a valid signal handler function. (They are used as special arguments to
+ signal().) Again, these are the values used by Linux.
+*/
+#define SIG_DFL (void (*)( int ))0
+#define SIG_ERR (void (*)( int ))-1
+#define SIG_IGN (void (*)( int ))1
+
+typedef _PDCLIB_sig_atomic sig_atomic_t;
+
+/* Installs a signal handler "func" for the given signal.
+ A signal handler is a function that takes an integer as argument (the signal
+ number) and returns void.
+
+ Note that a signal handler can do very little else than:
+ 1) assign a value to a static object of type "volatile sig_atomic_t",
+ 2) call signal() with the value of sig equal to the signal received,
+ 3) call _Exit(),
+ 4) call abort().
+ Virtually everything else is undefind.
+
+ The signal() function returns the previous installed signal handler, which
+ at program start may be SIG_DFL or SIG_ILL. (This implementation uses
+ SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is
+ returned and errno is set to an unspecified positive value.
+*/
+void (*signal( int sig, void (*func)( int ) ) )( int );
+
+/* Raises the given signal (executing the registered signal handler with the
+ given signal number as parameter).
+ This implementation does not prevent further signals of the same time from
+ occuring, but executes signal( sig, SIG_DFL ) before entering the signal
+ handler (i.e., a second signal before the signal handler re-registers itself
+ or SIG_IGN will end the program).
+ Returns zero if successful, nonzero otherwise. */
+int raise( int sig );
+
+#endif
+
#define _PDCLIB_UNGETCBUFSIZE 1
typedef long wint_t;
-
-/* Signals ------------------------------------------------------------------ */
-
-/* A word on signals, to the people using PDCLib in their OS projects.
-
- The way they are defined by the C standard severely limits their usefulness,
- to the point where a library implementation need not interface with the OS'
- signals at all (which is what the PDCLib example implementation does).
- (Other issues include, for example, that signal handlers are not re-entrant.)
-
- Thus, it is strongly discouraged to try bolting on a signal handling infra-
- structure onto <signal.h>. Since C's signal handling is so limited to begin
- with, and code using it is pretty much non-portable anyway, it would be
- smarter to keep <signal.h> in the barely functional state it is in, and
- instead create a better, OS-specific API.
-
- That being said, the below signals require to be defined to a positive int
- value. I took what my Linux box defined them to; if you have to change them,
- and what value to change them *to*, depends heavily on your environment and
- what you are expecting <signal.h> to accomplish (see above).
-*/
-#define _PDCLIB_SIGABRT 6
-#define _PDCLIB_SIGFPE 8
-#define _PDCLIB_SIGILL 4
-#define _PDCLIB_SIGINT 2
-#define _PDCLIB_SIGSEGV 11
-#define _PDCLIB_SIGTERM 15
-
-/* The following should be defined to pointer values that could NEVER point to
- a valid function. (They are used as special arguments to signal().) Again, I
- took the values of my Linux box, which should be as good as any other value.
-*/
-#define _PDCLIB_SIG_DFL (void (*)( int ))0
-#define _PDCLIB_SIG_ERR (void (*)( int ))-1
-#define _PDCLIB_SIG_IGN (void (*)( int ))1
-