/* Test of correct simulation for active stack. */
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <ucontext.h>
static char altstack_map[8096];
static volatile stack_t *sp;
static void sighandler(int sig)
{
/* Check that the alternate stack is active. */
assert(sp->ss_sp == altstack_map);
assert(sp->ss_size == sizeof(altstack_map));
assert(sp->ss_flags == SS_ONSTACK);
}
int main(void)
{
stack_t mainstack;
stack_t altstack;
struct sigaction sa;
/* Obtain an address inside the stack using a dirty trick. */
void *local = &sa;
/* Get an address for stack definition. */
if (getustack((stack_t**)&sp)) {
perror("getustack");
return 1;
}
/* Check the current stack. */
assert(sp->ss_sp <= local);
assert(local < (void*)((char*)sp->ss_sp + sp->ss_size));
assert(sp->ss_flags == 0);
/* Backup the current stack. */
mainstack = *sp;
/* Setup a signal handler. */
sa.sa_handler = sighandler;
sa.sa_flags = SA_ONSTACK;
if (sigfillset(&sa.sa_mask)) {
perror("sigfillset");
return 1;
}
if (sigaction(SIGUSR1, &sa, NULL)) {
perror("sigaction");
return 1;
}
/* Setup an alternate stack. */
altstack.ss_sp = altstack_map;
altstack.ss_size = sizeof(altstack_map);
altstack.ss_flags = 0;
if (sigaltstack(&altstack, NULL)) {
perror("sigaltstack");
return 1;
}
/* Raise a signal. */
raise(SIGUSR1);
/* Check the current stack. */
assert(mainstack.ss_sp == sp->ss_sp);
assert(mainstack.ss_size == sp->ss_size);
assert(mainstack.ss_flags == sp->ss_flags);
return 0;
}