184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner/* Check that clone() is implemented and properly works
284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner */
384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#define __GNU_SOURCE 1
484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <stdio.h>
584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <errno.h>
684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <sched.h>
784a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <unistd.h>
884a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <signal.h>
984a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <stdlib.h>
1084a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <sys/ptrace.h>
1184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <sys/wait.h>
1284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <stdarg.h>
1384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#include <string.h>
1484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
1584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turnerstatic int
1684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turnerclone_child (void *arg)
1784a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner{
1884a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner errno = 0;
1984a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner ptrace (PTRACE_TRACEME, 0, 0, 0);
2084a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner if (errno != 0)
2184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   perror ("ptrace");
2284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner if (kill (getpid (), SIGSTOP) < 0)
2384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   perror ("kill");
2484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner return 0;
2584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner}
2684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
2784a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#define PAGE_SIZE 4096
2884a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner#define STACK_SIZE (4 * PAGE_SIZE)
2984a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
3084a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turnerchar clone_stack[STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
3184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
3284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turnerint
3384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turnermain ()
3484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner{
3584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner int pid,child;
3684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner int status;
3784a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
3884a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner pid = clone (clone_child, clone_stack + 3 * PAGE_SIZE,
3984a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner              CLONE_VM | SIGCHLD, NULL);
4084a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner if (pid < 0)
4184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   {
4284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner     perror ("clone");
4384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner     exit (1);
4484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   }
4584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner printf ("child pid %d\n", pid);
4684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner
4784a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner //sleep(20);
4884a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner child = waitpid (pid, &status, 0);
4984a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner printf("waitpid returned %d\n", child);
5084a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner if (child < 0) {
5184a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   perror ("waitpid");
5284a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner   return 1;
5384a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner }
5484a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner printf ("child %d, status 0x%x\n", child, status);
5584a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner return 0;
5684a66d0c8d79857586bad4e3d3010ee44f8f6971David 'Digit' Turner}
57