ns.c 1.6 KB

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