summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-07-29 19:51:42 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-07-29 19:51:42 +0000
commit865fdcdce92da25d834f892d6351e4cf1a54995d (patch)
tree2f29e70011b9812356891aacfc9c84466e4a93ca
parent56e564fd6a5feaceea08c7fa2464f763db39f887 (diff)
Try to modify __atexit directly and see if our function gets called.
-rw-r--r--regress/lib/libc/atexit/Makefile12
-rw-r--r--regress/lib/libc/atexit/atexit_test.c131
-rw-r--r--regress/lib/libc/atexit/invalid.ok4
-rw-r--r--regress/lib/libc/atexit/valid.ok5
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()