github.com/SamWhited/moby@v1.13.1/contrib/syscall-test/userns.c (about)

     1  #define _GNU_SOURCE
     2  #include <errno.h>
     3  #include <sched.h>
     4  #include <signal.h>
     5  #include <stdio.h>
     6  #include <stdlib.h>
     7  #include <string.h>
     8  #include <sys/mman.h>
     9  #include <sys/wait.h>
    10  #include <unistd.h>
    11  
    12  #define STACK_SIZE (1024 * 1024)	/* Stack size for cloned child */
    13  
    14  struct clone_args {
    15  	char **argv;
    16  };
    17  
    18  // child_exec is the func that will be executed as the result of clone
    19  static int child_exec(void *stuff)
    20  {
    21  	struct clone_args *args = (struct clone_args *)stuff;
    22  	if (execvp(args->argv[0], args->argv) != 0) {
    23  		fprintf(stderr, "failed to execvp argments %s\n",
    24  			strerror(errno));
    25  		exit(-1);
    26  	}
    27  	// we should never reach here!
    28  	exit(EXIT_FAILURE);
    29  }
    30  
    31  int main(int argc, char **argv)
    32  {
    33  	struct clone_args args;
    34  	args.argv = &argv[1];
    35  
    36  	int clone_flags = CLONE_NEWUSER | SIGCHLD;
    37  
    38  	// allocate stack for child
    39  	char *stack;		/* Start of stack buffer */
    40  	char *child_stack;	/* End of stack buffer */
    41  	stack =
    42  	    mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
    43  		 MAP_SHARED | MAP_ANON | MAP_STACK, -1, 0);
    44  	if (stack == MAP_FAILED) {
    45  		fprintf(stderr, "mmap failed: %s\n", strerror(errno));
    46  		exit(EXIT_FAILURE);
    47  	}
    48  	child_stack = stack + STACK_SIZE;	/* Assume stack grows downward */
    49  
    50  	// the result of this call is that our child_exec will be run in another
    51  	// process returning its pid
    52  	pid_t pid = clone(child_exec, child_stack, clone_flags, &args);
    53  	if (pid < 0) {
    54  		fprintf(stderr, "clone failed: %s\n", strerror(errno));
    55  		exit(EXIT_FAILURE);
    56  	}
    57  	// lets wait on our child process here before we, the parent, exits
    58  	if (waitpid(pid, NULL, 0) == -1) {
    59  		fprintf(stderr, "failed to wait pid %d\n", pid);
    60  		exit(EXIT_FAILURE);
    61  	}
    62  	exit(EXIT_SUCCESS);
    63  }