diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2008-01-27 11:37:44 +0100 |
---|---|---|
committer | Tobias Klauser <tklauser@xenon.tklauser.home> | 2008-01-27 11:37:44 +0100 |
commit | 7e0f021a9aec35fd8e6725e87e3313b101d26f5e (patch) | |
tree | b1cacc4b24393f517aeb4610e9e1021f954307a8 /reference/C/CONTRIB/OR_USING_C/08.7.c |
Initial import (2.0.2-6)2.0.2-6
Diffstat (limited to 'reference/C/CONTRIB/OR_USING_C/08.7.c')
-rw-r--r-- | reference/C/CONTRIB/OR_USING_C/08.7.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/OR_USING_C/08.7.c b/reference/C/CONTRIB/OR_USING_C/08.7.c new file mode 100644 index 0000000..5518c96 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.7.c @@ -0,0 +1,108 @@ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <signal.h> +#include <stdio.h> + +char *stack; /* pointer to signal stack base */ +int tooksig = 0; /* 1 after we take the signal */ + +main() +{ + extern void x(); + struct sigvec sv; + struct sigstack ss; + struct rlimit rlimit; + + /* + * Set stack size limit to 50 kbytes. + */ + getrlimit(RLIMIT_STACK, &rlimit); + rlimit.rlim_cur = 50 * 1024; + + if (setrlimit(RLIMIT_STACK, &rlimit) < 0) { + perror("setrlimit"); + exit(1); + } + + /* + * Take illegal instruction and process it with x, + * on the interrupt stack. For 4.2BSD, change + * sv_flags to sv_onstack and SV_ONSTACK to 1. + */ + sv.sv_mask = 0; + sv.sv_handler = x; + sv.sv_flags = SV_ONSTACK; + sigvec(SIGILL, &sv, (struct sigvec *) 0); + + /* + * Allocate memory for the signal stack. The + * kernel assumes the addresses grow in the same + * direction as on the process stack (toward + * lower addresses, on a VAX). + */ + if ((stack = (char *) malloc(10240)) == NULL) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + /* + * Issue the call to tell the system about the + * signal stack. We pass the end of the signal + * stack, not the beginning, since the stack + * grows toward lower addresses. + */ + ss.ss_onstack = 0; + ss.ss_sp = (caddr_t) stack + 10240; + + if (sigstack(&ss, (struct sigstack *) 0) < 0) { + perror("sigstack"); + exit(1); + } + + /* + * Start using up stack space. + */ + y(); +} + +y() +{ + /* + * Take up 5k of stack space. + */ + char buf[5120]; + + printf("%s\n", tooksig ? "Now on extended stack." : + "On 50k stack."); + + /* + * Recurse. + */ + y(); +} + +/* + * Handle the signal. + */ +void x(sig, code, scp) +int sig, code; +struct sigcontext *scp; +{ + struct rlimit rlimit; + + /* + * Increase the stack limit to the maximum. + */ + getrlimit(RLIMIT_STACK, &rlimit); + rlimit.rlim_cur = rlimit.rlim_max; + + if (setrlimit(RLIMIT_STACK, &rlimit) < 0) { + perror("setrlimit"); + exit(1); + } + + tooksig = 1; + return; +} + |