diff options
author | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-07-29 19:51:42 +0000 |
---|---|---|
committer | Daniel Hartmeier <dhartmei@cvs.openbsd.org> | 2002-07-29 19:51:42 +0000 |
commit | 865fdcdce92da25d834f892d6351e4cf1a54995d (patch) | |
tree | 2f29e70011b9812356891aacfc9c84466e4a93ca | |
parent | 56e564fd6a5feaceea08c7fa2464f763db39f887 (diff) |
Try to modify __atexit directly and see if our function gets called.
-rw-r--r-- | regress/lib/libc/atexit/Makefile | 12 | ||||
-rw-r--r-- | regress/lib/libc/atexit/atexit_test.c | 131 | ||||
-rw-r--r-- | regress/lib/libc/atexit/invalid.ok | 4 | ||||
-rw-r--r-- | regress/lib/libc/atexit/valid.ok | 5 |
4 files changed, 152 insertions, 0 deletions
diff --git a/regress/lib/libc/atexit/Makefile b/regress/lib/libc/atexit/Makefile new file mode 100644 index 00000000000..800c1b5ed6f --- /dev/null +++ b/regress/lib/libc/atexit/Makefile @@ -0,0 +1,12 @@ +# $OpenBSD: Makefile,v 1.1 2002/07/29 19:51:41 dhartmei Exp $ + +NOMAN= +PROG=atexit_test + +regress: ${PROG} + ./${PROG} -valid 2>${.OBJDIR}/valid.out + cmp -s ${.OBJDIR}/valid.out ${.CURDIR}/valid.ok + ./${PROG} -invalid 2>${.OBJDIR}/invalid.out + cmp -s ${.OBJDIR}/invalid.out ${.CURDIR}/invalid.ok + +.include <bsd.regress.mk> diff --git a/regress/lib/libc/atexit/atexit_test.c b/regress/lib/libc/atexit/atexit_test.c new file mode 100644 index 00000000000..fcfe95cb020 --- /dev/null +++ b/regress/lib/libc/atexit/atexit_test.c @@ -0,0 +1,131 @@ +/* $OpenBSD: atexit_test.c,v 1.1 2002/07/29 19:51:41 dhartmei Exp $ */ + +/* + * Copyright (c) 2002 Daniel Hartmeier + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Effort sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F30602-01-2-0537. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include "/usr/src/lib/libc/stdlib/atexit.h" + +extern struct atexit *__atexit; +extern void (*__cleanup)(); + +void handle_first(); +void handle_middle(); +void handle_last(); +void handle_invalid(); +void handle_cleanup(); +void handle_signal(int); + +static int counter; + +int +main(int argc, char *argv[]) +{ + int i; + + if (argc != 2 || (strcmp(argv[1], "-valid") && + strcmp(argv[1], "-invalid"))) { + fprintf(stderr, "%s -valid/-invalid\n", argv[0]); + return (1); + } + fprintf(stderr, "main()\n"); + if (atexit(handle_last)) { + perror("atexit(handle_last) failed"); + return (1); + } + for (i = 0; i < 65535; ++i) { + if (atexit(handle_middle)) { + perror("atexit(handle_middle) failed"); + return (1); + } + } + if (atexit(handle_first)) { + perror("atexit(handle_first) failed"); + return (1); + } + /* this is supposed to segfault */ + if (strcmp(argv[1], "-valid")) { + signal(SIGSEGV, handle_signal); + __atexit->fns[0] = handle_invalid; + } + __cleanup = handle_cleanup; + counter = 0; + fprintf(stderr, "main() returns\n"); + return (0); +} + +void +handle_first() +{ + fprintf(stderr, "handle_first() counter == %i\n", counter); +} + +void +handle_middle() +{ + counter++; +} + +void +handle_last() +{ + fprintf(stderr, "handle_last() counter == %i\n", counter); +} + +void +handle_cleanup() +{ + fprintf(stderr, "handle_cleanup()\n"); +} + +void +handle_invalid() +{ + fprintf(stderr, "handle_invalid() THIS SHOULD HAVE SEGFAULTED INSTEAD!\n"); +} + +void +handle_signal(int sigraised) +{ + switch (sigraised) { + case SIGSEGV: + fprintf(stderr, "SIGSEGV\n"); + exit(0); + default: + fprintf(stderr, "unexpected signal caught\n"); + exit(1); + } +} diff --git a/regress/lib/libc/atexit/invalid.ok b/regress/lib/libc/atexit/invalid.ok new file mode 100644 index 00000000000..98cbf8c1de0 --- /dev/null +++ b/regress/lib/libc/atexit/invalid.ok @@ -0,0 +1,4 @@ +main() +SIGSEGV +handle_first() counter == 0 +handle_last() counter == 65535 diff --git a/regress/lib/libc/atexit/valid.ok b/regress/lib/libc/atexit/valid.ok new file mode 100644 index 00000000000..6509e827a70 --- /dev/null +++ b/regress/lib/libc/atexit/valid.ok @@ -0,0 +1,5 @@ +main() +main() returns +handle_first() counter == 0 +handle_last() counter == 65535 +handle_cleanup() |