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