diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2001-12-17 02:36:01 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2001-12-17 02:36:01 +0000 |
commit | db612c31eaea51b5134b19e147280173de6e12ab (patch) | |
tree | cdfab831261dfe8690860b3ee27e5f548530b694 /regress/lib/libc | |
parent | eb940cb3b8cab72c5de6adfd3de13bcaa92491a6 (diff) |
sigreturn test program
Diffstat (limited to 'regress/lib/libc')
-rw-r--r-- | regress/lib/libc/sigreturn/Makefile | 16 | ||||
-rw-r--r-- | regress/lib/libc/sigreturn/sigret.c | 168 |
2 files changed, 184 insertions, 0 deletions
diff --git a/regress/lib/libc/sigreturn/Makefile b/regress/lib/libc/sigreturn/Makefile new file mode 100644 index 00000000000..6a40c40fe0c --- /dev/null +++ b/regress/lib/libc/sigreturn/Makefile @@ -0,0 +1,16 @@ +# $OpenBSD: Makefile,v 1.1 2001/12/17 02:36:00 marc Exp $ + +PROG= sigret +SRCS= sigret.c +NOMAN= noman + +DEBUG+= -ggdb + +.PATH: ${.CURDIR}/../sigret + +install: + +regress: ${PROG} + ./${PROG} + +.include <bsd.prog.mk> diff --git a/regress/lib/libc/sigreturn/sigret.c b/regress/lib/libc/sigreturn/sigret.c new file mode 100644 index 00000000000..bd661a3649c --- /dev/null +++ b/regress/lib/libc/sigreturn/sigret.c @@ -0,0 +1,168 @@ +/* + * Playing games with sigreturn. Check if calling sigreturn from a + * signal handler screws anything up. + * + * Run with: + * -a: use an alternate signal stack + * + * -b: call sigreturn from outside of a signal handler + * An error is OK + * + * -c: clobber the sigcontext before calling sigreturn + * the program should die + * + * -f: don't use sigreturn -- fall through the signal handler + * -c, and -i options ignored when used + * + * -i: call sigreturn from a function called by the signal handler + * + * Program should not exit until killed. + */ + +#include <sys/time.h> + +#include <err.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int altstack; +int badcall; +int clobbercall; +int fallthru; +int indirect; + +volatile int count; +struct sigcontext gscp; +int gscp_loaded; + +static void +usage(const char * err, ...) +{ + extern const char * __progname; + + if (err) { + va_list ap; + va_start(ap, err); + vwarnx(err, ap); + va_end(ap); + } + fprintf(stderr, "usage: %s [-abcfi]\n", __progname); + exit(1); +} + +void +indirect_return(struct sigcontext * scp) +{ + sigreturn(scp); +} + +void +sig_handler(int sig, siginfo_t *blah, void *x) +{ + struct sigcontext * scp = x; + + count++; + + if (!fallthru) { + if (clobbercall) + memset(scp, 0, sizeof *scp); + if (indirect) + indirect_return(scp); + else if (badcall) { + gscp = *scp; + gscp_loaded = 1; + } else + sigreturn(scp); + } +} + +void +test2(char *fmt) +{ + char *ofmt = fmt; + + if (gscp_loaded) { + gscp_loaded = 0; + sigreturn(&gscp); + } + + for (; *fmt; fmt++) + switch (*fmt) { + case 'i': + case 'c': + case 'l': + case 'p': + break; + default: + fprintf(stderr, + "unexpected character 0x%02x `%c' in %s: count %d\n", + *fmt, *fmt, ofmt, count); + } +} + +int +main(int argc, char * argv[]) +{ + extern char *optarg; + extern int optind; + + int opt; + + struct sigaction act; + struct sigaltstack ss; + + while ((opt = getopt(argc, argv, "abcfi")) != -1) { + switch (opt) { + case 'a': + /* use sigaltstack */ + altstack = 1; + break; + case 'b': + /* call outside of sig_handler */ + badcall = 1; + break; + case 'c': + /* force error by munging sigcontext */ + clobbercall = 1; + break; + case 'f': + /* don't use sigreturn */ + fallthru = 1; + break; + case 'i': + /* call sigreturn indirectly */ + indirect = 1; + break; + } + } + + /* make sure there is no other cruft left on the command line */ + if (optind != argc) + usage("unknown arguement -- %s", argv[ optind ]); + + if (altstack) { + if ((ss.ss_sp = malloc(SIGSTKSZ)) == NULL) + errx(1, "ss_sp malloc"); + + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss,0) == -1) + err(1, "sigaltstack"); + } + + sigfillset(&act.sa_mask); + act.sa_sigaction = sig_handler; + act.sa_flags = SA_RESTART; + if (altstack) + act.sa_flags |= SA_ONSTACK; + sigaction(SIGALRM, &act, NULL); + + ualarm(10000, 10000); + + while (1) + test2("iclp"); +} |