Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/regress/lib/libc/clone - make tests independent of the direc...
details: https://anonhg.NetBSD.org/src/rev/75359c5c4ffd
branches: trunk
changeset: 513063:75359c5c4ffd
user: christos <christos%NetBSD.org@localhost>
date: Mon Jul 23 01:45:34 2001 +0000
description:
- make tests independent of the direction the stack grows
- add more sanity checks in the regression:
1. check that we get a new pid in the child
2. check that the stack in the child is the one we passed
3. check invalid argument handling
4. check running out of processes returns the right cod
XXX: does not work on the sparc, so it is ifdef'ed out
diffstat:
regress/lib/libc/clone/clonetest.c | 130 +++++++++++++++++++++++++++++-------
1 files changed, 105 insertions(+), 25 deletions(-)
diffs (192 lines):
diff -r d7fe0ef00c48 -r 75359c5c4ffd regress/lib/libc/clone/clonetest.c
--- a/regress/lib/libc/clone/clonetest.c Mon Jul 23 01:41:25 2001 +0000
+++ b/regress/lib/libc/clone/clonetest.c Mon Jul 23 01:45:34 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: clonetest.c,v 1.2 2001/07/18 19:24:02 thorpej Exp $ */
+/* $NetBSD: clonetest.c,v 1.3 2001/07/23 01:45:34 christos Exp $ */
/*
* This file placed in the public domain.
@@ -8,16 +8,26 @@
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/wait.h>
+#include <sys/resource.h>
#include <err.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
-int newclone(void *);
+static int newclone(void *);
+static int stackdir(void *);
+static void test1(void);
+static void test2(void);
+#ifndef __sparc__
+static void test3(void);
+#endif
int main(int, char *[]);
+
#define STACKSIZE (8 * 1024)
#define FROBVAL 41973
@@ -26,61 +36,131 @@
int
main(int argc, char *argv[])
{
+ test1();
+ test2();
+#ifndef __sparc__
+ test3();
+#endif
+ return 0;
+}
+
+static void
+test1()
+{
sigset_t mask;
void *stack;
- __volatile int frobme = 0;
pid_t pid;
+ __volatile long frobme[2];
int stat;
stack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON, -1, (off_t) 0);
+
if (stack == MAP_FAILED)
err(1, "mmap stack");
- /*
- * XXX FIX ME FOR UPWARD-GROWING STACK
- */
- stack = (caddr_t) stack + STACKSIZE;
+ stack = (caddr_t) stack + STACKSIZE * stackdir(&stat);
- printf("parent: stack = %p\n", stack);
+ printf("parent: stack = %p, frobme = %p\n", stack, frobme);
fflush(stdout);
+ frobme[0] = (long)getpid();
+ frobme[1] = (long)stack;
+
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
err(1, "sigprocmask (SIGUSR1)");
- pid = __clone(newclone, stack,
- CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGUSR1,
- (void *) &frobme);
- if (pid == -1)
+ switch (pid = __clone(newclone, stack,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD,
+ (void *)frobme)) {
+ case 0:
+ errx(1, "clone returned 0\n");
+ /*NOTREACHED*/
+ case -1:
err(1, "clone");
-
- while (waitpid(pid, &stat, __WCLONE) != pid)
- /* spin */ ;
+ /*NOTREACHED*/
+ default:
+ while (waitpid(pid, &stat, 0) != pid)
+ continue;
+ }
if (WIFEXITED(stat) == 0)
errx(1, "child didn't exit\n");
- printf("parent: childexit = 0x%x frobme = %d\n",
- WEXITSTATUS(stat), frobme);
+ printf("parent: childexit = 0x%x, frobme = %ld\n",
+ WEXITSTATUS(stat), frobme[1]);
+
+ if (WEXITSTATUS(stat) != CHILDEXIT || frobme[1] != FROBVAL)
+ exit(1);
+}
- if (WEXITSTATUS(stat) != CHILDEXIT || frobme != FROBVAL)
- exit(1);
-
- exit(0);
+static void
+test2()
+{
+ if (__clone(0, NULL,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD,
+ (void *)NULL) != -1 || errno != EINVAL)
+ errx(1, "clone did not return EINVAL on invalid arguments");
}
-int
+#ifndef __sparc__
+/*
+ * XXX: does not work on the sparc, why?
+ */
+static void
+test3()
+{
+ struct rlimit rl;
+
+ if (getrlimit(RLIMIT_NPROC, &rl) == -1)
+ err(1, "getrlimit");
+ rl.rlim_cur = 0;
+ rl.rlim_max = 0;
+ if (setrlimit(RLIMIT_NPROC, &rl) == -1)
+ err(1, "setrlimit");
+ if (__clone(newclone, malloc(10240),
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD,
+ (void *)&rl) != -1 || errno != EAGAIN)
+ errx(1, "clone did not return EAGAIN running out of procs");
+}
+#endif
+
+static int
newclone(void *arg)
{
- int *frobp = arg;
+ long *frobp = arg, diff;
- printf("child: stack ~= %p\n", &frobp);
+ printf("child: stack ~= %p, frobme = %p\n", &frobp, frobp);
fflush(stdout);
- *frobp = FROBVAL;
+ if (frobp[0] != getppid())
+ errx(1, "argument does not contain parent's pid\n");
+
+ if (frobp[0] == getpid())
+ errx(1, "called in parent's pid\n");
+
+ if (frobp[1] > (long)&frobp)
+ diff = frobp[1] - (long)&frobp;
+ else
+ diff = (long)&frobp - frobp[1];
+
+ if (diff > 1024)
+ errx(1, "called with bad stack\n");
+
+ frobp[1] = FROBVAL;
return (CHILDEXIT);
}
+
+/*
+ * return 1 if the stack grows down, 0 if it grows up.
+ */
+static int
+stackdir(void *p)
+{
+ void *q;
+ return p < q ? 0 : 1;
+}
Home |
Main Index |
Thread Index |
Old Index