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