diff options
Diffstat (limited to 'regress/lib')
130 files changed, 7946 insertions, 0 deletions
diff --git a/regress/lib/libc_r/Makefile b/regress/lib/libc_r/Makefile new file mode 100644 index 00000000000..f78a928032c --- /dev/null +++ b/regress/lib/libc_r/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +SUBDIR= cancel close cwd execve fork group netdb poll \ + preemption pthread_cond_timedwait pthread_create \ + pthread_join pthread_mutex readdir select setjmp signal \ + sigsuspend sigwait sleep socket stdarg stdio switch + +# Not available or disabled: fcntl, pause, preemption_float and pw + +regress: _SUBDIRUSE + +install: + +.include <bsd.subdir.mk> diff --git a/regress/lib/libc_r/Makefile.inc b/regress/lib/libc_r/Makefile.inc new file mode 100644 index 00000000000..aaca0ef4c74 --- /dev/null +++ b/regress/lib/libc_r/Makefile.inc @@ -0,0 +1,30 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/08/15 14:37:10 fgsch Exp $ +# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu + +LIBC_R?= /usr/lib/libc_r.a +LIBPTHREAD?= /usr/lib/libpthread.a + +.if 1 # ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "sparc" +LDADD+= -lpthread +DPADD+= ${LIBPTHREAD} +.else +LDADD+= -pthread +DPADD+= ${LIBC_R} +.endif + +CFLAGS+= -Wall # -Werror +DEBUG= -ggdb +CFLAGS+= -DSRCDIR='"${.CURDIR}"' +CFLAGS+= -I${.CURDIR}/../include + +NOMAN= + +MAXTIME= 5 + +regress: ${PROG} + @echo; echo "*** $? ***"; \ + if (ulimit -t ${MAXTIME}; ${.OBJDIR}/$?); then \ + echo "-- $? passed"; \ + else \ + echo "-- $? FAILED (exit code $$?)" >&2; \ + fi; diff --git a/regress/lib/libc_r/cancel/Makefile b/regress/lib/libc_r/cancel/Makefile new file mode 100644 index 00000000000..f9faf68398c --- /dev/null +++ b/regress/lib/libc_r/cancel/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= cancel +SRCS= cancel.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/cancel/cancel.c b/regress/lib/libc_r/cancel/cancel.c new file mode 100644 index 00000000000..2dd0d4c1940 --- /dev/null +++ b/regress/lib/libc_r/cancel/cancel.c @@ -0,0 +1,177 @@ +/* $OpenBSD: cancel.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 1999. Public Domain. */ + +#include <pthread.h> +#include <pthread_np.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include "test.h" + +static pthread_cond_t cond; +static pthread_mutex_t mutex; +static struct timespec expiretime; + +static int pv_state = 0; +void p() { + CHECKr(pthread_mutex_lock(&mutex)); + if (pv_state <= 0) { + CHECKr(pthread_cond_timedwait(&cond, &mutex, &expiretime)); + } + pv_state--; + CHECKr(pthread_mutex_unlock(&mutex)); +} + +void v() { + int needsignal; + + CHECKr(pthread_mutex_lock(&mutex)); + pv_state++; + needsignal = (pv_state == 1); + if (needsignal) + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); +} + +void +c1handler(void *fd) +{ + CHECKe(close((int)fd)); + v(); +} + +void * +child1fn(arg) + void *arg; +{ + int fd; + char buf[1024]; + int len; + + SET_NAME("c1"); + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)); + /* something that will block */ + CHECKe(fd = open("/dev/tty", O_RDONLY)); + pthread_cleanup_push(c1handler, (void *)fd); + v(); + while (1) { + CHECKe(len = read(fd, &buf, sizeof buf)); + printf("child 1 read %d bytes\n", len); + } + PANIC("child 1"); +} + +static int c2_in_test = 0; + +void +c2handler(void *arg) +{ + ASSERT(c2_in_test); + v(); +} + +static int message_seen = 0; +void * +child2fn(arg) + void *arg; +{ + SET_NAME("c2"); + + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)); + pthread_cleanup_push(c2handler, NULL); + v(); + + while (1) { + struct timespec now; + struct timespec end; + + /* + * XXX Be careful not to call any cancellation points + * until pthread_testcancel() + */ + + CHECKe(clock_gettime(CLOCK_REALTIME, &end)); + end.tv_sec ++; + + while (1) { + CHECKe(clock_gettime(CLOCK_REALTIME, &now)); + if (timespeccmp(&now, &end, >=)) + break; + pthread_yield(); + } + + /* XXX write() contains a cancellation point */ + /* printf("child 2 testing for cancel\n"); */ + + c2_in_test = 1; + pthread_testcancel(); + printf("you should see this message exactly once\n"); + message_seen++; + c2_in_test = 0; + ASSERT(message_seen == 1); + } + PANIC("child 2"); +} + +static int c3_cancel_survived; + +void +c3handler(void *arg) +{ + printf("(fyi, cancellation of self %s instantaneous)\n", + (c3_cancel_survived ? "was not" : "was")); + v(); +} + +void * +child3fn(arg) + void *arg; +{ + SET_NAME("c3"); + pthread_cleanup_push(c3handler, NULL); + + /* Cancel myself */ + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)); + c3_cancel_survived = 0; + pthread_cancel(pthread_self()); + c3_cancel_survived = 1; + pthread_testcancel(); + + PANIC("child 3"); +} + +int +main() +{ + pthread_t child1, child2, child3; + + /* Set up our control flow */ + CHECKr(pthread_mutex_init(&mutex, NULL)); + CHECKr(pthread_cond_init(&cond, NULL)); + CHECKe(clock_gettime(CLOCK_REALTIME, &expiretime)); + expiretime.tv_sec += 5; /* this test shouldn't run over 5 seconds */ + + CHECKr(pthread_create(&child1, NULL, child1fn, NULL)); + CHECKr(pthread_create(&child2, NULL, child2fn, NULL)); + p(); + p(); + + CHECKr(pthread_cancel(child1)); + p(); + + /* Give thread 2 a chance to go through its deferred loop once */ + sleep(2); + CHECKr(pthread_cancel(child2)); + p(); + + /* Child 3 cancels itself */ + CHECKr(pthread_create(&child3, NULL, child3fn, NULL)); + p(); + + /* Make sure they're all gone */ + CHECKr(pthread_join(child3, NULL)); + CHECKr(pthread_join(child2, NULL)); + CHECKr(pthread_join(child1, NULL)); + + exit(0); +} diff --git a/regress/lib/libc_r/close/Makefile b/regress/lib/libc_r/close/Makefile new file mode 100644 index 00000000000..d09a10dbd1c --- /dev/null +++ b/regress/lib/libc_r/close/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= close +SRCS= close.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/close/close.c b/regress/lib/libc_r/close/close.c new file mode 100644 index 00000000000..18b64b64f0e --- /dev/null +++ b/regress/lib/libc_r/close/close.c @@ -0,0 +1,100 @@ +/* $OpenBSD: close.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test the semantics of close() while a select() is happening. + * Not a great test. You need the 'discard' service running in inetd for + * this to work. + */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "test.h" + +int fd; + +void* new_thread(void* arg) +{ + fd_set r; + int ret; + char garbage[] = "blah blah blah"; + + FD_ZERO(&r); + FD_SET(fd, &r); + + printf("child: writing some garbage to fd %d\n", fd); + CHECKe(write(fd, garbage, sizeof garbage)); + printf("child: calling select() with fd %d\n", fd); + CHECKe(ret = select(fd + 1, &r, NULL, NULL, NULL)); + printf("child: select() returned %d\n", ret); + return NULL; +} + +int +main() +{ + pthread_t thread; + pthread_attr_t attr; + struct sockaddr_in addr; + int ret; + + /* Open up a TCP connection to the local discard port */ + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(9); /* port 9/tcp is discard service */ + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + printf("main: connecting to discard port with fd %d\n", fd); + ret = connect(fd, (struct sockaddr *)&addr, sizeof addr); + if (ret == -1) + fprintf(stderr, "connect() failed: ensure that the discard port is enabled for inetd(8)\n"); + CHECKe(ret); + printf("main: connected on fd %d\n", fd); + + CHECKr(pthread_attr_init(&attr)); + CHECKe(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); + printf("starting child thread\n"); + CHECKr(pthread_create(&thread, &attr, new_thread, NULL)); + sleep(1); + printf("main: closing fd %d\n", fd); + CHECKe(close(fd)); + printf("main: closed\n"); + sleep(1); + SUCCEED; +} diff --git a/regress/lib/libc_r/cwd/Makefile b/regress/lib/libc_r/cwd/Makefile new file mode 100644 index 00000000000..0821e066592 --- /dev/null +++ b/regress/lib/libc_r/cwd/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= cwd +SRCS= cwd.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/cwd/cwd.c b/regress/lib/libc_r/cwd/cwd.c new file mode 100644 index 00000000000..2480a825ef4 --- /dev/null +++ b/regress/lib/libc_r/cwd/cwd.c @@ -0,0 +1,55 @@ +/* $OpenBSD: cwd.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * 'Test' getcwd() and getwd() + */ + +#include <stdio.h> +#include <sys/param.h> +#include <unistd.h> +#include "test.h" + +int +main(int argc, char **argv) +{ + char wd[MAXPATHLEN]; + char *path; + + ASSERT(path = getcwd(wd, sizeof wd)); + printf("getcwd => %s\n", path); + ASSERT(path = getwd(wd)); + printf("getwd => %s\n", path); + SUCCEED; +} diff --git a/regress/lib/libc_r/execve/Makefile b/regress/lib/libc_r/execve/Makefile new file mode 100644 index 00000000000..8a828adb6a3 --- /dev/null +++ b/regress/lib/libc_r/execve/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= execve +SRCS= execve.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/execve/execve.c b/regress/lib/libc_r/execve/execve.c new file mode 100644 index 00000000000..fa4ceac012e --- /dev/null +++ b/regress/lib/libc_r/execve/execve.c @@ -0,0 +1,80 @@ +/* $OpenBSD: execve.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Test execve() and dup2() calls. + */ + +#include <pthread.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include "test.h" + +extern char **environ; +char *argv[] = { + "/bin/echo", + "This line should appear after the execve", + NULL +}; + +char * should_succeed = "This line should be displayed\n"; + +int +main() +{ + int fd; + + printf("This is the first message\n"); + if (isatty(STDOUT_FILENO)) { + char *ttynm; + + CHECKn(ttynm = ttyname(STDOUT_FILENO)); + printf("tty is %s\n", ttynm); + CHECKe(fd = open(ttynm, O_RDWR)); + } else + PANIC("stdout is not a tty: this test needs a tty"); + + CHECKn(printf("This output is necessary to set the stdout fd to NONBLOCKING\n")); + + /* do a dup2 */ + CHECKe(dup2(fd, STDOUT_FILENO)); + CHECKe(write(STDOUT_FILENO, should_succeed, + (size_t)strlen(should_succeed))); + CHECKe(execve(argv[0], argv, environ)); + DIE(errno, "execve %s", argv[0]); +} diff --git a/regress/lib/libc_r/fcntl/Makefile b/regress/lib/libc_r/fcntl/Makefile new file mode 100644 index 00000000000..74f14602f60 --- /dev/null +++ b/regress/lib/libc_r/fcntl/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= fcntl +SRCS= fcntl.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/fcntl/fcntl.c b/regress/lib/libc_r/fcntl/fcntl.c new file mode 100644 index 00000000000..7106a301b89 --- /dev/null +++ b/regress/lib/libc_r/fcntl/fcntl.c @@ -0,0 +1,70 @@ +/* $OpenBSD: fcntl.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test fcntl() flag inheritance across a fork() + */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include "test.h" + +int +main() +{ + int flags, newflags, child; + + CHECKe(flags = fcntl(0, F_GETFL)); + printf("flags = %x\n", flags); + + CHECKe(child = fork()); + switch(child) { + case 0: /* child */ + CHECKe(execlp("./pthread_create", "./pthread_create", + (char *)NULL)); + /* NOTREACHED */ + default: /* parent */ + CHECKe(wait(NULL)); + break; + } + + while(1){ + CHECKe(newflags = fcntl(0, F_GETFL)); + printf ("parent %d flags = %x\n", child, newflags); + sleep(1); + } +} diff --git a/regress/lib/libc_r/fork/Makefile b/regress/lib/libc_r/fork/Makefile new file mode 100644 index 00000000000..d8e724955c6 --- /dev/null +++ b/regress/lib/libc_r/fork/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= fork +SRCS= fork.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/fork/fork.c b/regress/lib/libc_r/fork/fork.c new file mode 100644 index 00000000000..cd227a70ce8 --- /dev/null +++ b/regress/lib/libc_r/fork/fork.c @@ -0,0 +1,126 @@ +/* $OpenBSD: fork.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Test the fork system call. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <sys/wait.h> +#include "test.h" + + +void * +empty(void *arg) +{ + + return (void *)0x12345678; +} + +void * +sleeper(void *arg) +{ + + pthread_set_name_np(pthread_self(), "slpr"); + sleep(10); + PANIC("sleeper timed out"); +} + + +int +main() +{ + int flags; + pthread_t sleeper_thread; + void *result; + int status; + pid_t parent_pid; + pid_t child_pid; + + parent_pid = getpid(); + + CHECKe(flags = fcntl(STDOUT_FILENO, F_GETFL)); + if ((flags & (O_NONBLOCK | O_NDELAY))) { + /* This fails when stdout is /dev/null!? */ + /*CHECKe*/(fcntl(STDOUT_FILENO, F_SETFL, + flags & ~(O_NONBLOCK | O_NDELAY))); + } + + CHECKr(pthread_create(&sleeper_thread, NULL, sleeper, NULL)); + sleep(1); + + printf("forking from pid %d\n", getpid()); + + CHECKe(child_pid = fork()); + if (child_pid == 0) { + /* child: */ + printf("child = pid %d\n", getpid()); + /* Our pid should change */ + ASSERT(getpid() != parent_pid); + /* Our sleeper thread should have disappeared */ + printf("sleeper should have disappeared\n"); + ASSERT(ESRCH == pthread_join(sleeper_thread, &result)); + printf("sleeper disappeared correctly\n"); + /* Test starting another thread */ + CHECKr(pthread_create(&sleeper_thread, NULL, empty, NULL)); + sleep(1); + CHECKr(pthread_join(sleeper_thread, &result)); + ASSERT(result == (void *)0x12345678); + printf("child ok\n"); + _exit(0); + PANIC("child _exit"); + } + + /* parent: */ + printf("parent = pid %d\n", getpid()); + /* Our pid should stay the same */ + ASSERT(getpid() == parent_pid); + /* wait for the child */ + ASSERTe(wait(&status), == child_pid); + /* the child should have called exit(0) */ + ASSERT(WIFEXITED(status)); + ASSERT(WEXITSTATUS(status) == 0); + /* Our sleeper thread should still be around */ + CHECKr(pthread_detach(sleeper_thread)); + printf("parent ok\n"); + SUCCEED; +} diff --git a/regress/lib/libc_r/group/Makefile b/regress/lib/libc_r/group/Makefile new file mode 100644 index 00000000000..b9f1557ba8a --- /dev/null +++ b/regress/lib/libc_r/group/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= group +SRCS= group.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/group/group.c b/regress/lib/libc_r/group/group.c new file mode 100644 index 00000000000..cc81df6cf01 --- /dev/null +++ b/regress/lib/libc_r/group/group.c @@ -0,0 +1,180 @@ +/* $OpenBSD: group.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * Test getgrgid_r() across multiple threads to see if the members list changes. + */ + +#include <pthread.h> +#include <unistd.h> +#include <stdio.h> +#include <grp.h> +#include <sys/types.h> +#include "test.h" + +struct group * getgrgid_r(gid_t, struct group *); + +char fail[] = "fail"; + +pthread_cond_t done; +volatile int done_count; + +pthread_mutex_t display; +pthread_mutex_t display2; + +void* +test(void* arg) +{ + gid_t gid = (int)arg; + gid_t ogid; + struct group grpbuf; + struct group *grp; + char **p; + char buf[2048]; + char *cpy[128]; + int i; + int count1, count2; + char *s; + char *oname; + char *opasswd; + + /* Acquire lock for running first part. */ + CHECKr(pthread_mutex_lock(&display)); + + /* Store magic name to test for non-alteration */ + grpbuf.gr_name = fail; + + /* Call getgrgid_r() */ + printf("gid %d\n", gid); + CHECKn(grp = getgrgid_r(gid, &grpbuf)); + + /* Test for non-alteration of group structure */ + ASSERT(grp->gr_name != fail); + + /* We must get the right group */ + ASSERT(grp->gr_gid == gid); + + s = buf; /* Keep our private buffer on the stack */ + + /* copy gr_name */ + strcpy(oname = s, grp->gr_name); + s += 1 + strlen(s); + + /* copy gr_passwd */ + strcpy(opasswd = s, grp->gr_passwd); + s += 1 + strlen(s); + + /* copy gr_gid */ + ogid = grp->gr_gid; + + /* copy gr_mem */ + for (i = 0, p = grp->gr_mem; *p; p++) { + strcpy(cpy[i] = s, *p); i++; + s += 1 + strlen(s); + } + cpy[i] = NULL; + +#if 0 + printf("now: %s:%s:%d:", grp->gr_name, grp->gr_passwd, grp->gr_gid); + for (p = grp->gr_mem; *p; p++) + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + printf("\n"); +#endif + +#ifdef DEBUG /* debugging this program */ + printf("buf = \""); + for (i = 0; i < s - buf; i++) + if (buf[i] == '\0') printf("\\0"); + else printf("%c", buf[i]); + printf("\"\n"); +#endif + + /* Inform main that we have finished */ + done_count++; + CHECKr(pthread_cond_signal(&done)); + + /* Allow other threads to run first part */ + CHECKr(pthread_mutex_unlock(&display)); + + /* Acquire lock for the second part */ + CHECKr(pthread_mutex_lock(&display2)); + + count1 = 0; + printf("before: %s:%s:%d:", oname, opasswd, ogid); + for (p = cpy; *p; p++) { + count1++; + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + } + printf("\n"); + + count2 = 0; + printf("after: %s:%s:%d:", grp->gr_name, grp->gr_passwd, grp->gr_gid); + for (p = grp->gr_mem; *p; p++) { + count2++; + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + } + printf("\n"); + + CHECKr(pthread_mutex_unlock(&display2)); + + if (count1 != count2) + return "gr_mem length changed"; + for (i = 0; i < count1; i++) + if (strcmp(cpy[i], grp->gr_mem[i]) != 0) + return "gr_mem list changed"; + if (strcmp(grp->gr_name, oname) != 0) + return "gr_name changed"; + if (strcmp(grp->gr_passwd, opasswd) != 0) + return "gr_passwd changed"; + if (grp->gr_gid != ogid) + return "gr_gid changed"; + return NULL; +} + + +#define NGRPS 5 +int +main() +{ + pthread_t thread[NGRPS]; + int gid; + int failed; + void *result; + + CHECKr(pthread_mutex_init(&display, NULL)); + CHECKr(pthread_mutex_init(&display2, NULL)); + + CHECKr(pthread_cond_init(&done, NULL)); + done_count = 0; + + pthread_mutex_lock(&display); + pthread_mutex_lock(&display2); + + /* Get separate threads to do a group open separately */ + for (gid = 0; gid < NGRPS; gid++) { + CHECKr(pthread_create(&thread[gid], NULL, test, (void *)gid)); + } + + /* Allow all threads to run their first part */ + while (done_count < NGRPS) + pthread_cond_wait(&done, &display); + + /* Allow each thread to run the 2nd part of its test */ + CHECKr(pthread_mutex_unlock(&display2)); + + /* Wait for each thread to terminate, collecting results. */ + failed = 0; + for (gid = 0; gid < NGRPS; gid++) { + CHECKr(pthread_join(thread[gid], &result)); + if (result != NULL) { + fprintf(stderr, "gid %d: %s\n", gid, (char *)result); + failed++; + } + } + + if (!failed) { + SUCCEED; + } else { + exit(1); + } +} diff --git a/regress/lib/libc_r/include/test.h b/regress/lib/libc_r/include/test.h new file mode 100644 index 00000000000..3d329bf90eb --- /dev/null +++ b/regress/lib/libc_r/include/test.h @@ -0,0 +1,123 @@ +/* $OpenBSD: test.h,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ + +#ifndef _h_test_ +#define _h_test_ + +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> + +int _thread_sys_write __P((int, const char*, size_t)); +__dead void _thread_sys__exit __P((int)) __attribute__((__noreturn__)); + +static __dead void __vpanic __P((const char *, const char *, const char *, + int, const char *, va_list)) __attribute__((__noreturn__)); +static __dead void __panic __P((const char *, const char *, const char *, + int, const char *, ...)) __attribute__((__noreturn__)); + +#if defined(__OpenBSD__) || defined(__FreeBSD__) +#include <pthread.h> +#include <pthread_np.h> +void _thread_dump_info __P((void)); +#define SET_NAME(x) pthread_set_name_np(pthread_self(), x) +#define DUMP_INFO() _thread_dump_info() +#else +#define SET_NAME(x) /* nada */ +#define DUMP_INFO() /* nada */ +#endif + +static void +__vpanic(type, errstr, filenm, lineno, fmt, ap) + const char *type; + const char *errstr; + const char *filenm; + int lineno; + const char *fmt; + va_list ap; +{ + char buf[1024]; + + /* "<type> at <filenm>:<lineno>: <fmt ap...>:<errstr>" */ + snprintf(buf, sizeof buf, "%s at %s:%d\n", type, filenm, lineno); + _thread_sys_write(2, buf, strlen(buf)); + vsnprintf(buf, sizeof buf, fmt, ap); + if (errstr != NULL) { + strlcat(buf, ": ", sizeof buf); + strlcat(buf, errstr, sizeof buf); + } + strlcat(buf, "\n", sizeof buf); + _thread_sys_write(2, buf, strlen(buf)); + + DUMP_INFO(); + _thread_sys__exit(1); + + _thread_sys_write(2, "[locking]\n", 10); + while(1); +} + +static void +__panic(type, errstr, filenm, lineno, fmt) + const char *type; + const char *errstr; + const char *filenm; + int lineno; + const char *fmt; +{ + va_list ap; + + va_start(ap, fmt); + __vpanic(type, errstr, filenm, lineno, fmt, ap); + va_end(ap); +} + +#define DIE(e, m, args...) \ + __panic("died", strerror(e), __FILE__, __LINE__, m , ## args) + +#define PANIC(m, args...) \ + __panic("panic", NULL, __FILE__, __LINE__, m, ## args) + +#define ASSERT(x) do { \ + if (!(x)) \ + __panic("assert failed", NULL, __FILE__, __LINE__, "%s", #x); \ +} while(0) + +#define ASSERTe(x,rhs) do { \ + int _x; \ + _x = (x); \ + if (!(_x rhs)) { \ + if (_x > 0) \ + __panic("assert failed", strerror(_x), __FILE__, __LINE__, \ + "%s %s", #x, #rhs); \ + else \ + __panic("assert failed", NULL, __FILE__, __LINE__, \ + "%s [=%d] %s", #x, _x, #rhs); \ + } \ +} while(0) + +#define _T(x) __builtin_classify_type(x) + +#define _CHECK(x, rhs, efn) do { \ + typeof(x) _x; \ + _x = (x); \ + if (!(_x rhs)) \ + __panic("check failed", efn, __FILE__, __LINE__, \ + ((_T(0) == _T(_x) )? "failed check %s (=%d) %s " : \ + (_T("") == _T(_x) )? "failed check %s (=%s) %s " : \ + (_T('x') == _T(_x) )? "failed check %s (=%c) %s " : \ + (_T(0L) == _T(_x) )? "failed check %s (=%ld) %s " : "?") \ + , #x, _x, #rhs); \ +} while(0) + +#define CHECKr(x) _CHECK(x, == 0, strerror(_x)) +#define CHECKe(x) _CHECK(x, != -1, strerror(errno)) +#define CHECKn(x) _CHECK(x, != 0, strerror(errno)) +#define CHECKhn(x) _CHECK(x, != 0, hstrerror(h_errno)) + +#define SUCCEED exit(0) + +#define OK (0) +#define NOTOK (-1) + +#endif _h_test_ diff --git a/regress/lib/libc_r/netdb/Makefile b/regress/lib/libc_r/netdb/Makefile new file mode 100644 index 00000000000..7b293a620c5 --- /dev/null +++ b/regress/lib/libc_r/netdb/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= netdb +SRCS= netdb.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/netdb/netdb.c b/regress/lib/libc_r/netdb/netdb.c new file mode 100644 index 00000000000..cf4d59e0560 --- /dev/null +++ b/regress/lib/libc_r/netdb/netdb.c @@ -0,0 +1,84 @@ +/* $OpenBSD: netdb.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1995 by Greg Hudson, ghudson@.mit.edu + * + * Test netdb calls. + */ + +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#include "test.h" + +static void test_serv() +{ + struct servent *serv; + + CHECKhn(serv = getservbyname("telnet", "tcp")); + printf("getservbyname -> port %d\n", ntohs(serv->s_port)); +} + +static void test_host() +{ + struct hostent *host; + struct in_addr addr; + + CHECKhn(host = gethostbyname("localhost")); + memcpy(&addr, host->h_addr, sizeof(addr)); + printf("gethostbyname -> %s\n", inet_ntoa(addr)); +} + +static void test_localhost() +{ + struct hostent *host; + + CHECKhn(host = gethostbyname("127.0.0.1")); +} + +int +main(int argc, char **argv) +{ + test_serv(); + test_localhost(); + test_host(); + + SUCCEED; +} diff --git a/regress/lib/libc_r/pause/Makefile b/regress/lib/libc_r/pause/Makefile new file mode 100644 index 00000000000..588a25ec48c --- /dev/null +++ b/regress/lib/libc_r/pause/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= pause +SRCS= pause.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pause/pause.c b/regress/lib/libc_r/pause/pause.c new file mode 100644 index 00000000000..8185e7ca2d0 --- /dev/null +++ b/regress/lib/libc_r/pause/pause.c @@ -0,0 +1,68 @@ +/* $OpenBSD: pause.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test pause() + */ + +#include <stdio.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include "test.h" + +int gotsig = 0; + +void +handler(sig) + int sig; +{ + printf("%s\n", strsignal(sig)); +} + +int +main() +{ + sigset_t all; + pid_t self; + + ASSERT(signal(SIGHUP, handler) != SIG_ERR); + CHECKe(self = getpid()); + CHECKe(sigemptyset(&all)); + CHECKe(sigaddset(&all, SIGHUP)); + CHECKe(sigprocmask(SIG_BLOCK, &all, NULL)); + CHECKe(kill(self, SIGHUP)); + CHECKe(pause()); + SUCCEED; +} diff --git a/regress/lib/libc_r/poll/Makefile b/regress/lib/libc_r/poll/Makefile new file mode 100644 index 00000000000..1d2503867e4 --- /dev/null +++ b/regress/lib/libc_r/poll/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= poll +SRCS= poll.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/poll/poll.c b/regress/lib/libc_r/poll/poll.c new file mode 100644 index 00000000000..360f8f800cb --- /dev/null +++ b/regress/lib/libc_r/poll/poll.c @@ -0,0 +1,136 @@ +/* $OpenBSD: poll.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +#include <pthread.h> +#include <fcntl.h> +#include <poll.h> +#include <paths.h> +#include <unistd.h> +#include "test.h" + + +#define POLLALL (POLLIN|POLLOUT|POLLERR|POLLNVAL) + +static void +print_pollfd(p) + struct pollfd *p; +{ + + printf("{fd=%d, events=< %s%s%s> revents=< %s%s%s%s%s>}", + p->fd, + p->events & POLLIN ? "in " : "", + p->events & POLLOUT ? "out " : "", + p->events & ~(POLLIN|POLLOUT) ? "XXX " : "", + p->revents & POLLIN ? "in " : "", + p->revents & POLLOUT ? "out " : "", + p->revents & POLLERR ? "err " : "", + p->revents & POLLHUP ? "hup " : "", + p->revents & POLLNVAL ? "nval " : "" + ); +} + +static void * +writer(arg) + void *arg; +{ + int fd = (int)arg; + const char msg[1] = { '!' }; + + ASSERTe(write(fd, &msg, sizeof msg), == sizeof msg); + return NULL; +} + +static void * +reader(arg) + void *arg; +{ + int fd = (int)arg; + char buf[1]; + + ASSERTe(read(fd, &buf, sizeof buf), == sizeof buf); + return NULL; +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t t; + void *result; + int null, zero, tty; + int tube[2]; + struct pollfd p[3]; + + /* Try an empty poll set */ + ASSERTe(poll(NULL, 0, 0), == 0); + + CHECKe(zero = open(_PATH_DEV "zero", O_RDONLY)); + CHECKe(null = open(_PATH_DEV "null", O_WRONLY)); + CHECKe(tty = open(_PATH_DEV "tty", O_WRONLY)); + + /* Try both descriptors being ready */ + p[0].fd = zero; + p[0].events = POLLIN|POLLOUT; + p[0].revents = 0; + p[1].fd = null; + p[1].events = POLLIN|POLLOUT; + p[1].revents = 0; + + ASSERTe(poll(p, 2, 0), == 2); /* if 4 then bug in kernel not fixed */ + printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("null p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT((p[0].revents & POLLIN) == POLLIN); + ASSERT((p[1].revents & POLLOUT) == POLLOUT); + + /* + * Try one of the descriptors being invalid + * and the other ready + */ + printf("closing zero\n"); + close(zero); + + p[0].fd = zero; + p[0].events = POLLIN|POLLOUT; + p[1].fd = null; + p[1].events = POLLIN|POLLOUT; + ASSERTe(poll(p, 2, 0), == 2); /* again, old kernels had this bug */ + printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("null p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT((p[0].revents & POLLNVAL) == POLLNVAL); + ASSERT((p[1].revents & POLLOUT) == POLLOUT); + + printf("closing null\n"); + close(null); + + /* + * New pipes. the write end should be writable (buffered) + */ + CHECKe(pipe(tube)); + CHECKe(fcntl(tube[0], F_SETFL, O_NONBLOCK)); + CHECKe(fcntl(tube[1], F_SETFL, O_NONBLOCK)); + + p[0].fd = tube[0]; + p[0].events = POLLIN; + p[1].fd = tube[1]; + p[1].events = POLLOUT; + ASSERTe(poll(p, 2, 0), == 1); + printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("wpipe p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT(p[0].revents == 0); + ASSERT(p[1].revents == POLLOUT); + + /* Start a writing thread to the write end [1] */ + printf("bg writing to wpipe\n"); + CHECKr(pthread_create(&t, NULL, writer, (void *)tube[1])); + /* The read end [0] should soon be ready for read (POLLIN) */ + p[0].fd = tube[0]; + p[0].events = POLLIN; + ASSERTe(poll(p, 1, INFTIM), == 1); + printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n'); + ASSERT(p[0].revents == POLLIN); + reader((void *)tube[0]); /* consume */ + CHECKr(pthread_join(t, &result)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/preemption/Makefile b/regress/lib/libc_r/preemption/Makefile new file mode 100644 index 00000000000..8370c6cc399 --- /dev/null +++ b/regress/lib/libc_r/preemption/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= preemption +SRCS= preemption.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/preemption/preemption.c b/regress/lib/libc_r/preemption/preemption.c new file mode 100644 index 00000000000..ef0829ce4f5 --- /dev/null +++ b/regress/lib/libc_r/preemption/preemption.c @@ -0,0 +1,73 @@ +/* $OpenBSD: preemption.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_cond(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include "test.h" + +void * +new_thread(void * new_buf) +{ + int i; + + printf("yielding:"); + for (i = 0; i < 10; i++) { + printf(" %d", i); + fflush(stdout); + pthread_yield(); + } + printf("\n"); + SUCCEED; +} + +int +main() +{ + pthread_t thread; + + CHECKr(pthread_create(&thread, NULL, new_thread, NULL)); + + while(1) + ; + PANIC("while"); +} diff --git a/regress/lib/libc_r/preemption_float/Makefile b/regress/lib/libc_r/preemption_float/Makefile new file mode 100644 index 00000000000..91ad73e48a7 --- /dev/null +++ b/regress/lib/libc_r/preemption_float/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= preemption_float +SRCS= preemption_float.c +#DPADD= ${LIBM} +#LDADD= -lm + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/preemption_float/preemption_float.c b/regress/lib/libc_r/preemption_float/preemption_float.c new file mode 100644 index 00000000000..3aa810689fd --- /dev/null +++ b/regress/lib/libc_r/preemption_float/preemption_float.c @@ -0,0 +1,148 @@ +/* $OpenBSD: preemption_float.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* Test to see if floating point state is being properly maintained + for each thread. Different threads doing floating point operations + simultaneously should not interfere with one another. This + includes operations that might change some FPU flags, such as + rounding modes, at least implicitly. */ + +#include <pthread.h> +#include <math.h> +#include <stdio.h> +#include "test.h" + +int limit = 2; +int float_passed = 0; +int float_failed = 1; + +void *log_loop (void *x) { + int i; + double d, d1, d2; + /* sleep (1); */ + for (i = 0; i < limit; i++) { + d = 42.0; + d = log (exp (d)); + d = (d + 39.0) / d; + if (i == 0) + d1 = d; + else { + d2 = d; + d = sin(d); + /* if (d2 != d1) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +void *trig_loop (void *x) { + int i; + double d, d1, d2; + /* sleep (1); */ + for (i = 0; i < limit; i++) { + d = 35.0; + d *= M_PI; + d /= M_LN2; + d = sin (d); + d = cos (1 / d); + if (i == 0) + d1 = d; + else { + d2 = d; + d = sin(d); + /* if (d2 != d1) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +int +floatloop(pthread_attr_t *attrp) +{ + pthread_t thread[2]; + int *x, *y; + + CHECKr(pthread_create (&thread[0], attrp, trig_loop, 0)); + CHECKr(pthread_create (&thread[1], attrp, log_loop, 0)); + CHECKr(pthread_join(thread[0], (void **) &x)); + CHECKr(pthread_join(thread[1], (void **) &y)); + + /* Return 0 for success */ + return ((*y == float_failed)?2:0) | + ((*x == float_failed)?1:0); +} + +#define N 10 +int +main() +{ + pthread_attr_t attr; + int i; + + /* Try with float point state not preserved */ + + CHECKr(pthread_attr_init(&attr)); + CHECKr(pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT)); + + for(limit = 2; limit < 100000; limit *=4) + if (floatloop(&attr) != 0) + break; + + if (limit >= 100000) { + printf("results are INDETERMINATE\n"); + SUCCEED; /* XXX */ + } + + limit *= 4; /* just to make sure */ + + printf("using limit = %d\n", limit); + + for (i = 0; i < 32; i++) { + /* Try the failure mode one more time. */ + if (floatloop(&attr) == 0) { + printf("%d ", i); + fflush(stdout); + } + /* Now see if saving float state will get rid of failure. */ + ASSERT(floatloop(NULL) == 0); + } + + SUCCEED; +} diff --git a/regress/lib/libc_r/pthread_cond_timedwait/Makefile b/regress/lib/libc_r/pthread_cond_timedwait/Makefile new file mode 100644 index 00000000000..487f916efe7 --- /dev/null +++ b/regress/lib/libc_r/pthread_cond_timedwait/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_cond_timedwait +SRCS= pthread_cond_timedwait.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pthread_cond_timedwait/pthread_cond_timedwait.c b/regress/lib/libc_r/pthread_cond_timedwait/pthread_cond_timedwait.c new file mode 100644 index 00000000000..3f34eb44c40 --- /dev/null +++ b/regress/lib/libc_r/pthread_cond_timedwait/pthread_cond_timedwait.c @@ -0,0 +1,113 @@ +/* $OpenBSD: pthread_cond_timedwait.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_cond(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include "test.h" + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +void* thread_1(void * new_buf) +{ + CHECKr(pthread_mutex_lock(&mutex)); + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); + pthread_exit(NULL); +} + +void* thread_2(void * new_buf) +{ + sleep(1); + CHECKr(pthread_mutex_lock(&mutex)); + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); + pthread_exit(NULL); +} + +int +main() +{ + struct timespec abstime = { 0, 0 }; + struct timeval curtime; + pthread_t thread; + int ret; + + printf("pthread_cond_timedwait START\n"); + + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(gettimeofday(&curtime, NULL)); + abstime.tv_sec = curtime.tv_sec + 5; + + /* Test a condition timeout */ + switch((ret = pthread_cond_timedwait(&cond, &mutex, &abstime))) { + case 0: + PANIC("pthread_cond_timedwait #0 failed to timeout"); + /* NOTREACHED */ + case ETIMEDOUT: + /* expected behaviour */ + printf("Got first timeout ok\n"); /* Added by monty */ + break; + default: + DIE(ret, "pthread_cond_timedwait"); + /* NOTREACHED */ + } + + /* Test a normal condition signal */ + CHECKr(pthread_create(&thread, NULL, thread_1, NULL)); + + abstime.tv_sec = curtime.tv_sec + 10; + CHECKr(pthread_cond_timedwait(&cond, &mutex, &abstime)); + + /* Test a normal condition signal after a sleep */ + CHECKr(pthread_create(&thread, NULL, thread_2, NULL)); + + pthread_yield(); + + abstime.tv_sec = curtime.tv_sec + 10; + CHECKr(pthread_cond_timedwait(&cond, &mutex, &abstime)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/pthread_create/Makefile b/regress/lib/libc_r/pthread_create/Makefile new file mode 100644 index 00000000000..8ecea5ff1ca --- /dev/null +++ b/regress/lib/libc_r/pthread_create/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= pthread_create +SRCS= pthread_create.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pthread_create/pthread_create.c b/regress/lib/libc_r/pthread_create/pthread_create.c new file mode 100644 index 00000000000..ccc2a6c4292 --- /dev/null +++ b/regress/lib/libc_r/pthread_create/pthread_create.c @@ -0,0 +1,66 @@ +/* $OpenBSD: pthread_create.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Test pthread_create() and pthread_exit() calls. + */ + +#include <pthread.h> +#include <stdio.h> +#include "test.h" + +void* new_thread(void* arg) +{ + int i; + + printf("New thread was passed arg address %p\n", arg); + printf("New thread stack at %p\n", &i); + return(NULL); + PANIC("return"); +} + +int +main() +{ + pthread_t thread; + int i; + + printf("Original thread stack at %p\n", &i); + CHECKr(pthread_create(&thread, NULL, new_thread, + (void *)0xdeadbeef)); + CHECKr(pthread_join(thread, NULL)); + SUCCEED; +} diff --git a/regress/lib/libc_r/pthread_join/Makefile b/regress/lib/libc_r/pthread_join/Makefile new file mode 100644 index 00000000000..fed1bdca2be --- /dev/null +++ b/regress/lib/libc_r/pthread_join/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_join +SRCS= pthread_join.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pthread_join/pthread_join.c b/regress/lib/libc_r/pthread_join/pthread_join.c new file mode 100644 index 00000000000..a8637caa887 --- /dev/null +++ b/regress/lib/libc_r/pthread_join/pthread_join.c @@ -0,0 +1,98 @@ +/* $OpenBSD: pthread_join.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_join.c ================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_join(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <unistd.h> +#include <stdio.h> +#include "test.h" + +/* This thread yields so the creator has a live thread to wait on */ +void* new_thread_1(void * new_buf) +{ + int i; + + sprintf((char *)new_buf, "New thread %%d stack at %p\n", &i); + pthread_yield(); /* (ensure parent can wait on live thread) */ + sleep(1); + return(new_buf); + PANIC("return"); +} + +/* This thread doesn't yield so the creator has a dead thread to wait on */ +void* new_thread_2(void * new_buf) +{ + int i; + + sprintf((char *)new_buf, "New thread %%d stack at %p\n", &i); + return(new_buf); + PANIC("return"); +} + +int +main() +{ + char buf[256], *status; + pthread_t thread; + int debug = 1; + int i = 0; + + if (debug) + printf("Original thread stack at %p\n", &i); + + CHECKr(pthread_create(&thread, NULL, new_thread_1, (void *)buf)); + CHECKr(pthread_join(thread, (void **)(&status))); + if (debug) + printf(status, ++i); + + /* Now have the created thread finishing before the join. */ + CHECKr(pthread_create(&thread, NULL, new_thread_2, (void *)buf)); + pthread_yield(); + sleep(1); /* (ensure thread is dead) */ + CHECKr(pthread_join(thread, (void **)(&status))); + + if (debug) + printf(status, ++i); + + SUCCEED; +} + diff --git a/regress/lib/libc_r/pthread_mutex/Makefile b/regress/lib/libc_r/pthread_mutex/Makefile new file mode 100644 index 00000000000..050627af875 --- /dev/null +++ b/regress/lib/libc_r/pthread_mutex/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_mutex +SRCS= pthread_mutex.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pthread_mutex/pthread_mutex.c b/regress/lib/libc_r/pthread_mutex/pthread_mutex.c new file mode 100644 index 00000000000..1375231bca2 --- /dev/null +++ b/regress/lib/libc_r/pthread_mutex/pthread_mutex.c @@ -0,0 +1,194 @@ +/* $OpenBSD: pthread_mutex.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_mutex(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include "test.h" + +int contention_variable; + +void * +thread_contention(arg) + void *arg; +{ + pthread_mutex_t *mutex = arg; + + SET_NAME("cntntn"); + + CHECKr(pthread_mutex_lock(mutex)); + ASSERT(contention_variable == 1); + contention_variable = 2; + CHECKr(pthread_mutex_unlock(mutex)); + pthread_exit(NULL); +} + +void +test_contention_lock(mutex) + pthread_mutex_t *mutex; +{ + pthread_t thread; + + printf(" test_contention_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + contention_variable = 0; + CHECKr(pthread_create(&thread, NULL, thread_contention, mutex)); + pthread_yield(); + contention_variable = 1; + CHECKr(pthread_mutex_unlock(mutex)); + CHECKr(pthread_mutex_lock(mutex)); + ASSERT(contention_variable == 2); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_nocontention_lock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_nocontention_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_debug_double_lock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_debug_double_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + ASSERTe(pthread_mutex_lock(mutex), == EDEADLK); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_debug_double_unlock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_debug_double_unlock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); + /* Posix D10 says undefined behaviour? */ + ASSERTe(pthread_mutex_unlock(mutex), != EPERM); +} + +void +test_nocontention_trylock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_nocontention_trylock()\n"); + CHECKr(pthread_mutex_trylock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_mutex_static() +{ + pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER; + + printf("test_mutex_static()\n"); + test_nocontention_lock(&mutex_static); + test_contention_lock(&mutex_static); +} + +void +test_mutex_fast(void) +{ + pthread_mutex_t mutex_fast; + + printf("test_mutex_fast()\n"); + CHECKr(pthread_mutex_init(&mutex_fast, NULL)); + test_nocontention_lock(&mutex_fast); + test_contention_lock(&mutex_fast); + CHECKr(pthread_mutex_destroy(&mutex_fast)); +} + +void +test_mutex_debug() +{ + pthread_mutexattr_t mutex_debug_attr; + pthread_mutex_t mutex_debug; + + printf("test_mutex_debug()\n"); + CHECKr(pthread_mutexattr_init(&mutex_debug_attr)); + CHECKr(pthread_mutexattr_settype(&mutex_debug_attr, + PTHREAD_MUTEX_ERRORCHECK)); + CHECKr(pthread_mutex_init(&mutex_debug, &mutex_debug_attr)); + test_nocontention_lock(&mutex_debug); + test_contention_lock(&mutex_debug); + test_debug_double_lock(&mutex_debug); + test_debug_double_unlock(&mutex_debug); + CHECKr(pthread_mutex_destroy(&mutex_debug)); +} + +void +test_mutex_recursive() +{ + pthread_mutexattr_t mutex_recursive_attr; + pthread_mutex_t mutex_recursive; + int i; + + printf("test_mutex_recursive()\n"); + CHECKr(pthread_mutexattr_init(&mutex_recursive_attr)); + CHECKr(pthread_mutexattr_settype(&mutex_recursive_attr, + PTHREAD_MUTEX_RECURSIVE)); + CHECKr(pthread_mutex_init(&mutex_recursive, &mutex_recursive_attr)); + + CHECKr(pthread_mutex_lock(&mutex_recursive)); + for (i = 0; i < 9; i++) + CHECKr(pthread_mutex_lock(&mutex_recursive)); + for (i = 0; i < 9; i++) + CHECKr(pthread_mutex_unlock(&mutex_recursive)); + CHECKr(pthread_mutex_unlock(&mutex_recursive)); + /* Posix D10 says undefined behaviour? */ + ASSERTe(pthread_mutex_unlock(&mutex_recursive), != 0); +} + +int +main() +{ + test_mutex_static(); + test_mutex_fast(); + test_mutex_debug(); + test_mutex_recursive(); + SUCCEED; +} diff --git a/regress/lib/libc_r/pw/Makefile b/regress/lib/libc_r/pw/Makefile new file mode 100644 index 00000000000..f5d21c798ac --- /dev/null +++ b/regress/lib/libc_r/pw/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pw +SRCS= pw.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/pw/pw.c b/regress/lib/libc_r/pw/pw.c new file mode 100644 index 00000000000..fc7beec4963 --- /dev/null +++ b/regress/lib/libc_r/pw/pw.c @@ -0,0 +1,61 @@ +/* $OpenBSD: pw.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <pwd.h> +#include "test.h" + +int +main() +{ + struct passwd *pw; + struct passwd pwbuf; + char buf[8192]; + char name[16]; + + CHECKn(pw = getpwuid(getuid())); + printf("getpwuid(%d) => %p\n", getuid(), pw); + printf(" name: %s\n uid: %d\n gid: %d\n" + "class: %s\ngecos: %s\n dir: %s\nshell: %s\n", + pw->pw_name, pw->pw_uid, pw->pw_gid, + pw->pw_class, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + + strlcpy(name, pw->pw_name, sizeof name); + CHECKe(getpwnam_r(name, &pwbuf, buf, sizeof buf, &pw)); + ASSERT(pwbuf.pw_uid == getuid()); + + SUCCEED; +} diff --git a/regress/lib/libc_r/readdir/Makefile b/regress/lib/libc_r/readdir/Makefile new file mode 100644 index 00000000000..c1c1e68a135 --- /dev/null +++ b/regress/lib/libc_r/readdir/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= readdir +SRCS= readdir.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/readdir/readdir.c b/regress/lib/libc_r/readdir/readdir.c new file mode 100644 index 00000000000..7d2c6ce26d4 --- /dev/null +++ b/regress/lib/libc_r/readdir/readdir.c @@ -0,0 +1,65 @@ +/* $OpenBSD: readdir.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_readdir.c ======================================================== + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 94/05/19 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <dirent.h> +#include <stdio.h> +#include "test.h" + +int +main() +{ + struct dirent * file; + DIR * dot_dir; + int found = 0; + + CHECKn(dot_dir = opendir(".")); + while ((file = readdir(dot_dir)) != NULL) + if (strcmp("readdir", file->d_name) == 0) + found = 1; + CHECKe(closedir(dot_dir)); + ASSERT(found); + SUCCEED; +} + diff --git a/regress/lib/libc_r/select/Makefile b/regress/lib/libc_r/select/Makefile new file mode 100644 index 00000000000..af34834aebc --- /dev/null +++ b/regress/lib/libc_r/select/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= select +SRCS= select.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/select/select.c b/regress/lib/libc_r/select/select.c new file mode 100644 index 00000000000..666ed9ef083 --- /dev/null +++ b/regress/lib/libc_r/select/select.c @@ -0,0 +1,152 @@ +/* $OpenBSD: select.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Rudimentary test of select(). + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <errno.h> +#include <unistd.h> +#include "test.h" + +#define NLOOPS 10000 + +int ntouts = 0; + +void * +bg_routine(arg) + void *arg; +{ + char dot = '.'; + int n; + + SET_NAME("bg"); + + /* Busy loop, printing dots */ + for (;;) { + pthread_yield(); + write(STDOUT_FILENO, &dot, sizeof dot); + pthread_yield(); + n = NLOOPS; + while (n-- > 0) + pthread_yield(); + } +} + +void * +fg_routine(arg) + void *arg; +{ + int flags; + int n; + fd_set r; + int fd = fileno((FILE *) arg); + int tty = isatty(fd); + int maxfd; + int nb; + char buf[128]; + + SET_NAME("fg"); + + /* Set the file descriptor to non-blocking */ + flags = fcntl(fd, F_GETFL); + CHECKr(fcntl(fd, F_SETFL, flags | O_NONBLOCK)); + + for (;;) { + + /* Print a prompt if it's a tty: */ + if (tty) { + printf("type something> "); + fflush(stdout); + } + + /* Select on the fdesc: */ + FD_ZERO(&r); + FD_SET(fd, &r); + maxfd = fd; + errno = 0; + CHECKe(n = select(maxfd + 1, &r, (fd_set *) 0, (fd_set *) 0, + (struct timeval *) 0)); + + if (n > 0) { + /* Something was ready for read. */ + printf("select returned %d\n", n); + while ((nb = read(fd, buf, sizeof(buf) - 1)) > 0) { + printf("read %d: `%.*s'\n", nb, nb, buf); + } + printf("last read was %d, errno = %d %s\n", nb, errno, + errno == 0 ? "success" : strerror(errno)); + if (nb < 0) + ASSERTe(errno, == EWOULDBLOCK || + errno == EAGAIN); + if (nb == 0) + break; + } else + ntouts++; + } + printf("read finished\n"); + return (NULL); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + pthread_t bg_thread, fg_thread; + FILE * slpr; + + /* Create a fdesc that will block for a while on read: */ + CHECKn(slpr = popen("sleep 2; echo foo", "r")); + + /* Create a busy loop thread that yields a lot: */ + CHECKr(pthread_create(&bg_thread, NULL, bg_routine, 0)); + + /* Create the thread that reads the fdesc: */ + CHECKr(pthread_create(&fg_thread, NULL, fg_routine, (void *) slpr)); + + /* Wait for the reader thread to finish */ + CHECKr(pthread_join(fg_thread, NULL)); + + /* Clean up*/ + CHECKe(pclose(slpr)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/setjmp/Makefile b/regress/lib/libc_r/setjmp/Makefile new file mode 100644 index 00000000000..26457b3f0fc --- /dev/null +++ b/regress/lib/libc_r/setjmp/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= setjmp +SRCS= setjmp.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/setjmp/setjmp.c b/regress/lib/libc_r/setjmp/setjmp.c new file mode 100644 index 00000000000..45f6feca99d --- /dev/null +++ b/regress/lib/libc_r/setjmp/setjmp.c @@ -0,0 +1,92 @@ +/* $OpenBSD: setjmp.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <setjmp.h> +#include "test.h" + +int reached; + +void * +_jump(arg) + void *arg; +{ + jmp_buf foo; + + reached = 0; + if (_setjmp(foo)) { + ASSERT(reached); + return NULL; + } + reached = 1; + _longjmp(foo, 1); + PANIC("_longjmp"); +} + +void * +jump(arg) + void *arg; +{ + jmp_buf foo; + + reached = 0; + if (setjmp(foo)) { + ASSERT(reached); + return NULL; + } + reached = 1; + longjmp(foo, 1); + PANIC("longjmp"); +} + +int +main() +{ + pthread_t child; + void *res; + + printf("jumping in main thread\n"); + (void)jump(NULL); + printf("_jumping in main thread\n"); + (void)_jump(NULL); + + printf("jumping in child thread\n"); + CHECKr(pthread_create(&child, NULL, jump, NULL)); + CHECKr(pthread_join(child, &res)); + + printf("_jumping in child thread\n"); + CHECKr(pthread_create(&child, NULL, _jump, NULL)); + CHECKr(pthread_join(child, &res)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/signal/Makefile b/regress/lib/libc_r/signal/Makefile new file mode 100644 index 00000000000..b107b790354 --- /dev/null +++ b/regress/lib/libc_r/signal/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= signal +SRCS= signal.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/signal/signal.c b/regress/lib/libc_r/signal/signal.c new file mode 100644 index 00000000000..effc36b7087 --- /dev/null +++ b/regress/lib/libc_r/signal/signal.c @@ -0,0 +1,49 @@ +/* $OpenBSD: signal.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * This program tests signal handler re-entrancy. + */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include "test.h" + +void * +sleeper(arg) + void *arg; +{ + sigset_t mask; + + /* Ignore all signals in this thread */ + sigfillset(&mask); + CHECKe(sigprocmask(SIG_SETMASK, &mask, NULL)); + + ASSERT(sleep(2) == 0); + SUCCEED; +} + +void +handler(sig) + int sig; +{ + printf("signal handler %d\n", sig); + alarm(1); + signal(SIGALRM, handler); +} + +int +main() +{ + pthread_t slpr; + + ASSERT(signal(SIGALRM, handler) != SIG_ERR); + CHECKe(alarm(1)); + CHECKr(pthread_create(&slpr, NULL, sleeper, NULL)); + /* ASSERT(sleep(1) == 0); */ + for (;;) + CHECKe(write(STDOUT_FILENO, ".", 1)); +} diff --git a/regress/lib/libc_r/sigsuspend/Makefile b/regress/lib/libc_r/sigsuspend/Makefile new file mode 100644 index 00000000000..4e0c7a93d2f --- /dev/null +++ b/regress/lib/libc_r/sigsuspend/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= sigsuspend +SRCS= sigsuspend.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/sigsuspend/sigsuspend.c b/regress/lib/libc_r/sigsuspend/sigsuspend.c new file mode 100644 index 00000000000..df3b990dafb --- /dev/null +++ b/regress/lib/libc_r/sigsuspend/sigsuspend.c @@ -0,0 +1,239 @@ +/* $OpenBSD: sigsuspend.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. + * + */ +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + +#include <pthread_np.h> +#include "test.h" + +static int sigcounts[NSIG + 1]; +static int sigfifo[NSIG + 1]; +static int fifo_depth = 0; +static sigset_t suspender_mask; +static pthread_t suspender_tid; + + +static void * +sigsuspender (void *arg) +{ + int save_count, status, i; + sigset_t run_mask; + + SET_NAME("sigsuspender"); + + /* Run with all signals blocked. */ + sigfillset (&run_mask); + CHECKe(sigprocmask (SIG_SETMASK, &run_mask, NULL)); + + /* Allow these signals to wake us up during a sigsuspend. */ + sigfillset (&suspender_mask); /* Default action */ + sigdelset (&suspender_mask, SIGINT); /* terminate */ + sigdelset (&suspender_mask, SIGHUP); /* terminate */ + sigdelset (&suspender_mask, SIGQUIT); /* create core image */ + sigdelset (&suspender_mask, SIGURG); /* ignore */ + sigdelset (&suspender_mask, SIGIO); /* ignore */ + sigdelset (&suspender_mask, SIGUSR2); /* terminate */ + + while (sigcounts[SIGINT] == 0) { + save_count = sigcounts[SIGUSR2]; + + status = sigsuspend (&suspender_mask); + if ((status == 0) || (errno != EINTR)) { + DIE(errno, "Unable to suspend for signals, " + "return value %d\n", + status); + } + for (i = 0; i < fifo_depth; i++) + printf ("Sigsuspend woke up by signal %d (%s)\n", + sigfifo[i], strsignal(sigfifo[i])); + fifo_depth = 0; + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + sigset_t set; + pthread_t self; + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; + + /* + * If we are running on behalf of the suspender thread, + * ensure that we have the correct mask set. + */ + self = pthread_self (); + if (self == suspender_tid) { + sigfifo[fifo_depth] = signo; + fifo_depth++; + printf (" -> Suspender thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); + sigprocmask (SIG_SETMASK, NULL, &set); + ASSERT(set == suspender_mask); + } + else + printf (" -> Main thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); +} + + +int main (int argc, char *argv[]) +{ + pthread_attr_t pattr; + struct sigaction act; + sigset_t oldset; + sigset_t newset; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Ignore signal SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* Get our current signal mask. */ + CHECKe(sigprocmask (SIG_SETMASK, NULL, &oldset)); + + /* Mask out SIGUSR1 and SIGUSR2. */ + newset = oldset; + sigaddset (&newset, SIGUSR1); + sigaddset (&newset, SIGUSR2); + CHECKe(sigprocmask (SIG_SETMASK, &newset, NULL)); + + /* Install a signal handler for SIGUSR1 and SIGUSR2 */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGUSR1); + sigaddset (&act.sa_mask, SIGUSR2); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGUSR1, &act, NULL)); + CHECKe(sigaction (SIGUSR2, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Create the sigsuspender thread. + */ + CHECKr(pthread_create (&suspender_tid, &pattr, sigsuspender, NULL)); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (suspender_tid, SIGIO)); + sleep (1); + CHECKe(kill (getpid (), SIGIO)); + sleep (1); + /* sigsuspend should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a + * sigsuspend. + */ + CHECKr(pthread_kill (suspender_tid, SIGURG)); + sleep (1); + CHECKe(kill (getpid (), SIGURG)); + sleep (1); + /* sigsuspend should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 3); + + /* + * Verify that a SIGUSR2 signal will release a sigsuspended + * thread. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR2)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR2)); + sleep (1); + /* sigsuspend should wake yp for SIGUSR2 */ + ASSERT(sigcounts[SIGUSR2] == 2); + + /* + * Verify that a signal, blocked in both the main and + * sigsuspender threads, does not cause the signal handler + * to be called. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR1)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR1)); + sleep (1); + /* signal handler should not be called for USR1 */ + ASSERT(sigcounts[SIGUSR1] == 0); +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill (getpid (), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (suspender_tid, NULL)); +#endif + SUCCEED; +} + diff --git a/regress/lib/libc_r/sigwait/Makefile b/regress/lib/libc_r/sigwait/Makefile new file mode 100644 index 00000000000..52117d781b0 --- /dev/null +++ b/regress/lib/libc_r/sigwait/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= sigwait +SRCS= sigwait.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/sigwait/sigwait.c b/regress/lib/libc_r/sigwait/sigwait.c new file mode 100644 index 00000000000..a166eaf2a1e --- /dev/null +++ b/regress/lib/libc_r/sigwait/sigwait.c @@ -0,0 +1,264 @@ +/* $OpenBSD: sigwait.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. + * + */ +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + +#include <pthread_np.h> +#include "test.h" + +static int sigcounts[NSIG + 1]; +static sigset_t wait_mask; +static pthread_mutex_t waiter_mutex; + + +static void * +sigwaiter (void *arg) +{ + int signo; + sigset_t mask; + + SET_NAME("sigwaiter"); + + /* Block SIGHUP */ + sigemptyset (&mask); + sigaddset (&mask, SIGHUP); + CHECKe(sigprocmask (SIG_BLOCK, &mask, NULL)); + + while (sigcounts[SIGINT] == 0) { + printf("Sigwait waiting (thread %p)\n", pthread_self()); + CHECKe(sigwait (&wait_mask, &signo)); + sigcounts[signo]++; + printf ("Sigwait caught signal %d (%s)\n", signo, + strsignal(signo)); + + /* Allow the main thread to prevent the sigwait. */ + CHECKr(pthread_mutex_lock (&waiter_mutex)); + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + printf (" -> Signal handler caught signal %d (%s) in thread %p\n", + signo, strsignal(signo), pthread_self()); + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; +} + +int main (int argc, char *argv[]) +{ + pthread_mutexattr_t mattr; + pthread_attr_t pattr; + pthread_t tid; + struct sigaction act; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Setupt our wait mask. */ + sigemptyset (&wait_mask); /* Default action */ + sigaddset (&wait_mask, SIGHUP); /* terminate */ + sigaddset (&wait_mask, SIGINT); /* terminate */ + sigaddset (&wait_mask, SIGQUIT); /* create core image */ + sigaddset (&wait_mask, SIGURG); /* ignore */ + sigaddset (&wait_mask, SIGIO); /* ignore */ + sigaddset (&wait_mask, SIGUSR1); /* terminate */ + + /* Ignore signals SIGHUP and SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGHUP, &act, NULL)); + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Initialize and create a mutex. + */ + CHECKr(pthread_mutexattr_init (&mattr)); + CHECKr(pthread_mutex_init (&waiter_mutex, &mattr)); + + /* + * Create the sigwaiter thread. + */ + CHECKr(pthread_create (&tid, &pattr, sigwaiter, NULL)); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (tid, SIGIO)); + sleep (1); + CHECKe(kill(getpid(), SIGIO)); + sleep (1); + /* sigwait should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGURG)); + sleep (1); + CHECKe(kill(getpid(), SIGURG)); + sleep (1); + /* sigwait should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 2); + + /* + * Verify that a signal with a default action that terminates + * the process will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + CHECKe(kill(getpid(), SIGUSR1)); + sleep (1); + if (sigcounts[SIGUSR1] != 2) + printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n"); + + /* + * Verify that if we install a signal handler for a previously + * ignored signal, an occurrence of this signal will release + * the (already waiting) sigwait. + */ + + /* Install a signal handler for SIGHUP. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGHUP, &act, NULL)); + + /* Sending SIGHUP should release the sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + CHECKr(pthread_kill (tid, SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 2); + + /* + * Verify that a pending signal in the waiters mask will + * cause sigwait to return the pending signal. We do this + * by taking the waiters mutex and signaling the waiter to + * release him from the sigwait. The waiter will block + * on taking the mutex, and we can then send the waiter a + * signal which should be added to his pending signals. + * The next time the waiter does a sigwait, he should + * return with the pending signal. + */ + sigcounts[SIGHUP] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 1); + /* + * Add SIGHUP to all threads pending signals. Since there is + * a signal handler installed for SIGHUP and this signal is + * blocked from the waiter thread and unblocked in the main + * thread, the signal handler should be called once for SIGHUP. + */ + CHECKe(kill(getpid(), SIGHUP)); + /* Release the waiter thread and allow him to run. */ + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 3); + + /* + * Repeat the above test using pthread_kill and SIGUSR1 + */ + sigcounts[SIGUSR1] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + /* sigwait should wake up for SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 1); + /* Add SIGHUP to the waiters pending signals. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + /* Release the waiter thread and allow him to run. */ + CHECKe(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 2); + +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill(getpid(), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (tid, NULL)); +#endif + + SUCCEED; +} diff --git a/regress/lib/libc_r/sleep/Makefile b/regress/lib/libc_r/sleep/Makefile new file mode 100644 index 00000000000..5cde62316d2 --- /dev/null +++ b/regress/lib/libc_r/sleep/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= sleep +SRCS= sleep.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/sleep/sleep.c b/regress/lib/libc_r/sleep/sleep.c new file mode 100644 index 00000000000..ec5ddd1bb66 --- /dev/null +++ b/regress/lib/libc_r/sleep/sleep.c @@ -0,0 +1,82 @@ +/* $OpenBSD: sleep.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sleep.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test context switch functionality. + * + * 1.00 93/08/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include "test.h" + +const char buf[] = "abcdefghijklimnopqrstuvwxyz"; +int fd = 1; + +void* new_thread(void* arg) +{ + int i; + + for (i = 0; i < 10; i++) { + write(fd, buf + (long) arg, 1); + sleep(1); + } + return NULL; +} + +int +main() +{ + pthread_t thread[2]; + int count = sizeof thread/sizeof thread[0]; + long i; + + printf("Going to sleep\n"); + sleep(3); + printf("Done sleeping\n"); + + for(i = 0; i < count; i++) + CHECKr(pthread_create(&thread[i], NULL, new_thread, + (void *) i)); + + for (i = 0; i < count; i++) + CHECKr(pthread_join(thread[i], NULL)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/socket/1/Makefile b/regress/lib/libc_r/socket/1/Makefile new file mode 100644 index 00000000000..e0eeda8e59b --- /dev/null +++ b/regress/lib/libc_r/socket/1/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket1 +SRCS= socket1.c +CFLAGS+= -I${.CURDIR}/../../include + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/socket/1/socket1.c b/regress/lib/libc_r/socket/1/socket1.c new file mode 100644 index 00000000000..ee41bf1db48 --- /dev/null +++ b/regress/lib/libc_r/socket/1/socket1.c @@ -0,0 +1,194 @@ +/* $OpenBSD: socket1.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include "test.h" +#include <sched.h> +#include <string.h> +#include <stdlib.h> + +struct sockaddr_in a_sout; +int success = 0; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_attr_t attr; + +static int counter = 0; + +void * +sock_connect(arg) + void *arg; +{ + char buf[1024]; + int fd; + + /* Ensure sock_read runs first */ + CHECKr(pthread_mutex_lock(&mutex)); + + a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */ + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + ASSERT(++counter == 2); + + /* connect to the socket */ + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + CHECKe(close(fd)); + + CHECKr(pthread_mutex_unlock(&mutex)); + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + ASSERT(++counter == 3); + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + + /* Ensure sock_read runs again */ + pthread_yield(); + sleep(1); + + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(read(fd, buf, 1024)); + + write(fd, "6", 1); + + ASSERT(++counter == atoi(buf)); + CHECKe(close(fd)); + success++; + CHECKr(pthread_mutex_unlock(&mutex)); + + return(NULL); +} + +void * +sock_write(arg) + void *arg; +{ + int fd = *(int *)arg; + + CHECKe(write(fd, "5", 1)); + return(NULL); +} + +void * +sock_accept(arg) + void *arg; +{ + pthread_t thread; + struct sockaddr a_sin; + int a_sin_size, a_fd, fd; + short port; + char buf[1024]; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = INADDR_ANY; + + CHECKe(a_fd = socket(AF_INET, SOCK_STREAM, 0)); + + while (1) { + if(0 == bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout))) + break; + if (errno == EADDRINUSE) { + a_sout.sin_port = htons((++port)); + continue; + } + DIE(errno, "bind"); + } + CHECKe(listen(a_fd, 2)); + + ASSERT(++counter == 1); + + CHECKr(pthread_create(&thread, &attr, sock_connect, + (void *)0xdeadbeaf)); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(close(fd)); + + ASSERT(++counter == 4); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKr(pthread_mutex_unlock(&mutex)); + + /* Setup a write thread */ + CHECKr(pthread_create(&thread, &attr, sock_write, &fd)); + CHECKe(read(fd, buf, 1024)); + + ASSERT(++counter == atoi(buf)); + + CHECKe(close(fd)); + + CHECKr(pthread_mutex_lock(&mutex)); + success++; + CHECKr(pthread_mutex_unlock(&mutex)); + + CHECKr(pthread_join(thread, NULL)); + return(NULL); +} + +int +main() +{ + pthread_t thread; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_attr_init(&attr)); +#if 0 + CHECKr(pthread_attr_setschedpolicy(&attr, SCHED_FIFO)); +#endif + CHECKr(pthread_create(&thread, &attr, sock_accept, + (void *)0xdeadbeaf)); + + CHECKr(pthread_join(thread, NULL)); + + ASSERT(success == 2); + SUCCEED; +} diff --git a/regress/lib/libc_r/socket/2/Makefile b/regress/lib/libc_r/socket/2/Makefile new file mode 100644 index 00000000000..c53d752619c --- /dev/null +++ b/regress/lib/libc_r/socket/2/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket2 +SRCS= socket2.c +CFLAGS+= -I${.CURDIR}/../../include +CLEANFILES+= socket2a + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/socket/2/socket2.c b/regress/lib/libc_r/socket/2/socket2.c new file mode 100644 index 00000000000..5b3b51fda57 --- /dev/null +++ b/regress/lib/libc_r/socket/2/socket2.c @@ -0,0 +1,188 @@ +/* $OpenBSD: socket2.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <string.h> +#include "test.h" + +struct sockaddr_in a_sout; + +#define MESSAGE5 "This should be message #5" +#define MESSAGE6 "This should be message #6" + +void * +sock_write(arg) + void *arg; +{ + int fd = *(int *)arg; + + SET_NAME("writer"); + CHECKe(write(fd, MESSAGE5, sizeof(MESSAGE5))); + return(NULL); +} + +static pthread_mutex_t waiter_mutex = PTHREAD_MUTEX_INITIALIZER; + +void* +waiter(sig) +{ + int status; + pid_t pid; + + SET_NAME("waiter"); + CHECKr(pthread_mutex_lock(&waiter_mutex)); + printf("waiting for child\n"); + CHECKe(pid = wait(&status)); + ASSERT(WIFEXITED(status)); + ASSERT(WEXITSTATUS(status) == 0); + printf("child exited\n"); + CHECKr(pthread_mutex_unlock(&waiter_mutex)); + return (NULL); +} + +void * +sock_accept(arg) + void *arg; +{ + pthread_t thread, wthread; + struct sockaddr a_sin; + int a_sin_size, a_fd, fd; + u_int16_t port; + char buf[1024]; + pid_t pid; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = INADDR_ANY; + + CHECKe(a_fd = socket(AF_INET, SOCK_STREAM, 0)); + + while(1) { + if (bind(a_fd, (struct sockaddr *)&a_sout, sizeof(a_sout))==0) + break; + if (errno == EADDRINUSE) { + a_sout.sin_port = htons((++port)); + continue; + } + DIE(errno, "bind"); + } + + printf("listening on port %d\n", port); + + CHECKe(listen(a_fd, 2)); + + printf("%d: This should be message #1\n", getpid()); + + CHECKr(pthread_mutex_init(&waiter_mutex, NULL)); + CHECKr(pthread_mutex_lock(&waiter_mutex)); + CHECKr(pthread_create(&wthread, NULL, waiter, NULL)); + + CHECKe(pid = fork()); + switch(pid) { + case 0: + execl("socket2a", "socket2a", "fork okay", (char *)NULL); + DIE(errno, "execl"); + default: + break; + } + CHECKr(pthread_mutex_unlock(&waiter_mutex)); + pthread_yield(); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKe(close(fd)); + + sleep(1); + + printf("%d: This should be message #4\n", getpid()); + + a_sin_size = sizeof(a_sin); + memset(&a_sin, 0, sizeof(a_sin)); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + + /* Setup a write thread */ + + CHECKr(pthread_create(&thread, NULL, sock_write, &fd)); + CHECKe(read(fd, buf, 1024)); + + printf("%d: %s\n", getpid(), buf); /* message 6 */ + + CHECKe(close(fd)); + + if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) { + sleep(2); + if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) { + /* forcibly kill child */ + CHECKe(kill(pid, SIGKILL)); + PANIC("child %d took too long to exit", pid); + } + } + CHECKr(pthread_join(wthread, NULL)); + + return(NULL); +} + +int +main() +{ + pthread_t thread; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_create(&thread, NULL, sock_accept, + (void *)0xdeadbeaf)); + + CHECKr(pthread_join(thread, NULL)); + + SUCCEED; +} diff --git a/regress/lib/libc_r/socket/2a/Makefile b/regress/lib/libc_r/socket/2a/Makefile new file mode 100644 index 00000000000..11a91f9dc8d --- /dev/null +++ b/regress/lib/libc_r/socket/2a/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket2a +SRCS= socket2a.c +CFLAGS+= -I${.CURDIR}/../../include + +regress: + @cd ${.CURDIR}/../2; \ + if test -d ${__objdir} ; then \ + cd ${__objdir} ; \ + fi; \ + ln -sf ${.OBJDIR}/${PROG} + # Nothing here so far... + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/socket/2a/socket2a.c b/regress/lib/libc_r/socket/2a/socket2a.c new file mode 100644 index 00000000000..551b925065d --- /dev/null +++ b/regress/lib/libc_r/socket/2a/socket2a.c @@ -0,0 +1,118 @@ +/* $OpenBSD: socket2a.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <string.h> +#include "test.h" + +struct sockaddr_in a_sout; + +#define MESSAGE5 "This should be message #5" +#define MESSAGE6 "This should be message #6" + +void * +sock_connect(arg) + void *arg; +{ + char buf[1024]; + int fd; + short port; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* loopback */ + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + printf("%d: This should be message #2\n", getpid()); + + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + CHECKe(close(fd)); + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + printf("%d: This should be message #3\n", getpid()); + + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + + /* Ensure sock_read runs again */ + + CHECKe(read(fd, buf, 1024)); + CHECKe(write(fd, MESSAGE6, sizeof(MESSAGE6))); + + printf("%d: %s\n", getpid(), buf); + + CHECKe(close(fd)); + return (NULL); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t thread; + + if (argv[1] && (!strcmp(argv[1], "fork okay"))) { + sleep(1); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_create(&thread, NULL, sock_connect, + (void *)0xdeadbeaf)); + CHECKr(pthread_join(thread, NULL)); + SUCCEED; + } else { + fprintf(stderr, "test_sock_2a needs to be exec'ed from " + "test_sock_2.\n"); + fprintf(stderr, "It is not a stand alone test.\n"); + PANIC("usage"); + } +} diff --git a/regress/lib/libc_r/socket/Makefile b/regress/lib/libc_r/socket/Makefile new file mode 100644 index 00000000000..30574a5e2a6 --- /dev/null +++ b/regress/lib/libc_r/socket/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +SUBDIR= 1 2a 2 + +regress: _SUBDIRUSE + +.include <bsd.subdir.mk> diff --git a/regress/lib/libc_r/socket/Makefile.inc b/regress/lib/libc_r/socket/Makefile.inc new file mode 100644 index 00000000000..051138b01c5 --- /dev/null +++ b/regress/lib/libc_r/socket/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +.include "${.CURDIR}/../../Makefile.inc" diff --git a/regress/lib/libc_r/stdarg/Makefile b/regress/lib/libc_r/stdarg/Makefile new file mode 100644 index 00000000000..60c57f3e876 --- /dev/null +++ b/regress/lib/libc_r/stdarg/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= stdarg +SRCS= stdarg.c + +CFLAGS+= -I${.CURDIR}/../include + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/stdarg/stdarg.c b/regress/lib/libc_r/stdarg/stdarg.c new file mode 100644 index 00000000000..a3e07d58a21 --- /dev/null +++ b/regress/lib/libc_r/stdarg/stdarg.c @@ -0,0 +1,87 @@ +/* $OpenBSD: stdarg.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * Test <stdarg.h> + */ + +#include <pthread.h> +#include <stdio.h> +#include <stdarg.h> +#include "test.h" + +#define EQ(v,exp) _CHECK(v, == exp, NULL) + +int thing; + +int +test1(char *fmt, ...) +{ + va_list ap; + + char ch; + int i; + char c; + long l; + void *p; + char *ofmt = fmt; + + va_start(ap, fmt); + for (; *fmt; fmt++) + switch ((ch =*fmt)) { + case 'i': + i = va_arg(ap, int); + EQ(i, 1234); + break; + case 'c': + c = va_arg(ap, char); + EQ(c, 'x'); + break; + case 'l': + l = va_arg(ap, long); + EQ(l, 123456789L); + break; + case 'p': + p = va_arg(ap, void *); + EQ(p, &thing); + break; + default: + fprintf(stderr, "unexpected character 0x%02x `%c' in %s(%p) at %p\n", + ch, ch, ofmt, ofmt, fmt); + ASSERT(0); + } + va_end(ap); + return 9; +} + +void * +run_test(arg) + void *arg; +{ + char *msg = (char *)arg; + int i; + + SET_NAME(msg); + + puts(msg); + for (i = 0; i < 1000000; i++) { + ASSERT(test1("iclp", 1234, 'x', 123456789L, &thing) == 9); + } + printf("ok\n"); + return NULL; +} + +int +main() +{ + pthread_t t1, t2; + + printf("trying loop in single-threaded mode:\n"); + run_test("main"); + printf("now running loop with 2 threads:\n"); + CHECKr(pthread_create(&t1, NULL, run_test, "child 1")); + CHECKr(pthread_create(&t2, NULL, run_test, "child 2")); + CHECKr(pthread_join(t1, NULL)); + CHECKr(pthread_join(t2, NULL)); + SUCCEED; +} diff --git a/regress/lib/libc_r/stdio/Makefile b/regress/lib/libc_r/stdio/Makefile new file mode 100644 index 00000000000..f41504c0f39 --- /dev/null +++ b/regress/lib/libc_r/stdio/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= stdio +SRCS= stdio.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/stdio/stdio.c b/regress/lib/libc_r/stdio/stdio.c new file mode 100644 index 00000000000..9f3246d516b --- /dev/null +++ b/regress/lib/libc_r/stdio/stdio.c @@ -0,0 +1,111 @@ +/* $OpenBSD: stdio.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "test.h" + +char * base_name = "stdio.c"; +char * dir_name = SRCDIR; +char * fullname; + +/* Test fopen()/ftell()/getc() */ +void +test_1() +{ + struct stat statbuf; + FILE * fp; + int i; + + CHECKe(stat(fullname, &statbuf)); + + CHECKn((fp = fopen(fullname, "r"))); + + /* Get the entire file */ + while ((i = getc(fp)) != EOF) + ; + + ASSERT(ftell(fp) == statbuf.st_size); + + CHECKe(fclose(fp)); +} + +/* Test fopen()/fclose() */ +void +test_2() +{ + FILE *fp1, *fp2; + + CHECKn(fp1 = fopen(fullname, "r")); + CHECKe(fclose(fp1)); + + CHECKn(fp2 = fopen(fullname, "r")); + CHECKe(fclose(fp2)); + + ASSERT(fp1 == fp2); +} + +/* Test sscanf()/sprintf() */ +void +test_3(void) +{ + char * str = "10 4.53"; + char buf[64]; + double d; + int i; + + ASSERT(sscanf(str, "%d %lf", &i, &d) == 2); + + /* Should have a check */ + sprintf(buf, "%d %2.2f", i, d); + ASSERT(strcmp(buf, str) == 0); +} + +int +main() +{ + + CHECKn(fullname = malloc (strlen (dir_name) + strlen (base_name) + 2)); + sprintf (fullname, "%s/%s", dir_name, base_name); + + test_1(); + test_2(); + test_3(); + + SUCCEED; +} diff --git a/regress/lib/libc_r/switch/Makefile b/regress/lib/libc_r/switch/Makefile new file mode 100644 index 00000000000..ef0d6108068 --- /dev/null +++ b/regress/lib/libc_r/switch/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= switch +SRCS= switch.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libc_r/switch/switch.c b/regress/lib/libc_r/switch/switch.c new file mode 100644 index 00000000000..94fc9934bff --- /dev/null +++ b/regress/lib/libc_r/switch/switch.c @@ -0,0 +1,130 @@ +/* $OpenBSD: switch.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_switch.c ======================================================== + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test context switch functionality. + * + * 1.00 93/08/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include "test.h" + +const char buf[] = "abcdefghijklmnopqrstuvwxyz"; +char x[sizeof(buf)]; +int fd = 1; + +volatile int ending = 0; + +/* ========================================================================== + * usage(); + */ +void usage(void) +{ + printf("test_switch [-d?] [-c count]\n"); + printf("count must be between 2 and 26\n"); + errno = 0; +} + +void * +new_thread(arg) + void *arg; +{ + SET_NAME("writer"); + while (!ending) { + CHECKe(write (fd, (char *) arg, 1)); + x[(char *)arg - buf] = 1; + } + return NULL; +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t thread; + int count = 4; + int debug = 0; + int eof = 0; + long i; + + /* Getopt variables. */ + extern int optind, opterr; + extern char *optarg; + + while (!eof) + switch (getopt (argc, argv, "c:d?")) + { + case EOF: + eof = 1; + break; + case 'd': + debug++; + break; + case 'c': + count = atoi(optarg); + if ((count > 26) || (count < 2)) { + count = 2; + } + break; + case '?': + usage(); + return(OK); + default: + usage(); + return(NOTOK); + } + + /* create the threads */ + for (i = 0; i < count; i++) + CHECKr(pthread_create(&thread, NULL, new_thread, + (void*)(buf+i))); + + /* give all threads a chance to run */ + sleep (4); + + ending = 1; + for (i = 0; i < count; i++) + ASSERT(x[i]); /* make sure each thread ran */ + + SUCCEED; +} diff --git a/regress/lib/libpthread/Makefile b/regress/lib/libpthread/Makefile new file mode 100644 index 00000000000..f78a928032c --- /dev/null +++ b/regress/lib/libpthread/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +SUBDIR= cancel close cwd execve fork group netdb poll \ + preemption pthread_cond_timedwait pthread_create \ + pthread_join pthread_mutex readdir select setjmp signal \ + sigsuspend sigwait sleep socket stdarg stdio switch + +# Not available or disabled: fcntl, pause, preemption_float and pw + +regress: _SUBDIRUSE + +install: + +.include <bsd.subdir.mk> diff --git a/regress/lib/libpthread/Makefile.inc b/regress/lib/libpthread/Makefile.inc new file mode 100644 index 00000000000..aaca0ef4c74 --- /dev/null +++ b/regress/lib/libpthread/Makefile.inc @@ -0,0 +1,30 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/08/15 14:37:10 fgsch Exp $ +# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu + +LIBC_R?= /usr/lib/libc_r.a +LIBPTHREAD?= /usr/lib/libpthread.a + +.if 1 # ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "sparc" +LDADD+= -lpthread +DPADD+= ${LIBPTHREAD} +.else +LDADD+= -pthread +DPADD+= ${LIBC_R} +.endif + +CFLAGS+= -Wall # -Werror +DEBUG= -ggdb +CFLAGS+= -DSRCDIR='"${.CURDIR}"' +CFLAGS+= -I${.CURDIR}/../include + +NOMAN= + +MAXTIME= 5 + +regress: ${PROG} + @echo; echo "*** $? ***"; \ + if (ulimit -t ${MAXTIME}; ${.OBJDIR}/$?); then \ + echo "-- $? passed"; \ + else \ + echo "-- $? FAILED (exit code $$?)" >&2; \ + fi; diff --git a/regress/lib/libpthread/cancel/Makefile b/regress/lib/libpthread/cancel/Makefile new file mode 100644 index 00000000000..f9faf68398c --- /dev/null +++ b/regress/lib/libpthread/cancel/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= cancel +SRCS= cancel.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/cancel/cancel.c b/regress/lib/libpthread/cancel/cancel.c new file mode 100644 index 00000000000..2dd0d4c1940 --- /dev/null +++ b/regress/lib/libpthread/cancel/cancel.c @@ -0,0 +1,177 @@ +/* $OpenBSD: cancel.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 1999. Public Domain. */ + +#include <pthread.h> +#include <pthread_np.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include "test.h" + +static pthread_cond_t cond; +static pthread_mutex_t mutex; +static struct timespec expiretime; + +static int pv_state = 0; +void p() { + CHECKr(pthread_mutex_lock(&mutex)); + if (pv_state <= 0) { + CHECKr(pthread_cond_timedwait(&cond, &mutex, &expiretime)); + } + pv_state--; + CHECKr(pthread_mutex_unlock(&mutex)); +} + +void v() { + int needsignal; + + CHECKr(pthread_mutex_lock(&mutex)); + pv_state++; + needsignal = (pv_state == 1); + if (needsignal) + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); +} + +void +c1handler(void *fd) +{ + CHECKe(close((int)fd)); + v(); +} + +void * +child1fn(arg) + void *arg; +{ + int fd; + char buf[1024]; + int len; + + SET_NAME("c1"); + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)); + /* something that will block */ + CHECKe(fd = open("/dev/tty", O_RDONLY)); + pthread_cleanup_push(c1handler, (void *)fd); + v(); + while (1) { + CHECKe(len = read(fd, &buf, sizeof buf)); + printf("child 1 read %d bytes\n", len); + } + PANIC("child 1"); +} + +static int c2_in_test = 0; + +void +c2handler(void *arg) +{ + ASSERT(c2_in_test); + v(); +} + +static int message_seen = 0; +void * +child2fn(arg) + void *arg; +{ + SET_NAME("c2"); + + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL)); + pthread_cleanup_push(c2handler, NULL); + v(); + + while (1) { + struct timespec now; + struct timespec end; + + /* + * XXX Be careful not to call any cancellation points + * until pthread_testcancel() + */ + + CHECKe(clock_gettime(CLOCK_REALTIME, &end)); + end.tv_sec ++; + + while (1) { + CHECKe(clock_gettime(CLOCK_REALTIME, &now)); + if (timespeccmp(&now, &end, >=)) + break; + pthread_yield(); + } + + /* XXX write() contains a cancellation point */ + /* printf("child 2 testing for cancel\n"); */ + + c2_in_test = 1; + pthread_testcancel(); + printf("you should see this message exactly once\n"); + message_seen++; + c2_in_test = 0; + ASSERT(message_seen == 1); + } + PANIC("child 2"); +} + +static int c3_cancel_survived; + +void +c3handler(void *arg) +{ + printf("(fyi, cancellation of self %s instantaneous)\n", + (c3_cancel_survived ? "was not" : "was")); + v(); +} + +void * +child3fn(arg) + void *arg; +{ + SET_NAME("c3"); + pthread_cleanup_push(c3handler, NULL); + + /* Cancel myself */ + CHECKr(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)); + c3_cancel_survived = 0; + pthread_cancel(pthread_self()); + c3_cancel_survived = 1; + pthread_testcancel(); + + PANIC("child 3"); +} + +int +main() +{ + pthread_t child1, child2, child3; + + /* Set up our control flow */ + CHECKr(pthread_mutex_init(&mutex, NULL)); + CHECKr(pthread_cond_init(&cond, NULL)); + CHECKe(clock_gettime(CLOCK_REALTIME, &expiretime)); + expiretime.tv_sec += 5; /* this test shouldn't run over 5 seconds */ + + CHECKr(pthread_create(&child1, NULL, child1fn, NULL)); + CHECKr(pthread_create(&child2, NULL, child2fn, NULL)); + p(); + p(); + + CHECKr(pthread_cancel(child1)); + p(); + + /* Give thread 2 a chance to go through its deferred loop once */ + sleep(2); + CHECKr(pthread_cancel(child2)); + p(); + + /* Child 3 cancels itself */ + CHECKr(pthread_create(&child3, NULL, child3fn, NULL)); + p(); + + /* Make sure they're all gone */ + CHECKr(pthread_join(child3, NULL)); + CHECKr(pthread_join(child2, NULL)); + CHECKr(pthread_join(child1, NULL)); + + exit(0); +} diff --git a/regress/lib/libpthread/close/Makefile b/regress/lib/libpthread/close/Makefile new file mode 100644 index 00000000000..d09a10dbd1c --- /dev/null +++ b/regress/lib/libpthread/close/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= close +SRCS= close.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/close/close.c b/regress/lib/libpthread/close/close.c new file mode 100644 index 00000000000..18b64b64f0e --- /dev/null +++ b/regress/lib/libpthread/close/close.c @@ -0,0 +1,100 @@ +/* $OpenBSD: close.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test the semantics of close() while a select() is happening. + * Not a great test. You need the 'discard' service running in inetd for + * this to work. + */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "test.h" + +int fd; + +void* new_thread(void* arg) +{ + fd_set r; + int ret; + char garbage[] = "blah blah blah"; + + FD_ZERO(&r); + FD_SET(fd, &r); + + printf("child: writing some garbage to fd %d\n", fd); + CHECKe(write(fd, garbage, sizeof garbage)); + printf("child: calling select() with fd %d\n", fd); + CHECKe(ret = select(fd + 1, &r, NULL, NULL, NULL)); + printf("child: select() returned %d\n", ret); + return NULL; +} + +int +main() +{ + pthread_t thread; + pthread_attr_t attr; + struct sockaddr_in addr; + int ret; + + /* Open up a TCP connection to the local discard port */ + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(9); /* port 9/tcp is discard service */ + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + printf("main: connecting to discard port with fd %d\n", fd); + ret = connect(fd, (struct sockaddr *)&addr, sizeof addr); + if (ret == -1) + fprintf(stderr, "connect() failed: ensure that the discard port is enabled for inetd(8)\n"); + CHECKe(ret); + printf("main: connected on fd %d\n", fd); + + CHECKr(pthread_attr_init(&attr)); + CHECKe(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); + printf("starting child thread\n"); + CHECKr(pthread_create(&thread, &attr, new_thread, NULL)); + sleep(1); + printf("main: closing fd %d\n", fd); + CHECKe(close(fd)); + printf("main: closed\n"); + sleep(1); + SUCCEED; +} diff --git a/regress/lib/libpthread/cwd/Makefile b/regress/lib/libpthread/cwd/Makefile new file mode 100644 index 00000000000..0821e066592 --- /dev/null +++ b/regress/lib/libpthread/cwd/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= cwd +SRCS= cwd.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/cwd/cwd.c b/regress/lib/libpthread/cwd/cwd.c new file mode 100644 index 00000000000..2480a825ef4 --- /dev/null +++ b/regress/lib/libpthread/cwd/cwd.c @@ -0,0 +1,55 @@ +/* $OpenBSD: cwd.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * 'Test' getcwd() and getwd() + */ + +#include <stdio.h> +#include <sys/param.h> +#include <unistd.h> +#include "test.h" + +int +main(int argc, char **argv) +{ + char wd[MAXPATHLEN]; + char *path; + + ASSERT(path = getcwd(wd, sizeof wd)); + printf("getcwd => %s\n", path); + ASSERT(path = getwd(wd)); + printf("getwd => %s\n", path); + SUCCEED; +} diff --git a/regress/lib/libpthread/execve/Makefile b/regress/lib/libpthread/execve/Makefile new file mode 100644 index 00000000000..8a828adb6a3 --- /dev/null +++ b/regress/lib/libpthread/execve/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= execve +SRCS= execve.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/execve/execve.c b/regress/lib/libpthread/execve/execve.c new file mode 100644 index 00000000000..fa4ceac012e --- /dev/null +++ b/regress/lib/libpthread/execve/execve.c @@ -0,0 +1,80 @@ +/* $OpenBSD: execve.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Test execve() and dup2() calls. + */ + +#include <pthread.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include "test.h" + +extern char **environ; +char *argv[] = { + "/bin/echo", + "This line should appear after the execve", + NULL +}; + +char * should_succeed = "This line should be displayed\n"; + +int +main() +{ + int fd; + + printf("This is the first message\n"); + if (isatty(STDOUT_FILENO)) { + char *ttynm; + + CHECKn(ttynm = ttyname(STDOUT_FILENO)); + printf("tty is %s\n", ttynm); + CHECKe(fd = open(ttynm, O_RDWR)); + } else + PANIC("stdout is not a tty: this test needs a tty"); + + CHECKn(printf("This output is necessary to set the stdout fd to NONBLOCKING\n")); + + /* do a dup2 */ + CHECKe(dup2(fd, STDOUT_FILENO)); + CHECKe(write(STDOUT_FILENO, should_succeed, + (size_t)strlen(should_succeed))); + CHECKe(execve(argv[0], argv, environ)); + DIE(errno, "execve %s", argv[0]); +} diff --git a/regress/lib/libpthread/fcntl/Makefile b/regress/lib/libpthread/fcntl/Makefile new file mode 100644 index 00000000000..74f14602f60 --- /dev/null +++ b/regress/lib/libpthread/fcntl/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= fcntl +SRCS= fcntl.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/fcntl/fcntl.c b/regress/lib/libpthread/fcntl/fcntl.c new file mode 100644 index 00000000000..3e054ca67be --- /dev/null +++ b/regress/lib/libpthread/fcntl/fcntl.c @@ -0,0 +1,70 @@ +/* $OpenBSD: fcntl.c,v 1.1.1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test fcntl() flag inheritance across a fork() + */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include "test.h" + +int +main() +{ + int flags, newflags, child; + + CHECKe(flags = fcntl(0, F_GETFL)); + printf("flags = %x\n", flags); + + CHECKe(child = fork()); + switch(child) { + case 0: /* child */ + CHECKe(execlp("./pthread_create", "./pthread_create", + (char *)NULL)); + /* NOTREACHED */ + default: /* parent */ + CHECKe(wait(NULL)); + break; + } + + while(1){ + CHECKe(newflags = fcntl(0, F_GETFL)); + printf ("parent %d flags = %x\n", child, newflags); + sleep(1); + } +} diff --git a/regress/lib/libpthread/fork/Makefile b/regress/lib/libpthread/fork/Makefile new file mode 100644 index 00000000000..d8e724955c6 --- /dev/null +++ b/regress/lib/libpthread/fork/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= fork +SRCS= fork.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/fork/fork.c b/regress/lib/libpthread/fork/fork.c new file mode 100644 index 00000000000..cd227a70ce8 --- /dev/null +++ b/regress/lib/libpthread/fork/fork.c @@ -0,0 +1,126 @@ +/* $OpenBSD: fork.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Test the fork system call. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <sys/wait.h> +#include "test.h" + + +void * +empty(void *arg) +{ + + return (void *)0x12345678; +} + +void * +sleeper(void *arg) +{ + + pthread_set_name_np(pthread_self(), "slpr"); + sleep(10); + PANIC("sleeper timed out"); +} + + +int +main() +{ + int flags; + pthread_t sleeper_thread; + void *result; + int status; + pid_t parent_pid; + pid_t child_pid; + + parent_pid = getpid(); + + CHECKe(flags = fcntl(STDOUT_FILENO, F_GETFL)); + if ((flags & (O_NONBLOCK | O_NDELAY))) { + /* This fails when stdout is /dev/null!? */ + /*CHECKe*/(fcntl(STDOUT_FILENO, F_SETFL, + flags & ~(O_NONBLOCK | O_NDELAY))); + } + + CHECKr(pthread_create(&sleeper_thread, NULL, sleeper, NULL)); + sleep(1); + + printf("forking from pid %d\n", getpid()); + + CHECKe(child_pid = fork()); + if (child_pid == 0) { + /* child: */ + printf("child = pid %d\n", getpid()); + /* Our pid should change */ + ASSERT(getpid() != parent_pid); + /* Our sleeper thread should have disappeared */ + printf("sleeper should have disappeared\n"); + ASSERT(ESRCH == pthread_join(sleeper_thread, &result)); + printf("sleeper disappeared correctly\n"); + /* Test starting another thread */ + CHECKr(pthread_create(&sleeper_thread, NULL, empty, NULL)); + sleep(1); + CHECKr(pthread_join(sleeper_thread, &result)); + ASSERT(result == (void *)0x12345678); + printf("child ok\n"); + _exit(0); + PANIC("child _exit"); + } + + /* parent: */ + printf("parent = pid %d\n", getpid()); + /* Our pid should stay the same */ + ASSERT(getpid() == parent_pid); + /* wait for the child */ + ASSERTe(wait(&status), == child_pid); + /* the child should have called exit(0) */ + ASSERT(WIFEXITED(status)); + ASSERT(WEXITSTATUS(status) == 0); + /* Our sleeper thread should still be around */ + CHECKr(pthread_detach(sleeper_thread)); + printf("parent ok\n"); + SUCCEED; +} diff --git a/regress/lib/libpthread/group/Makefile b/regress/lib/libpthread/group/Makefile new file mode 100644 index 00000000000..b9f1557ba8a --- /dev/null +++ b/regress/lib/libpthread/group/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= group +SRCS= group.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/group/group.c b/regress/lib/libpthread/group/group.c new file mode 100644 index 00000000000..cc81df6cf01 --- /dev/null +++ b/regress/lib/libpthread/group/group.c @@ -0,0 +1,180 @@ +/* $OpenBSD: group.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * Test getgrgid_r() across multiple threads to see if the members list changes. + */ + +#include <pthread.h> +#include <unistd.h> +#include <stdio.h> +#include <grp.h> +#include <sys/types.h> +#include "test.h" + +struct group * getgrgid_r(gid_t, struct group *); + +char fail[] = "fail"; + +pthread_cond_t done; +volatile int done_count; + +pthread_mutex_t display; +pthread_mutex_t display2; + +void* +test(void* arg) +{ + gid_t gid = (int)arg; + gid_t ogid; + struct group grpbuf; + struct group *grp; + char **p; + char buf[2048]; + char *cpy[128]; + int i; + int count1, count2; + char *s; + char *oname; + char *opasswd; + + /* Acquire lock for running first part. */ + CHECKr(pthread_mutex_lock(&display)); + + /* Store magic name to test for non-alteration */ + grpbuf.gr_name = fail; + + /* Call getgrgid_r() */ + printf("gid %d\n", gid); + CHECKn(grp = getgrgid_r(gid, &grpbuf)); + + /* Test for non-alteration of group structure */ + ASSERT(grp->gr_name != fail); + + /* We must get the right group */ + ASSERT(grp->gr_gid == gid); + + s = buf; /* Keep our private buffer on the stack */ + + /* copy gr_name */ + strcpy(oname = s, grp->gr_name); + s += 1 + strlen(s); + + /* copy gr_passwd */ + strcpy(opasswd = s, grp->gr_passwd); + s += 1 + strlen(s); + + /* copy gr_gid */ + ogid = grp->gr_gid; + + /* copy gr_mem */ + for (i = 0, p = grp->gr_mem; *p; p++) { + strcpy(cpy[i] = s, *p); i++; + s += 1 + strlen(s); + } + cpy[i] = NULL; + +#if 0 + printf("now: %s:%s:%d:", grp->gr_name, grp->gr_passwd, grp->gr_gid); + for (p = grp->gr_mem; *p; p++) + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + printf("\n"); +#endif + +#ifdef DEBUG /* debugging this program */ + printf("buf = \""); + for (i = 0; i < s - buf; i++) + if (buf[i] == '\0') printf("\\0"); + else printf("%c", buf[i]); + printf("\"\n"); +#endif + + /* Inform main that we have finished */ + done_count++; + CHECKr(pthread_cond_signal(&done)); + + /* Allow other threads to run first part */ + CHECKr(pthread_mutex_unlock(&display)); + + /* Acquire lock for the second part */ + CHECKr(pthread_mutex_lock(&display2)); + + count1 = 0; + printf("before: %s:%s:%d:", oname, opasswd, ogid); + for (p = cpy; *p; p++) { + count1++; + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + } + printf("\n"); + + count2 = 0; + printf("after: %s:%s:%d:", grp->gr_name, grp->gr_passwd, grp->gr_gid); + for (p = grp->gr_mem; *p; p++) { + count2++; + printf("%s%s", *p, *(p+1) == NULL ? "": ","); + } + printf("\n"); + + CHECKr(pthread_mutex_unlock(&display2)); + + if (count1 != count2) + return "gr_mem length changed"; + for (i = 0; i < count1; i++) + if (strcmp(cpy[i], grp->gr_mem[i]) != 0) + return "gr_mem list changed"; + if (strcmp(grp->gr_name, oname) != 0) + return "gr_name changed"; + if (strcmp(grp->gr_passwd, opasswd) != 0) + return "gr_passwd changed"; + if (grp->gr_gid != ogid) + return "gr_gid changed"; + return NULL; +} + + +#define NGRPS 5 +int +main() +{ + pthread_t thread[NGRPS]; + int gid; + int failed; + void *result; + + CHECKr(pthread_mutex_init(&display, NULL)); + CHECKr(pthread_mutex_init(&display2, NULL)); + + CHECKr(pthread_cond_init(&done, NULL)); + done_count = 0; + + pthread_mutex_lock(&display); + pthread_mutex_lock(&display2); + + /* Get separate threads to do a group open separately */ + for (gid = 0; gid < NGRPS; gid++) { + CHECKr(pthread_create(&thread[gid], NULL, test, (void *)gid)); + } + + /* Allow all threads to run their first part */ + while (done_count < NGRPS) + pthread_cond_wait(&done, &display); + + /* Allow each thread to run the 2nd part of its test */ + CHECKr(pthread_mutex_unlock(&display2)); + + /* Wait for each thread to terminate, collecting results. */ + failed = 0; + for (gid = 0; gid < NGRPS; gid++) { + CHECKr(pthread_join(thread[gid], &result)); + if (result != NULL) { + fprintf(stderr, "gid %d: %s\n", gid, (char *)result); + failed++; + } + } + + if (!failed) { + SUCCEED; + } else { + exit(1); + } +} diff --git a/regress/lib/libpthread/include/test.h b/regress/lib/libpthread/include/test.h new file mode 100644 index 00000000000..3d329bf90eb --- /dev/null +++ b/regress/lib/libpthread/include/test.h @@ -0,0 +1,123 @@ +/* $OpenBSD: test.h,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ + +#ifndef _h_test_ +#define _h_test_ + +#include <stdio.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> + +int _thread_sys_write __P((int, const char*, size_t)); +__dead void _thread_sys__exit __P((int)) __attribute__((__noreturn__)); + +static __dead void __vpanic __P((const char *, const char *, const char *, + int, const char *, va_list)) __attribute__((__noreturn__)); +static __dead void __panic __P((const char *, const char *, const char *, + int, const char *, ...)) __attribute__((__noreturn__)); + +#if defined(__OpenBSD__) || defined(__FreeBSD__) +#include <pthread.h> +#include <pthread_np.h> +void _thread_dump_info __P((void)); +#define SET_NAME(x) pthread_set_name_np(pthread_self(), x) +#define DUMP_INFO() _thread_dump_info() +#else +#define SET_NAME(x) /* nada */ +#define DUMP_INFO() /* nada */ +#endif + +static void +__vpanic(type, errstr, filenm, lineno, fmt, ap) + const char *type; + const char *errstr; + const char *filenm; + int lineno; + const char *fmt; + va_list ap; +{ + char buf[1024]; + + /* "<type> at <filenm>:<lineno>: <fmt ap...>:<errstr>" */ + snprintf(buf, sizeof buf, "%s at %s:%d\n", type, filenm, lineno); + _thread_sys_write(2, buf, strlen(buf)); + vsnprintf(buf, sizeof buf, fmt, ap); + if (errstr != NULL) { + strlcat(buf, ": ", sizeof buf); + strlcat(buf, errstr, sizeof buf); + } + strlcat(buf, "\n", sizeof buf); + _thread_sys_write(2, buf, strlen(buf)); + + DUMP_INFO(); + _thread_sys__exit(1); + + _thread_sys_write(2, "[locking]\n", 10); + while(1); +} + +static void +__panic(type, errstr, filenm, lineno, fmt) + const char *type; + const char *errstr; + const char *filenm; + int lineno; + const char *fmt; +{ + va_list ap; + + va_start(ap, fmt); + __vpanic(type, errstr, filenm, lineno, fmt, ap); + va_end(ap); +} + +#define DIE(e, m, args...) \ + __panic("died", strerror(e), __FILE__, __LINE__, m , ## args) + +#define PANIC(m, args...) \ + __panic("panic", NULL, __FILE__, __LINE__, m, ## args) + +#define ASSERT(x) do { \ + if (!(x)) \ + __panic("assert failed", NULL, __FILE__, __LINE__, "%s", #x); \ +} while(0) + +#define ASSERTe(x,rhs) do { \ + int _x; \ + _x = (x); \ + if (!(_x rhs)) { \ + if (_x > 0) \ + __panic("assert failed", strerror(_x), __FILE__, __LINE__, \ + "%s %s", #x, #rhs); \ + else \ + __panic("assert failed", NULL, __FILE__, __LINE__, \ + "%s [=%d] %s", #x, _x, #rhs); \ + } \ +} while(0) + +#define _T(x) __builtin_classify_type(x) + +#define _CHECK(x, rhs, efn) do { \ + typeof(x) _x; \ + _x = (x); \ + if (!(_x rhs)) \ + __panic("check failed", efn, __FILE__, __LINE__, \ + ((_T(0) == _T(_x) )? "failed check %s (=%d) %s " : \ + (_T("") == _T(_x) )? "failed check %s (=%s) %s " : \ + (_T('x') == _T(_x) )? "failed check %s (=%c) %s " : \ + (_T(0L) == _T(_x) )? "failed check %s (=%ld) %s " : "?") \ + , #x, _x, #rhs); \ +} while(0) + +#define CHECKr(x) _CHECK(x, == 0, strerror(_x)) +#define CHECKe(x) _CHECK(x, != -1, strerror(errno)) +#define CHECKn(x) _CHECK(x, != 0, strerror(errno)) +#define CHECKhn(x) _CHECK(x, != 0, hstrerror(h_errno)) + +#define SUCCEED exit(0) + +#define OK (0) +#define NOTOK (-1) + +#endif _h_test_ diff --git a/regress/lib/libpthread/netdb/Makefile b/regress/lib/libpthread/netdb/Makefile new file mode 100644 index 00000000000..7b293a620c5 --- /dev/null +++ b/regress/lib/libpthread/netdb/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= netdb +SRCS= netdb.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/netdb/netdb.c b/regress/lib/libpthread/netdb/netdb.c new file mode 100644 index 00000000000..cf4d59e0560 --- /dev/null +++ b/regress/lib/libpthread/netdb/netdb.c @@ -0,0 +1,84 @@ +/* $OpenBSD: netdb.c,v 1.1 2001/08/15 14:37:11 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1995 by Greg Hudson, ghudson@.mit.edu + * + * Test netdb calls. + */ + +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#include "test.h" + +static void test_serv() +{ + struct servent *serv; + + CHECKhn(serv = getservbyname("telnet", "tcp")); + printf("getservbyname -> port %d\n", ntohs(serv->s_port)); +} + +static void test_host() +{ + struct hostent *host; + struct in_addr addr; + + CHECKhn(host = gethostbyname("localhost")); + memcpy(&addr, host->h_addr, sizeof(addr)); + printf("gethostbyname -> %s\n", inet_ntoa(addr)); +} + +static void test_localhost() +{ + struct hostent *host; + + CHECKhn(host = gethostbyname("127.0.0.1")); +} + +int +main(int argc, char **argv) +{ + test_serv(); + test_localhost(); + test_host(); + + SUCCEED; +} diff --git a/regress/lib/libpthread/pause/Makefile b/regress/lib/libpthread/pause/Makefile new file mode 100644 index 00000000000..588a25ec48c --- /dev/null +++ b/regress/lib/libpthread/pause/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:11 fgsch Exp $ + +PROG= pause +SRCS= pause.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pause/pause.c b/regress/lib/libpthread/pause/pause.c new file mode 100644 index 00000000000..8185e7ca2d0 --- /dev/null +++ b/regress/lib/libpthread/pause/pause.c @@ -0,0 +1,68 @@ +/* $OpenBSD: pause.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Test pause() + */ + +#include <stdio.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include "test.h" + +int gotsig = 0; + +void +handler(sig) + int sig; +{ + printf("%s\n", strsignal(sig)); +} + +int +main() +{ + sigset_t all; + pid_t self; + + ASSERT(signal(SIGHUP, handler) != SIG_ERR); + CHECKe(self = getpid()); + CHECKe(sigemptyset(&all)); + CHECKe(sigaddset(&all, SIGHUP)); + CHECKe(sigprocmask(SIG_BLOCK, &all, NULL)); + CHECKe(kill(self, SIGHUP)); + CHECKe(pause()); + SUCCEED; +} diff --git a/regress/lib/libpthread/poll/Makefile b/regress/lib/libpthread/poll/Makefile new file mode 100644 index 00000000000..1d2503867e4 --- /dev/null +++ b/regress/lib/libpthread/poll/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= poll +SRCS= poll.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/poll/poll.c b/regress/lib/libpthread/poll/poll.c new file mode 100644 index 00000000000..360f8f800cb --- /dev/null +++ b/regress/lib/libpthread/poll/poll.c @@ -0,0 +1,136 @@ +/* $OpenBSD: poll.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +#include <pthread.h> +#include <fcntl.h> +#include <poll.h> +#include <paths.h> +#include <unistd.h> +#include "test.h" + + +#define POLLALL (POLLIN|POLLOUT|POLLERR|POLLNVAL) + +static void +print_pollfd(p) + struct pollfd *p; +{ + + printf("{fd=%d, events=< %s%s%s> revents=< %s%s%s%s%s>}", + p->fd, + p->events & POLLIN ? "in " : "", + p->events & POLLOUT ? "out " : "", + p->events & ~(POLLIN|POLLOUT) ? "XXX " : "", + p->revents & POLLIN ? "in " : "", + p->revents & POLLOUT ? "out " : "", + p->revents & POLLERR ? "err " : "", + p->revents & POLLHUP ? "hup " : "", + p->revents & POLLNVAL ? "nval " : "" + ); +} + +static void * +writer(arg) + void *arg; +{ + int fd = (int)arg; + const char msg[1] = { '!' }; + + ASSERTe(write(fd, &msg, sizeof msg), == sizeof msg); + return NULL; +} + +static void * +reader(arg) + void *arg; +{ + int fd = (int)arg; + char buf[1]; + + ASSERTe(read(fd, &buf, sizeof buf), == sizeof buf); + return NULL; +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t t; + void *result; + int null, zero, tty; + int tube[2]; + struct pollfd p[3]; + + /* Try an empty poll set */ + ASSERTe(poll(NULL, 0, 0), == 0); + + CHECKe(zero = open(_PATH_DEV "zero", O_RDONLY)); + CHECKe(null = open(_PATH_DEV "null", O_WRONLY)); + CHECKe(tty = open(_PATH_DEV "tty", O_WRONLY)); + + /* Try both descriptors being ready */ + p[0].fd = zero; + p[0].events = POLLIN|POLLOUT; + p[0].revents = 0; + p[1].fd = null; + p[1].events = POLLIN|POLLOUT; + p[1].revents = 0; + + ASSERTe(poll(p, 2, 0), == 2); /* if 4 then bug in kernel not fixed */ + printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("null p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT((p[0].revents & POLLIN) == POLLIN); + ASSERT((p[1].revents & POLLOUT) == POLLOUT); + + /* + * Try one of the descriptors being invalid + * and the other ready + */ + printf("closing zero\n"); + close(zero); + + p[0].fd = zero; + p[0].events = POLLIN|POLLOUT; + p[1].fd = null; + p[1].events = POLLIN|POLLOUT; + ASSERTe(poll(p, 2, 0), == 2); /* again, old kernels had this bug */ + printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("null p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT((p[0].revents & POLLNVAL) == POLLNVAL); + ASSERT((p[1].revents & POLLOUT) == POLLOUT); + + printf("closing null\n"); + close(null); + + /* + * New pipes. the write end should be writable (buffered) + */ + CHECKe(pipe(tube)); + CHECKe(fcntl(tube[0], F_SETFL, O_NONBLOCK)); + CHECKe(fcntl(tube[1], F_SETFL, O_NONBLOCK)); + + p[0].fd = tube[0]; + p[0].events = POLLIN; + p[1].fd = tube[1]; + p[1].events = POLLOUT; + ASSERTe(poll(p, 2, 0), == 1); + printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n'); + printf("wpipe p[1]="); print_pollfd(&p[1]); putchar('\n'); + ASSERT(p[0].revents == 0); + ASSERT(p[1].revents == POLLOUT); + + /* Start a writing thread to the write end [1] */ + printf("bg writing to wpipe\n"); + CHECKr(pthread_create(&t, NULL, writer, (void *)tube[1])); + /* The read end [0] should soon be ready for read (POLLIN) */ + p[0].fd = tube[0]; + p[0].events = POLLIN; + ASSERTe(poll(p, 1, INFTIM), == 1); + printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n'); + ASSERT(p[0].revents == POLLIN); + reader((void *)tube[0]); /* consume */ + CHECKr(pthread_join(t, &result)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/preemption/Makefile b/regress/lib/libpthread/preemption/Makefile new file mode 100644 index 00000000000..8370c6cc399 --- /dev/null +++ b/regress/lib/libpthread/preemption/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= preemption +SRCS= preemption.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/preemption/preemption.c b/regress/lib/libpthread/preemption/preemption.c new file mode 100644 index 00000000000..ef0829ce4f5 --- /dev/null +++ b/regress/lib/libpthread/preemption/preemption.c @@ -0,0 +1,73 @@ +/* $OpenBSD: preemption.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_cond(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include "test.h" + +void * +new_thread(void * new_buf) +{ + int i; + + printf("yielding:"); + for (i = 0; i < 10; i++) { + printf(" %d", i); + fflush(stdout); + pthread_yield(); + } + printf("\n"); + SUCCEED; +} + +int +main() +{ + pthread_t thread; + + CHECKr(pthread_create(&thread, NULL, new_thread, NULL)); + + while(1) + ; + PANIC("while"); +} diff --git a/regress/lib/libpthread/preemption_float/Makefile b/regress/lib/libpthread/preemption_float/Makefile new file mode 100644 index 00000000000..91ad73e48a7 --- /dev/null +++ b/regress/lib/libpthread/preemption_float/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= preemption_float +SRCS= preemption_float.c +#DPADD= ${LIBM} +#LDADD= -lm + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/preemption_float/preemption_float.c b/regress/lib/libpthread/preemption_float/preemption_float.c new file mode 100644 index 00000000000..3aa810689fd --- /dev/null +++ b/regress/lib/libpthread/preemption_float/preemption_float.c @@ -0,0 +1,148 @@ +/* $OpenBSD: preemption_float.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* Test to see if floating point state is being properly maintained + for each thread. Different threads doing floating point operations + simultaneously should not interfere with one another. This + includes operations that might change some FPU flags, such as + rounding modes, at least implicitly. */ + +#include <pthread.h> +#include <math.h> +#include <stdio.h> +#include "test.h" + +int limit = 2; +int float_passed = 0; +int float_failed = 1; + +void *log_loop (void *x) { + int i; + double d, d1, d2; + /* sleep (1); */ + for (i = 0; i < limit; i++) { + d = 42.0; + d = log (exp (d)); + d = (d + 39.0) / d; + if (i == 0) + d1 = d; + else { + d2 = d; + d = sin(d); + /* if (d2 != d1) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +void *trig_loop (void *x) { + int i; + double d, d1, d2; + /* sleep (1); */ + for (i = 0; i < limit; i++) { + d = 35.0; + d *= M_PI; + d /= M_LN2; + d = sin (d); + d = cos (1 / d); + if (i == 0) + d1 = d; + else { + d2 = d; + d = sin(d); + /* if (d2 != d1) { */ + if (memcmp (&d2, &d1, 8)) { + pthread_exit(&float_failed); + } + } + } + pthread_exit(&float_passed); +} + +int +floatloop(pthread_attr_t *attrp) +{ + pthread_t thread[2]; + int *x, *y; + + CHECKr(pthread_create (&thread[0], attrp, trig_loop, 0)); + CHECKr(pthread_create (&thread[1], attrp, log_loop, 0)); + CHECKr(pthread_join(thread[0], (void **) &x)); + CHECKr(pthread_join(thread[1], (void **) &y)); + + /* Return 0 for success */ + return ((*y == float_failed)?2:0) | + ((*x == float_failed)?1:0); +} + +#define N 10 +int +main() +{ + pthread_attr_t attr; + int i; + + /* Try with float point state not preserved */ + + CHECKr(pthread_attr_init(&attr)); + CHECKr(pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT)); + + for(limit = 2; limit < 100000; limit *=4) + if (floatloop(&attr) != 0) + break; + + if (limit >= 100000) { + printf("results are INDETERMINATE\n"); + SUCCEED; /* XXX */ + } + + limit *= 4; /* just to make sure */ + + printf("using limit = %d\n", limit); + + for (i = 0; i < 32; i++) { + /* Try the failure mode one more time. */ + if (floatloop(&attr) == 0) { + printf("%d ", i); + fflush(stdout); + } + /* Now see if saving float state will get rid of failure. */ + ASSERT(floatloop(NULL) == 0); + } + + SUCCEED; +} diff --git a/regress/lib/libpthread/pthread_cond_timedwait/Makefile b/regress/lib/libpthread/pthread_cond_timedwait/Makefile new file mode 100644 index 00000000000..487f916efe7 --- /dev/null +++ b/regress/lib/libpthread/pthread_cond_timedwait/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_cond_timedwait +SRCS= pthread_cond_timedwait.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pthread_cond_timedwait/pthread_cond_timedwait.c b/regress/lib/libpthread/pthread_cond_timedwait/pthread_cond_timedwait.c new file mode 100644 index 00000000000..3f34eb44c40 --- /dev/null +++ b/regress/lib/libpthread/pthread_cond_timedwait/pthread_cond_timedwait.c @@ -0,0 +1,113 @@ +/* $OpenBSD: pthread_cond_timedwait.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_cond(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include "test.h" + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +void* thread_1(void * new_buf) +{ + CHECKr(pthread_mutex_lock(&mutex)); + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); + pthread_exit(NULL); +} + +void* thread_2(void * new_buf) +{ + sleep(1); + CHECKr(pthread_mutex_lock(&mutex)); + CHECKr(pthread_cond_signal(&cond)); + CHECKr(pthread_mutex_unlock(&mutex)); + pthread_exit(NULL); +} + +int +main() +{ + struct timespec abstime = { 0, 0 }; + struct timeval curtime; + pthread_t thread; + int ret; + + printf("pthread_cond_timedwait START\n"); + + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(gettimeofday(&curtime, NULL)); + abstime.tv_sec = curtime.tv_sec + 5; + + /* Test a condition timeout */ + switch((ret = pthread_cond_timedwait(&cond, &mutex, &abstime))) { + case 0: + PANIC("pthread_cond_timedwait #0 failed to timeout"); + /* NOTREACHED */ + case ETIMEDOUT: + /* expected behaviour */ + printf("Got first timeout ok\n"); /* Added by monty */ + break; + default: + DIE(ret, "pthread_cond_timedwait"); + /* NOTREACHED */ + } + + /* Test a normal condition signal */ + CHECKr(pthread_create(&thread, NULL, thread_1, NULL)); + + abstime.tv_sec = curtime.tv_sec + 10; + CHECKr(pthread_cond_timedwait(&cond, &mutex, &abstime)); + + /* Test a normal condition signal after a sleep */ + CHECKr(pthread_create(&thread, NULL, thread_2, NULL)); + + pthread_yield(); + + abstime.tv_sec = curtime.tv_sec + 10; + CHECKr(pthread_cond_timedwait(&cond, &mutex, &abstime)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/pthread_create/Makefile b/regress/lib/libpthread/pthread_create/Makefile new file mode 100644 index 00000000000..8ecea5ff1ca --- /dev/null +++ b/regress/lib/libpthread/pthread_create/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= pthread_create +SRCS= pthread_create.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pthread_create/pthread_create.c b/regress/lib/libpthread/pthread_create/pthread_create.c new file mode 100644 index 00000000000..ccc2a6c4292 --- /dev/null +++ b/regress/lib/libpthread/pthread_create/pthread_create.c @@ -0,0 +1,66 @@ +/* $OpenBSD: pthread_create.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Test pthread_create() and pthread_exit() calls. + */ + +#include <pthread.h> +#include <stdio.h> +#include "test.h" + +void* new_thread(void* arg) +{ + int i; + + printf("New thread was passed arg address %p\n", arg); + printf("New thread stack at %p\n", &i); + return(NULL); + PANIC("return"); +} + +int +main() +{ + pthread_t thread; + int i; + + printf("Original thread stack at %p\n", &i); + CHECKr(pthread_create(&thread, NULL, new_thread, + (void *)0xdeadbeef)); + CHECKr(pthread_join(thread, NULL)); + SUCCEED; +} diff --git a/regress/lib/libpthread/pthread_join/Makefile b/regress/lib/libpthread/pthread_join/Makefile new file mode 100644 index 00000000000..fed1bdca2be --- /dev/null +++ b/regress/lib/libpthread/pthread_join/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_join +SRCS= pthread_join.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pthread_join/pthread_join.c b/regress/lib/libpthread/pthread_join/pthread_join.c new file mode 100644 index 00000000000..a8637caa887 --- /dev/null +++ b/regress/lib/libpthread/pthread_join/pthread_join.c @@ -0,0 +1,98 @@ +/* $OpenBSD: pthread_join.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_join.c ================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_join(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <unistd.h> +#include <stdio.h> +#include "test.h" + +/* This thread yields so the creator has a live thread to wait on */ +void* new_thread_1(void * new_buf) +{ + int i; + + sprintf((char *)new_buf, "New thread %%d stack at %p\n", &i); + pthread_yield(); /* (ensure parent can wait on live thread) */ + sleep(1); + return(new_buf); + PANIC("return"); +} + +/* This thread doesn't yield so the creator has a dead thread to wait on */ +void* new_thread_2(void * new_buf) +{ + int i; + + sprintf((char *)new_buf, "New thread %%d stack at %p\n", &i); + return(new_buf); + PANIC("return"); +} + +int +main() +{ + char buf[256], *status; + pthread_t thread; + int debug = 1; + int i = 0; + + if (debug) + printf("Original thread stack at %p\n", &i); + + CHECKr(pthread_create(&thread, NULL, new_thread_1, (void *)buf)); + CHECKr(pthread_join(thread, (void **)(&status))); + if (debug) + printf(status, ++i); + + /* Now have the created thread finishing before the join. */ + CHECKr(pthread_create(&thread, NULL, new_thread_2, (void *)buf)); + pthread_yield(); + sleep(1); /* (ensure thread is dead) */ + CHECKr(pthread_join(thread, (void **)(&status))); + + if (debug) + printf(status, ++i); + + SUCCEED; +} + diff --git a/regress/lib/libpthread/pthread_mutex/Makefile b/regress/lib/libpthread/pthread_mutex/Makefile new file mode 100644 index 00000000000..050627af875 --- /dev/null +++ b/regress/lib/libpthread/pthread_mutex/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pthread_mutex +SRCS= pthread_mutex.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pthread_mutex/pthread_mutex.c b/regress/lib/libpthread/pthread_mutex/pthread_mutex.c new file mode 100644 index 00000000000..1375231bca2 --- /dev/null +++ b/regress/lib/libpthread/pthread_mutex/pthread_mutex.c @@ -0,0 +1,194 @@ +/* $OpenBSD: pthread_mutex.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_pthread_cond.c ========================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_mutex(). Run this after test_create() + * + * 1.23 94/05/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include "test.h" + +int contention_variable; + +void * +thread_contention(arg) + void *arg; +{ + pthread_mutex_t *mutex = arg; + + SET_NAME("cntntn"); + + CHECKr(pthread_mutex_lock(mutex)); + ASSERT(contention_variable == 1); + contention_variable = 2; + CHECKr(pthread_mutex_unlock(mutex)); + pthread_exit(NULL); +} + +void +test_contention_lock(mutex) + pthread_mutex_t *mutex; +{ + pthread_t thread; + + printf(" test_contention_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + contention_variable = 0; + CHECKr(pthread_create(&thread, NULL, thread_contention, mutex)); + pthread_yield(); + contention_variable = 1; + CHECKr(pthread_mutex_unlock(mutex)); + CHECKr(pthread_mutex_lock(mutex)); + ASSERT(contention_variable == 2); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_nocontention_lock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_nocontention_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_debug_double_lock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_debug_double_lock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + ASSERTe(pthread_mutex_lock(mutex), == EDEADLK); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_debug_double_unlock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_debug_double_unlock()\n"); + CHECKr(pthread_mutex_lock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); + /* Posix D10 says undefined behaviour? */ + ASSERTe(pthread_mutex_unlock(mutex), != EPERM); +} + +void +test_nocontention_trylock(mutex) + pthread_mutex_t *mutex; +{ + printf(" test_nocontention_trylock()\n"); + CHECKr(pthread_mutex_trylock(mutex)); + CHECKr(pthread_mutex_unlock(mutex)); +} + +void +test_mutex_static() +{ + pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER; + + printf("test_mutex_static()\n"); + test_nocontention_lock(&mutex_static); + test_contention_lock(&mutex_static); +} + +void +test_mutex_fast(void) +{ + pthread_mutex_t mutex_fast; + + printf("test_mutex_fast()\n"); + CHECKr(pthread_mutex_init(&mutex_fast, NULL)); + test_nocontention_lock(&mutex_fast); + test_contention_lock(&mutex_fast); + CHECKr(pthread_mutex_destroy(&mutex_fast)); +} + +void +test_mutex_debug() +{ + pthread_mutexattr_t mutex_debug_attr; + pthread_mutex_t mutex_debug; + + printf("test_mutex_debug()\n"); + CHECKr(pthread_mutexattr_init(&mutex_debug_attr)); + CHECKr(pthread_mutexattr_settype(&mutex_debug_attr, + PTHREAD_MUTEX_ERRORCHECK)); + CHECKr(pthread_mutex_init(&mutex_debug, &mutex_debug_attr)); + test_nocontention_lock(&mutex_debug); + test_contention_lock(&mutex_debug); + test_debug_double_lock(&mutex_debug); + test_debug_double_unlock(&mutex_debug); + CHECKr(pthread_mutex_destroy(&mutex_debug)); +} + +void +test_mutex_recursive() +{ + pthread_mutexattr_t mutex_recursive_attr; + pthread_mutex_t mutex_recursive; + int i; + + printf("test_mutex_recursive()\n"); + CHECKr(pthread_mutexattr_init(&mutex_recursive_attr)); + CHECKr(pthread_mutexattr_settype(&mutex_recursive_attr, + PTHREAD_MUTEX_RECURSIVE)); + CHECKr(pthread_mutex_init(&mutex_recursive, &mutex_recursive_attr)); + + CHECKr(pthread_mutex_lock(&mutex_recursive)); + for (i = 0; i < 9; i++) + CHECKr(pthread_mutex_lock(&mutex_recursive)); + for (i = 0; i < 9; i++) + CHECKr(pthread_mutex_unlock(&mutex_recursive)); + CHECKr(pthread_mutex_unlock(&mutex_recursive)); + /* Posix D10 says undefined behaviour? */ + ASSERTe(pthread_mutex_unlock(&mutex_recursive), != 0); +} + +int +main() +{ + test_mutex_static(); + test_mutex_fast(); + test_mutex_debug(); + test_mutex_recursive(); + SUCCEED; +} diff --git a/regress/lib/libpthread/pw/Makefile b/regress/lib/libpthread/pw/Makefile new file mode 100644 index 00000000000..f5d21c798ac --- /dev/null +++ b/regress/lib/libpthread/pw/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= pw +SRCS= pw.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/pw/pw.c b/regress/lib/libpthread/pw/pw.c new file mode 100644 index 00000000000..fc7beec4963 --- /dev/null +++ b/regress/lib/libpthread/pw/pw.c @@ -0,0 +1,61 @@ +/* $OpenBSD: pw.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <pwd.h> +#include "test.h" + +int +main() +{ + struct passwd *pw; + struct passwd pwbuf; + char buf[8192]; + char name[16]; + + CHECKn(pw = getpwuid(getuid())); + printf("getpwuid(%d) => %p\n", getuid(), pw); + printf(" name: %s\n uid: %d\n gid: %d\n" + "class: %s\ngecos: %s\n dir: %s\nshell: %s\n", + pw->pw_name, pw->pw_uid, pw->pw_gid, + pw->pw_class, pw->pw_gecos, pw->pw_dir, pw->pw_shell); + + strlcpy(name, pw->pw_name, sizeof name); + CHECKe(getpwnam_r(name, &pwbuf, buf, sizeof buf, &pw)); + ASSERT(pwbuf.pw_uid == getuid()); + + SUCCEED; +} diff --git a/regress/lib/libpthread/readdir/Makefile b/regress/lib/libpthread/readdir/Makefile new file mode 100644 index 00000000000..c1c1e68a135 --- /dev/null +++ b/regress/lib/libpthread/readdir/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= readdir +SRCS= readdir.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/readdir/readdir.c b/regress/lib/libpthread/readdir/readdir.c new file mode 100644 index 00000000000..7d2c6ce26d4 --- /dev/null +++ b/regress/lib/libpthread/readdir/readdir.c @@ -0,0 +1,65 @@ +/* $OpenBSD: readdir.c,v 1.1 2001/08/15 14:37:12 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_readdir.c ======================================================== + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 94/05/19 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <dirent.h> +#include <stdio.h> +#include "test.h" + +int +main() +{ + struct dirent * file; + DIR * dot_dir; + int found = 0; + + CHECKn(dot_dir = opendir(".")); + while ((file = readdir(dot_dir)) != NULL) + if (strcmp("readdir", file->d_name) == 0) + found = 1; + CHECKe(closedir(dot_dir)); + ASSERT(found); + SUCCEED; +} + diff --git a/regress/lib/libpthread/select/Makefile b/regress/lib/libpthread/select/Makefile new file mode 100644 index 00000000000..af34834aebc --- /dev/null +++ b/regress/lib/libpthread/select/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:12 fgsch Exp $ + +PROG= select +SRCS= select.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/select/select.c b/regress/lib/libpthread/select/select.c new file mode 100644 index 00000000000..666ed9ef083 --- /dev/null +++ b/regress/lib/libpthread/select/select.c @@ -0,0 +1,152 @@ +/* $OpenBSD: select.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* + * Rudimentary test of select(). + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <stdio.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <errno.h> +#include <unistd.h> +#include "test.h" + +#define NLOOPS 10000 + +int ntouts = 0; + +void * +bg_routine(arg) + void *arg; +{ + char dot = '.'; + int n; + + SET_NAME("bg"); + + /* Busy loop, printing dots */ + for (;;) { + pthread_yield(); + write(STDOUT_FILENO, &dot, sizeof dot); + pthread_yield(); + n = NLOOPS; + while (n-- > 0) + pthread_yield(); + } +} + +void * +fg_routine(arg) + void *arg; +{ + int flags; + int n; + fd_set r; + int fd = fileno((FILE *) arg); + int tty = isatty(fd); + int maxfd; + int nb; + char buf[128]; + + SET_NAME("fg"); + + /* Set the file descriptor to non-blocking */ + flags = fcntl(fd, F_GETFL); + CHECKr(fcntl(fd, F_SETFL, flags | O_NONBLOCK)); + + for (;;) { + + /* Print a prompt if it's a tty: */ + if (tty) { + printf("type something> "); + fflush(stdout); + } + + /* Select on the fdesc: */ + FD_ZERO(&r); + FD_SET(fd, &r); + maxfd = fd; + errno = 0; + CHECKe(n = select(maxfd + 1, &r, (fd_set *) 0, (fd_set *) 0, + (struct timeval *) 0)); + + if (n > 0) { + /* Something was ready for read. */ + printf("select returned %d\n", n); + while ((nb = read(fd, buf, sizeof(buf) - 1)) > 0) { + printf("read %d: `%.*s'\n", nb, nb, buf); + } + printf("last read was %d, errno = %d %s\n", nb, errno, + errno == 0 ? "success" : strerror(errno)); + if (nb < 0) + ASSERTe(errno, == EWOULDBLOCK || + errno == EAGAIN); + if (nb == 0) + break; + } else + ntouts++; + } + printf("read finished\n"); + return (NULL); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + pthread_t bg_thread, fg_thread; + FILE * slpr; + + /* Create a fdesc that will block for a while on read: */ + CHECKn(slpr = popen("sleep 2; echo foo", "r")); + + /* Create a busy loop thread that yields a lot: */ + CHECKr(pthread_create(&bg_thread, NULL, bg_routine, 0)); + + /* Create the thread that reads the fdesc: */ + CHECKr(pthread_create(&fg_thread, NULL, fg_routine, (void *) slpr)); + + /* Wait for the reader thread to finish */ + CHECKr(pthread_join(fg_thread, NULL)); + + /* Clean up*/ + CHECKe(pclose(slpr)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/setjmp/Makefile b/regress/lib/libpthread/setjmp/Makefile new file mode 100644 index 00000000000..26457b3f0fc --- /dev/null +++ b/regress/lib/libpthread/setjmp/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= setjmp +SRCS= setjmp.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/setjmp/setjmp.c b/regress/lib/libpthread/setjmp/setjmp.c new file mode 100644 index 00000000000..45f6feca99d --- /dev/null +++ b/regress/lib/libpthread/setjmp/setjmp.c @@ -0,0 +1,92 @@ +/* $OpenBSD: setjmp.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <setjmp.h> +#include "test.h" + +int reached; + +void * +_jump(arg) + void *arg; +{ + jmp_buf foo; + + reached = 0; + if (_setjmp(foo)) { + ASSERT(reached); + return NULL; + } + reached = 1; + _longjmp(foo, 1); + PANIC("_longjmp"); +} + +void * +jump(arg) + void *arg; +{ + jmp_buf foo; + + reached = 0; + if (setjmp(foo)) { + ASSERT(reached); + return NULL; + } + reached = 1; + longjmp(foo, 1); + PANIC("longjmp"); +} + +int +main() +{ + pthread_t child; + void *res; + + printf("jumping in main thread\n"); + (void)jump(NULL); + printf("_jumping in main thread\n"); + (void)_jump(NULL); + + printf("jumping in child thread\n"); + CHECKr(pthread_create(&child, NULL, jump, NULL)); + CHECKr(pthread_join(child, &res)); + + printf("_jumping in child thread\n"); + CHECKr(pthread_create(&child, NULL, _jump, NULL)); + CHECKr(pthread_join(child, &res)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/signal/Makefile b/regress/lib/libpthread/signal/Makefile new file mode 100644 index 00000000000..b107b790354 --- /dev/null +++ b/regress/lib/libpthread/signal/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= signal +SRCS= signal.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/signal/signal.c b/regress/lib/libpthread/signal/signal.c new file mode 100644 index 00000000000..effc36b7087 --- /dev/null +++ b/regress/lib/libpthread/signal/signal.c @@ -0,0 +1,49 @@ +/* $OpenBSD: signal.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * This program tests signal handler re-entrancy. + */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include "test.h" + +void * +sleeper(arg) + void *arg; +{ + sigset_t mask; + + /* Ignore all signals in this thread */ + sigfillset(&mask); + CHECKe(sigprocmask(SIG_SETMASK, &mask, NULL)); + + ASSERT(sleep(2) == 0); + SUCCEED; +} + +void +handler(sig) + int sig; +{ + printf("signal handler %d\n", sig); + alarm(1); + signal(SIGALRM, handler); +} + +int +main() +{ + pthread_t slpr; + + ASSERT(signal(SIGALRM, handler) != SIG_ERR); + CHECKe(alarm(1)); + CHECKr(pthread_create(&slpr, NULL, sleeper, NULL)); + /* ASSERT(sleep(1) == 0); */ + for (;;) + CHECKe(write(STDOUT_FILENO, ".", 1)); +} diff --git a/regress/lib/libpthread/sigsuspend/Makefile b/regress/lib/libpthread/sigsuspend/Makefile new file mode 100644 index 00000000000..4e0c7a93d2f --- /dev/null +++ b/regress/lib/libpthread/sigsuspend/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= sigsuspend +SRCS= sigsuspend.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/sigsuspend/sigsuspend.c b/regress/lib/libpthread/sigsuspend/sigsuspend.c new file mode 100644 index 00000000000..df3b990dafb --- /dev/null +++ b/regress/lib/libpthread/sigsuspend/sigsuspend.c @@ -0,0 +1,239 @@ +/* $OpenBSD: sigsuspend.c,v 1.1 2001/08/15 14:37:13 fgsch Exp $ */ +/* + * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. + * + */ +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + +#include <pthread_np.h> +#include "test.h" + +static int sigcounts[NSIG + 1]; +static int sigfifo[NSIG + 1]; +static int fifo_depth = 0; +static sigset_t suspender_mask; +static pthread_t suspender_tid; + + +static void * +sigsuspender (void *arg) +{ + int save_count, status, i; + sigset_t run_mask; + + SET_NAME("sigsuspender"); + + /* Run with all signals blocked. */ + sigfillset (&run_mask); + CHECKe(sigprocmask (SIG_SETMASK, &run_mask, NULL)); + + /* Allow these signals to wake us up during a sigsuspend. */ + sigfillset (&suspender_mask); /* Default action */ + sigdelset (&suspender_mask, SIGINT); /* terminate */ + sigdelset (&suspender_mask, SIGHUP); /* terminate */ + sigdelset (&suspender_mask, SIGQUIT); /* create core image */ + sigdelset (&suspender_mask, SIGURG); /* ignore */ + sigdelset (&suspender_mask, SIGIO); /* ignore */ + sigdelset (&suspender_mask, SIGUSR2); /* terminate */ + + while (sigcounts[SIGINT] == 0) { + save_count = sigcounts[SIGUSR2]; + + status = sigsuspend (&suspender_mask); + if ((status == 0) || (errno != EINTR)) { + DIE(errno, "Unable to suspend for signals, " + "return value %d\n", + status); + } + for (i = 0; i < fifo_depth; i++) + printf ("Sigsuspend woke up by signal %d (%s)\n", + sigfifo[i], strsignal(sigfifo[i])); + fifo_depth = 0; + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + sigset_t set; + pthread_t self; + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; + + /* + * If we are running on behalf of the suspender thread, + * ensure that we have the correct mask set. + */ + self = pthread_self (); + if (self == suspender_tid) { + sigfifo[fifo_depth] = signo; + fifo_depth++; + printf (" -> Suspender thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); + sigprocmask (SIG_SETMASK, NULL, &set); + ASSERT(set == suspender_mask); + } + else + printf (" -> Main thread signal handler caught " + "signal %d (%s)\n", signo, strsignal(signo)); +} + + +int main (int argc, char *argv[]) +{ + pthread_attr_t pattr; + struct sigaction act; + sigset_t oldset; + sigset_t newset; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Ignore signal SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* Get our current signal mask. */ + CHECKe(sigprocmask (SIG_SETMASK, NULL, &oldset)); + + /* Mask out SIGUSR1 and SIGUSR2. */ + newset = oldset; + sigaddset (&newset, SIGUSR1); + sigaddset (&newset, SIGUSR2); + CHECKe(sigprocmask (SIG_SETMASK, &newset, NULL)); + + /* Install a signal handler for SIGUSR1 and SIGUSR2 */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGUSR1); + sigaddset (&act.sa_mask, SIGUSR2); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGUSR1, &act, NULL)); + CHECKe(sigaction (SIGUSR2, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Create the sigsuspender thread. + */ + CHECKr(pthread_create (&suspender_tid, &pattr, sigsuspender, NULL)); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (suspender_tid, SIGIO)); + sleep (1); + CHECKe(kill (getpid (), SIGIO)); + sleep (1); + /* sigsuspend should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a + * sigsuspend. + */ + CHECKr(pthread_kill (suspender_tid, SIGURG)); + sleep (1); + CHECKe(kill (getpid (), SIGURG)); + sleep (1); + /* sigsuspend should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 3); + + /* + * Verify that a SIGUSR2 signal will release a sigsuspended + * thread. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR2)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR2)); + sleep (1); + /* sigsuspend should wake yp for SIGUSR2 */ + ASSERT(sigcounts[SIGUSR2] == 2); + + /* + * Verify that a signal, blocked in both the main and + * sigsuspender threads, does not cause the signal handler + * to be called. + */ + CHECKr(pthread_kill (suspender_tid, SIGUSR1)); + sleep (1); + CHECKe(kill (getpid (), SIGUSR1)); + sleep (1); + /* signal handler should not be called for USR1 */ + ASSERT(sigcounts[SIGUSR1] == 0); +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill (getpid (), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (suspender_tid, NULL)); +#endif + SUCCEED; +} + diff --git a/regress/lib/libpthread/sigwait/Makefile b/regress/lib/libpthread/sigwait/Makefile new file mode 100644 index 00000000000..52117d781b0 --- /dev/null +++ b/regress/lib/libpthread/sigwait/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:13 fgsch Exp $ + +PROG= sigwait +SRCS= sigwait.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/sigwait/sigwait.c b/regress/lib/libpthread/sigwait/sigwait.c new file mode 100644 index 00000000000..a166eaf2a1e --- /dev/null +++ b/regress/lib/libpthread/sigwait/sigwait.c @@ -0,0 +1,264 @@ +/* $OpenBSD: sigwait.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Daniel M. Eischen. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL M. EISCHEN 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 REGENTS 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. + * + */ +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + +#include <pthread_np.h> +#include "test.h" + +static int sigcounts[NSIG + 1]; +static sigset_t wait_mask; +static pthread_mutex_t waiter_mutex; + + +static void * +sigwaiter (void *arg) +{ + int signo; + sigset_t mask; + + SET_NAME("sigwaiter"); + + /* Block SIGHUP */ + sigemptyset (&mask); + sigaddset (&mask, SIGHUP); + CHECKe(sigprocmask (SIG_BLOCK, &mask, NULL)); + + while (sigcounts[SIGINT] == 0) { + printf("Sigwait waiting (thread %p)\n", pthread_self()); + CHECKe(sigwait (&wait_mask, &signo)); + sigcounts[signo]++; + printf ("Sigwait caught signal %d (%s)\n", signo, + strsignal(signo)); + + /* Allow the main thread to prevent the sigwait. */ + CHECKr(pthread_mutex_lock (&waiter_mutex)); + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + } + + return (arg); +} + + +static void +sighandler (int signo) +{ + printf (" -> Signal handler caught signal %d (%s) in thread %p\n", + signo, strsignal(signo), pthread_self()); + + if ((signo >= 0) && (signo <= NSIG)) + sigcounts[signo]++; +} + +int main (int argc, char *argv[]) +{ + pthread_mutexattr_t mattr; + pthread_attr_t pattr; + pthread_t tid; + struct sigaction act; + + /* Initialize our signal counts. */ + memset ((void *) sigcounts, 0, NSIG * sizeof (int)); + + /* Setupt our wait mask. */ + sigemptyset (&wait_mask); /* Default action */ + sigaddset (&wait_mask, SIGHUP); /* terminate */ + sigaddset (&wait_mask, SIGINT); /* terminate */ + sigaddset (&wait_mask, SIGQUIT); /* create core image */ + sigaddset (&wait_mask, SIGURG); /* ignore */ + sigaddset (&wait_mask, SIGIO); /* ignore */ + sigaddset (&wait_mask, SIGUSR1); /* terminate */ + + /* Ignore signals SIGHUP and SIGIO. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + sigaddset (&act.sa_mask, SIGIO); + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + CHECKe(sigaction (SIGHUP, &act, NULL)); + CHECKe(sigaction (SIGIO, &act, NULL)); + + /* Install a signal handler for SIGURG */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGURG); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGURG, &act, NULL)); + + /* Install a signal handler for SIGXCPU */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGXCPU); + CHECKe(sigaction (SIGXCPU, &act, NULL)); + + /* + * Initialize the thread attribute. + */ + CHECKr(pthread_attr_init (&pattr)); + CHECKr(pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE)); + + /* + * Initialize and create a mutex. + */ + CHECKr(pthread_mutexattr_init (&mattr)); + CHECKr(pthread_mutex_init (&waiter_mutex, &mattr)); + + /* + * Create the sigwaiter thread. + */ + CHECKr(pthread_create (&tid, &pattr, sigwaiter, NULL)); + + /* + * Verify that an ignored signal doesn't cause a wakeup. + * We don't have a handler installed for SIGIO. + */ + CHECKr(pthread_kill (tid, SIGIO)); + sleep (1); + CHECKe(kill(getpid(), SIGIO)); + sleep (1); + /* sigwait should not wake up for ignored signal SIGIO */ + ASSERT(sigcounts[SIGIO] == 0); + + /* + * Verify that a signal with a default action of ignore, for + * which we have a signal handler installed, will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGURG)); + sleep (1); + CHECKe(kill(getpid(), SIGURG)); + sleep (1); + /* sigwait should wake up for SIGURG */ + ASSERT(sigcounts[SIGURG] == 2); + + /* + * Verify that a signal with a default action that terminates + * the process will release a sigwait. + */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + CHECKe(kill(getpid(), SIGUSR1)); + sleep (1); + if (sigcounts[SIGUSR1] != 2) + printf ("FAIL: sigwait doesn't wake up for SIGUSR1.\n"); + + /* + * Verify that if we install a signal handler for a previously + * ignored signal, an occurrence of this signal will release + * the (already waiting) sigwait. + */ + + /* Install a signal handler for SIGHUP. */ + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SIGHUP); + act.sa_handler = sighandler; + act.sa_flags = SA_RESTART; + CHECKe(sigaction (SIGHUP, &act, NULL)); + + /* Sending SIGHUP should release the sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + CHECKr(pthread_kill (tid, SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 2); + + /* + * Verify that a pending signal in the waiters mask will + * cause sigwait to return the pending signal. We do this + * by taking the waiters mutex and signaling the waiter to + * release him from the sigwait. The waiter will block + * on taking the mutex, and we can then send the waiter a + * signal which should be added to his pending signals. + * The next time the waiter does a sigwait, he should + * return with the pending signal. + */ + sigcounts[SIGHUP] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKe(kill(getpid(), SIGHUP)); + sleep (1); + /* sigwait should wake up for SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 1); + /* + * Add SIGHUP to all threads pending signals. Since there is + * a signal handler installed for SIGHUP and this signal is + * blocked from the waiter thread and unblocked in the main + * thread, the signal handler should be called once for SIGHUP. + */ + CHECKe(kill(getpid(), SIGHUP)); + /* Release the waiter thread and allow him to run. */ + CHECKr(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGHUP */ + ASSERT(sigcounts[SIGHUP] == 3); + + /* + * Repeat the above test using pthread_kill and SIGUSR1 + */ + sigcounts[SIGUSR1] = 0; + CHECKr(pthread_mutex_lock (&waiter_mutex)); + /* Release the waiter from sigwait. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + sleep (1); + /* sigwait should wake up for SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 1); + /* Add SIGHUP to the waiters pending signals. */ + CHECKr(pthread_kill (tid, SIGUSR1)); + /* Release the waiter thread and allow him to run. */ + CHECKe(pthread_mutex_unlock (&waiter_mutex)); + sleep (1); + /* sigwait should return for pending SIGUSR1 */ + ASSERT(sigcounts[SIGUSR1] == 2); + +#if 0 + /* + * Verify that we can still kill the process for a signal + * not being waited on by sigwait. + */ + CHECKe(kill(getpid(), SIGPIPE)); + PANIC("SIGPIPE did not terminate process"); + + /* + * Wait for the thread to finish. + */ + CHECKr(pthread_join (tid, NULL)); +#endif + + SUCCEED; +} diff --git a/regress/lib/libpthread/sleep/Makefile b/regress/lib/libpthread/sleep/Makefile new file mode 100644 index 00000000000..5cde62316d2 --- /dev/null +++ b/regress/lib/libpthread/sleep/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= sleep +SRCS= sleep.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/sleep/sleep.c b/regress/lib/libpthread/sleep/sleep.c new file mode 100644 index 00000000000..ec5ddd1bb66 --- /dev/null +++ b/regress/lib/libpthread/sleep/sleep.c @@ -0,0 +1,82 @@ +/* $OpenBSD: sleep.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sleep.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test context switch functionality. + * + * 1.00 93/08/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> +#include "test.h" + +const char buf[] = "abcdefghijklimnopqrstuvwxyz"; +int fd = 1; + +void* new_thread(void* arg) +{ + int i; + + for (i = 0; i < 10; i++) { + write(fd, buf + (long) arg, 1); + sleep(1); + } + return NULL; +} + +int +main() +{ + pthread_t thread[2]; + int count = sizeof thread/sizeof thread[0]; + long i; + + printf("Going to sleep\n"); + sleep(3); + printf("Done sleeping\n"); + + for(i = 0; i < count; i++) + CHECKr(pthread_create(&thread[i], NULL, new_thread, + (void *) i)); + + for (i = 0; i < count; i++) + CHECKr(pthread_join(thread[i], NULL)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/socket/1/Makefile b/regress/lib/libpthread/socket/1/Makefile new file mode 100644 index 00000000000..e0eeda8e59b --- /dev/null +++ b/regress/lib/libpthread/socket/1/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket1 +SRCS= socket1.c +CFLAGS+= -I${.CURDIR}/../../include + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/socket/1/socket1.c b/regress/lib/libpthread/socket/1/socket1.c new file mode 100644 index 00000000000..ee41bf1db48 --- /dev/null +++ b/regress/lib/libpthread/socket/1/socket1.c @@ -0,0 +1,194 @@ +/* $OpenBSD: socket1.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include "test.h" +#include <sched.h> +#include <string.h> +#include <stdlib.h> + +struct sockaddr_in a_sout; +int success = 0; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_attr_t attr; + +static int counter = 0; + +void * +sock_connect(arg) + void *arg; +{ + char buf[1024]; + int fd; + + /* Ensure sock_read runs first */ + CHECKr(pthread_mutex_lock(&mutex)); + + a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */ + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + ASSERT(++counter == 2); + + /* connect to the socket */ + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + CHECKe(close(fd)); + + CHECKr(pthread_mutex_unlock(&mutex)); + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + ASSERT(++counter == 3); + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + + /* Ensure sock_read runs again */ + pthread_yield(); + sleep(1); + + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(read(fd, buf, 1024)); + + write(fd, "6", 1); + + ASSERT(++counter == atoi(buf)); + CHECKe(close(fd)); + success++; + CHECKr(pthread_mutex_unlock(&mutex)); + + return(NULL); +} + +void * +sock_write(arg) + void *arg; +{ + int fd = *(int *)arg; + + CHECKe(write(fd, "5", 1)); + return(NULL); +} + +void * +sock_accept(arg) + void *arg; +{ + pthread_t thread; + struct sockaddr a_sin; + int a_sin_size, a_fd, fd; + short port; + char buf[1024]; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = INADDR_ANY; + + CHECKe(a_fd = socket(AF_INET, SOCK_STREAM, 0)); + + while (1) { + if(0 == bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout))) + break; + if (errno == EADDRINUSE) { + a_sout.sin_port = htons((++port)); + continue; + } + DIE(errno, "bind"); + } + CHECKe(listen(a_fd, 2)); + + ASSERT(++counter == 1); + + CHECKr(pthread_create(&thread, &attr, sock_connect, + (void *)0xdeadbeaf)); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKr(pthread_mutex_lock(&mutex)); + CHECKe(close(fd)); + + ASSERT(++counter == 4); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKr(pthread_mutex_unlock(&mutex)); + + /* Setup a write thread */ + CHECKr(pthread_create(&thread, &attr, sock_write, &fd)); + CHECKe(read(fd, buf, 1024)); + + ASSERT(++counter == atoi(buf)); + + CHECKe(close(fd)); + + CHECKr(pthread_mutex_lock(&mutex)); + success++; + CHECKr(pthread_mutex_unlock(&mutex)); + + CHECKr(pthread_join(thread, NULL)); + return(NULL); +} + +int +main() +{ + pthread_t thread; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_attr_init(&attr)); +#if 0 + CHECKr(pthread_attr_setschedpolicy(&attr, SCHED_FIFO)); +#endif + CHECKr(pthread_create(&thread, &attr, sock_accept, + (void *)0xdeadbeaf)); + + CHECKr(pthread_join(thread, NULL)); + + ASSERT(success == 2); + SUCCEED; +} diff --git a/regress/lib/libpthread/socket/2/Makefile b/regress/lib/libpthread/socket/2/Makefile new file mode 100644 index 00000000000..c53d752619c --- /dev/null +++ b/regress/lib/libpthread/socket/2/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket2 +SRCS= socket2.c +CFLAGS+= -I${.CURDIR}/../../include +CLEANFILES+= socket2a + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/socket/2/socket2.c b/regress/lib/libpthread/socket/2/socket2.c new file mode 100644 index 00000000000..5b3b51fda57 --- /dev/null +++ b/regress/lib/libpthread/socket/2/socket2.c @@ -0,0 +1,188 @@ +/* $OpenBSD: socket2.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <pthread_np.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <string.h> +#include "test.h" + +struct sockaddr_in a_sout; + +#define MESSAGE5 "This should be message #5" +#define MESSAGE6 "This should be message #6" + +void * +sock_write(arg) + void *arg; +{ + int fd = *(int *)arg; + + SET_NAME("writer"); + CHECKe(write(fd, MESSAGE5, sizeof(MESSAGE5))); + return(NULL); +} + +static pthread_mutex_t waiter_mutex = PTHREAD_MUTEX_INITIALIZER; + +void* +waiter(sig) +{ + int status; + pid_t pid; + + SET_NAME("waiter"); + CHECKr(pthread_mutex_lock(&waiter_mutex)); + printf("waiting for child\n"); + CHECKe(pid = wait(&status)); + ASSERT(WIFEXITED(status)); + ASSERT(WEXITSTATUS(status) == 0); + printf("child exited\n"); + CHECKr(pthread_mutex_unlock(&waiter_mutex)); + return (NULL); +} + +void * +sock_accept(arg) + void *arg; +{ + pthread_t thread, wthread; + struct sockaddr a_sin; + int a_sin_size, a_fd, fd; + u_int16_t port; + char buf[1024]; + pid_t pid; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = INADDR_ANY; + + CHECKe(a_fd = socket(AF_INET, SOCK_STREAM, 0)); + + while(1) { + if (bind(a_fd, (struct sockaddr *)&a_sout, sizeof(a_sout))==0) + break; + if (errno == EADDRINUSE) { + a_sout.sin_port = htons((++port)); + continue; + } + DIE(errno, "bind"); + } + + printf("listening on port %d\n", port); + + CHECKe(listen(a_fd, 2)); + + printf("%d: This should be message #1\n", getpid()); + + CHECKr(pthread_mutex_init(&waiter_mutex, NULL)); + CHECKr(pthread_mutex_lock(&waiter_mutex)); + CHECKr(pthread_create(&wthread, NULL, waiter, NULL)); + + CHECKe(pid = fork()); + switch(pid) { + case 0: + execl("socket2a", "socket2a", "fork okay", (char *)NULL); + DIE(errno, "execl"); + default: + break; + } + CHECKr(pthread_mutex_unlock(&waiter_mutex)); + pthread_yield(); + + a_sin_size = sizeof(a_sin); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + CHECKe(close(fd)); + + sleep(1); + + printf("%d: This should be message #4\n", getpid()); + + a_sin_size = sizeof(a_sin); + memset(&a_sin, 0, sizeof(a_sin)); + CHECKe(fd = accept(a_fd, &a_sin, &a_sin_size)); + + /* Setup a write thread */ + + CHECKr(pthread_create(&thread, NULL, sock_write, &fd)); + CHECKe(read(fd, buf, 1024)); + + printf("%d: %s\n", getpid(), buf); /* message 6 */ + + CHECKe(close(fd)); + + if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) { + sleep(2); + if (pthread_mutex_trylock(&waiter_mutex) == EBUSY) { + /* forcibly kill child */ + CHECKe(kill(pid, SIGKILL)); + PANIC("child %d took too long to exit", pid); + } + } + CHECKr(pthread_join(wthread, NULL)); + + return(NULL); +} + +int +main() +{ + pthread_t thread; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_create(&thread, NULL, sock_accept, + (void *)0xdeadbeaf)); + + CHECKr(pthread_join(thread, NULL)); + + SUCCEED; +} diff --git a/regress/lib/libpthread/socket/2a/Makefile b/regress/lib/libpthread/socket/2a/Makefile new file mode 100644 index 00000000000..11a91f9dc8d --- /dev/null +++ b/regress/lib/libpthread/socket/2a/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +PROG= socket2a +SRCS= socket2a.c +CFLAGS+= -I${.CURDIR}/../../include + +regress: + @cd ${.CURDIR}/../2; \ + if test -d ${__objdir} ; then \ + cd ${__objdir} ; \ + fi; \ + ln -sf ${.OBJDIR}/${PROG} + # Nothing here so far... + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/socket/2a/socket2a.c b/regress/lib/libpthread/socket/2a/socket2a.c new file mode 100644 index 00000000000..551b925065d --- /dev/null +++ b/regress/lib/libpthread/socket/2a/socket2a.c @@ -0,0 +1,118 @@ +/* $OpenBSD: socket2a.c,v 1.1 2001/08/15 14:37:10 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_sock_1.c ========================================================= + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test pthread_create() and pthread_exit() calls. + * + * 1.00 93/08/03 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <string.h> +#include "test.h" + +struct sockaddr_in a_sout; + +#define MESSAGE5 "This should be message #5" +#define MESSAGE6 "This should be message #6" + +void * +sock_connect(arg) + void *arg; +{ + char buf[1024]; + int fd; + short port; + + port = 3276; + a_sout.sin_family = AF_INET; + a_sout.sin_port = htons(port); + a_sout.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* loopback */ + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + printf("%d: This should be message #2\n", getpid()); + + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + CHECKe(close(fd)); + + CHECKe(fd = socket(AF_INET, SOCK_STREAM, 0)); + + printf("%d: This should be message #3\n", getpid()); + + CHECKe(connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout))); + + /* Ensure sock_read runs again */ + + CHECKe(read(fd, buf, 1024)); + CHECKe(write(fd, MESSAGE6, sizeof(MESSAGE6))); + + printf("%d: %s\n", getpid(), buf); + + CHECKe(close(fd)); + return (NULL); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t thread; + + if (argv[1] && (!strcmp(argv[1], "fork okay"))) { + sleep(1); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + CHECKr(pthread_create(&thread, NULL, sock_connect, + (void *)0xdeadbeaf)); + CHECKr(pthread_join(thread, NULL)); + SUCCEED; + } else { + fprintf(stderr, "test_sock_2a needs to be exec'ed from " + "test_sock_2.\n"); + fprintf(stderr, "It is not a stand alone test.\n"); + PANIC("usage"); + } +} diff --git a/regress/lib/libpthread/socket/Makefile b/regress/lib/libpthread/socket/Makefile new file mode 100644 index 00000000000..30574a5e2a6 --- /dev/null +++ b/regress/lib/libpthread/socket/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:10 fgsch Exp $ + +SUBDIR= 1 2a 2 + +regress: _SUBDIRUSE + +.include <bsd.subdir.mk> diff --git a/regress/lib/libpthread/socket/Makefile.inc b/regress/lib/libpthread/socket/Makefile.inc new file mode 100644 index 00000000000..dd4abfd15df --- /dev/null +++ b/regress/lib/libpthread/socket/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1.1.1 2001/08/15 14:37:10 fgsch Exp $ + +.include "${.CURDIR}/../../Makefile.inc" diff --git a/regress/lib/libpthread/stdarg/Makefile b/regress/lib/libpthread/stdarg/Makefile new file mode 100644 index 00000000000..60c57f3e876 --- /dev/null +++ b/regress/lib/libpthread/stdarg/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= stdarg +SRCS= stdarg.c + +CFLAGS+= -I${.CURDIR}/../include + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/stdarg/stdarg.c b/regress/lib/libpthread/stdarg/stdarg.c new file mode 100644 index 00000000000..a3e07d58a21 --- /dev/null +++ b/regress/lib/libpthread/stdarg/stdarg.c @@ -0,0 +1,87 @@ +/* $OpenBSD: stdarg.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* David Leonard <d@openbsd.org>, 2001. Public Domain. */ + +/* + * Test <stdarg.h> + */ + +#include <pthread.h> +#include <stdio.h> +#include <stdarg.h> +#include "test.h" + +#define EQ(v,exp) _CHECK(v, == exp, NULL) + +int thing; + +int +test1(char *fmt, ...) +{ + va_list ap; + + char ch; + int i; + char c; + long l; + void *p; + char *ofmt = fmt; + + va_start(ap, fmt); + for (; *fmt; fmt++) + switch ((ch =*fmt)) { + case 'i': + i = va_arg(ap, int); + EQ(i, 1234); + break; + case 'c': + c = va_arg(ap, char); + EQ(c, 'x'); + break; + case 'l': + l = va_arg(ap, long); + EQ(l, 123456789L); + break; + case 'p': + p = va_arg(ap, void *); + EQ(p, &thing); + break; + default: + fprintf(stderr, "unexpected character 0x%02x `%c' in %s(%p) at %p\n", + ch, ch, ofmt, ofmt, fmt); + ASSERT(0); + } + va_end(ap); + return 9; +} + +void * +run_test(arg) + void *arg; +{ + char *msg = (char *)arg; + int i; + + SET_NAME(msg); + + puts(msg); + for (i = 0; i < 1000000; i++) { + ASSERT(test1("iclp", 1234, 'x', 123456789L, &thing) == 9); + } + printf("ok\n"); + return NULL; +} + +int +main() +{ + pthread_t t1, t2; + + printf("trying loop in single-threaded mode:\n"); + run_test("main"); + printf("now running loop with 2 threads:\n"); + CHECKr(pthread_create(&t1, NULL, run_test, "child 1")); + CHECKr(pthread_create(&t2, NULL, run_test, "child 2")); + CHECKr(pthread_join(t1, NULL)); + CHECKr(pthread_join(t2, NULL)); + SUCCEED; +} diff --git a/regress/lib/libpthread/stdio/Makefile b/regress/lib/libpthread/stdio/Makefile new file mode 100644 index 00000000000..f41504c0f39 --- /dev/null +++ b/regress/lib/libpthread/stdio/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= stdio +SRCS= stdio.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/stdio/stdio.c b/regress/lib/libpthread/stdio/stdio.c new file mode 100644 index 00000000000..9f3246d516b --- /dev/null +++ b/regress/lib/libpthread/stdio/stdio.c @@ -0,0 +1,111 @@ +/* $OpenBSD: stdio.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "test.h" + +char * base_name = "stdio.c"; +char * dir_name = SRCDIR; +char * fullname; + +/* Test fopen()/ftell()/getc() */ +void +test_1() +{ + struct stat statbuf; + FILE * fp; + int i; + + CHECKe(stat(fullname, &statbuf)); + + CHECKn((fp = fopen(fullname, "r"))); + + /* Get the entire file */ + while ((i = getc(fp)) != EOF) + ; + + ASSERT(ftell(fp) == statbuf.st_size); + + CHECKe(fclose(fp)); +} + +/* Test fopen()/fclose() */ +void +test_2() +{ + FILE *fp1, *fp2; + + CHECKn(fp1 = fopen(fullname, "r")); + CHECKe(fclose(fp1)); + + CHECKn(fp2 = fopen(fullname, "r")); + CHECKe(fclose(fp2)); + + ASSERT(fp1 == fp2); +} + +/* Test sscanf()/sprintf() */ +void +test_3(void) +{ + char * str = "10 4.53"; + char buf[64]; + double d; + int i; + + ASSERT(sscanf(str, "%d %lf", &i, &d) == 2); + + /* Should have a check */ + sprintf(buf, "%d %2.2f", i, d); + ASSERT(strcmp(buf, str) == 0); +} + +int +main() +{ + + CHECKn(fullname = malloc (strlen (dir_name) + strlen (base_name) + 2)); + sprintf (fullname, "%s/%s", dir_name, base_name); + + test_1(); + test_2(); + test_3(); + + SUCCEED; +} diff --git a/regress/lib/libpthread/switch/Makefile b/regress/lib/libpthread/switch/Makefile new file mode 100644 index 00000000000..ef0d6108068 --- /dev/null +++ b/regress/lib/libpthread/switch/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2001/08/15 14:37:16 fgsch Exp $ + +PROG= switch +SRCS= switch.c + +.include <bsd.prog.mk> diff --git a/regress/lib/libpthread/switch/switch.c b/regress/lib/libpthread/switch/switch.c new file mode 100644 index 00000000000..94fc9934bff --- /dev/null +++ b/regress/lib/libpthread/switch/switch.c @@ -0,0 +1,130 @@ +/* $OpenBSD: switch.c,v 1.1 2001/08/15 14:37:16 fgsch Exp $ */ +/* + * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors, + * proven@mit.edu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Chris Provenzano, + * the University of California, Berkeley, and contributors. + * 4. Neither the name of Chris Provenzano, the University, nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO 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 CHRIS PROVENZANO, THE REGENTS 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. + */ + +/* ==== test_switch.c ======================================================== + * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu + * + * Description : Test context switch functionality. + * + * 1.00 93/08/04 proven + * -Started coding this file. + */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include "test.h" + +const char buf[] = "abcdefghijklmnopqrstuvwxyz"; +char x[sizeof(buf)]; +int fd = 1; + +volatile int ending = 0; + +/* ========================================================================== + * usage(); + */ +void usage(void) +{ + printf("test_switch [-d?] [-c count]\n"); + printf("count must be between 2 and 26\n"); + errno = 0; +} + +void * +new_thread(arg) + void *arg; +{ + SET_NAME("writer"); + while (!ending) { + CHECKe(write (fd, (char *) arg, 1)); + x[(char *)arg - buf] = 1; + } + return NULL; +} + +int +main(argc, argv) + int argc; + char **argv; +{ + pthread_t thread; + int count = 4; + int debug = 0; + int eof = 0; + long i; + + /* Getopt variables. */ + extern int optind, opterr; + extern char *optarg; + + while (!eof) + switch (getopt (argc, argv, "c:d?")) + { + case EOF: + eof = 1; + break; + case 'd': + debug++; + break; + case 'c': + count = atoi(optarg); + if ((count > 26) || (count < 2)) { + count = 2; + } + break; + case '?': + usage(); + return(OK); + default: + usage(); + return(NOTOK); + } + + /* create the threads */ + for (i = 0; i < count; i++) + CHECKr(pthread_create(&thread, NULL, new_thread, + (void*)(buf+i))); + + /* give all threads a chance to run */ + sleep (4); + + ending = 1; + for (i = 0; i < count; i++) + ASSERT(x[i]); /* make sure each thread ran */ + + SUCCEED; +} |