ax_check_uts_namespace.m4 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # -*- Autoconf -*-
  2. # SYNOPSIS
  3. #
  4. # AX_CHECK_UTS_NAMESPACE
  5. #
  6. # DESCRIPTION
  7. #
  8. # This macro checks whether the local system supports Linux UTS namespaces.
  9. # Also requires user namespaces to be available, so that non-root users
  10. # can enter the namespace.
  11. # If so, it calls AC_DEFINE(HAVE_UTS_NAMESPACE).
  12. AC_DEFUN([AX_CHECK_UTS_NAMESPACE],[dnl
  13. AC_CACHE_CHECK([whether UTS namespaces are supported],
  14. ax_cv_uts_namespace,[
  15. AC_LANG_PUSH([C])
  16. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  17. #define _GNU_SOURCE
  18. #include <sched.h>
  19. #include <signal.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <fcntl.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <sys/wait.h>
  26. int utsfn(void *d) {
  27. char buffer[1024];
  28. const char *name = "autoconftest";
  29. int rc = sethostname(name, strlen(name));
  30. if (rc != 0) return 1;
  31. gethostname(buffer, 1024);
  32. return (strcmp(buffer, name) != 0);
  33. }
  34. char st2[1024*1024];
  35. int fn(void *d) {
  36. pid_t child;
  37. int rc, status;
  38. usleep(100000); /* synchronize by sleep */
  39. if (getuid() != 0) return 1;
  40. child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0);
  41. if (child < 0) return 1;
  42. rc = waitpid(child, &status, 0);
  43. if (rc <= 0) return 1;
  44. if (!WIFEXITED(status)) return 1;
  45. return WEXITSTATUS(status);
  46. }
  47. char st[1024*1024];
  48. int main() {
  49. char buffer[1024];
  50. int rc, status, fd;
  51. pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0);
  52. if (child < 0) return 1;
  53. sprintf(buffer, "/proc/%d/uid_map", child);
  54. fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755);
  55. sprintf(buffer, "0 %d 1\n", getuid());
  56. write(fd, buffer, strlen(buffer));
  57. close(fd);
  58. rc = waitpid(child, &status, 0);
  59. if (rc <= 0) return 1;
  60. if (!WIFEXITED(status)) return 1;
  61. return WEXITSTATUS(status);
  62. }
  63. ]])
  64. ],[ax_cv_uts_namespace=yes],[ax_cv_uts_namespace=no],[ax_cv_uts_namespace=no])
  65. AC_LANG_POP([C])
  66. ])
  67. if test "$ax_cv_uts_namespace" = yes; then
  68. AC_DEFINE([HAVE_UTS_NAMESPACE],[1],[Whether UTS namespaces are available])
  69. fi
  70. ]) # AX_CHECK_UTS_NAMESPACE