11cb0ef41Sopenharmony_ci# -*- Autoconf -*-
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci# SYNOPSIS
41cb0ef41Sopenharmony_ci#
51cb0ef41Sopenharmony_ci#   AX_CHECK_UTS_NAMESPACE
61cb0ef41Sopenharmony_ci#
71cb0ef41Sopenharmony_ci# DESCRIPTION
81cb0ef41Sopenharmony_ci#
91cb0ef41Sopenharmony_ci#   This macro checks whether the local system supports Linux UTS namespaces.
101cb0ef41Sopenharmony_ci#   Also requires user namespaces to be available, so that non-root users
111cb0ef41Sopenharmony_ci#   can enter the namespace.
121cb0ef41Sopenharmony_ci#   If so, it calls AC_DEFINE(HAVE_UTS_NAMESPACE).
131cb0ef41Sopenharmony_ci#
141cb0ef41Sopenharmony_ci# Copyright (C) The c-ares team
151cb0ef41Sopenharmony_ci# SPDX-License-Identifier: MIT
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciAC_DEFUN([AX_CHECK_UTS_NAMESPACE],[dnl
181cb0ef41Sopenharmony_ci AC_CACHE_CHECK([whether UTS namespaces are supported],
191cb0ef41Sopenharmony_ci  ax_cv_uts_namespace,[
201cb0ef41Sopenharmony_ci  AC_LANG_PUSH([C])
211cb0ef41Sopenharmony_ci  AC_RUN_IFELSE([AC_LANG_SOURCE([[
221cb0ef41Sopenharmony_ci#define _GNU_SOURCE
231cb0ef41Sopenharmony_ci#include <sched.h>
241cb0ef41Sopenharmony_ci#include <signal.h>
251cb0ef41Sopenharmony_ci#include <stdio.h>
261cb0ef41Sopenharmony_ci#include <string.h>
271cb0ef41Sopenharmony_ci#include <fcntl.h>
281cb0ef41Sopenharmony_ci#include <unistd.h>
291cb0ef41Sopenharmony_ci#include <sys/types.h>
301cb0ef41Sopenharmony_ci#include <sys/wait.h>
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciint utsfn(void *d) {
331cb0ef41Sopenharmony_ci  char buffer[1024];
341cb0ef41Sopenharmony_ci  const char *name = "autoconftest";
351cb0ef41Sopenharmony_ci  int rc = sethostname(name, strlen(name));
361cb0ef41Sopenharmony_ci  if (rc != 0) return 1;
371cb0ef41Sopenharmony_ci  gethostname(buffer, 1024);
381cb0ef41Sopenharmony_ci  return (strcmp(buffer, name) != 0);
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_cichar st2[1024*1024];
421cb0ef41Sopenharmony_ciint fn(void *d) {
431cb0ef41Sopenharmony_ci  pid_t child;
441cb0ef41Sopenharmony_ci  int rc, status;
451cb0ef41Sopenharmony_ci  usleep(100000);  /* synchronize by sleep */
461cb0ef41Sopenharmony_ci  if (getuid() != 0) return 1;
471cb0ef41Sopenharmony_ci  child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0);
481cb0ef41Sopenharmony_ci  if (child < 0) return 1;
491cb0ef41Sopenharmony_ci  rc = waitpid(child, &status, 0);
501cb0ef41Sopenharmony_ci  if (rc <= 0) return 1;
511cb0ef41Sopenharmony_ci  if (!WIFEXITED(status)) return 1;
521cb0ef41Sopenharmony_ci  return WEXITSTATUS(status);
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_cichar st[1024*1024];
551cb0ef41Sopenharmony_ciint main() {
561cb0ef41Sopenharmony_ci  char buffer[1024];
571cb0ef41Sopenharmony_ci  int rc, status, fd;
581cb0ef41Sopenharmony_ci  pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0);
591cb0ef41Sopenharmony_ci  if (child < 0) return 1;
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child);
621cb0ef41Sopenharmony_ci  fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755);
631cb0ef41Sopenharmony_ci  snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid());
641cb0ef41Sopenharmony_ci  write(fd, buffer, strlen(buffer));
651cb0ef41Sopenharmony_ci  close(fd);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  rc = waitpid(child, &status, 0);
681cb0ef41Sopenharmony_ci  if (rc <= 0) return 1;
691cb0ef41Sopenharmony_ci  if (!WIFEXITED(status)) return 1;
701cb0ef41Sopenharmony_ci  return WEXITSTATUS(status);
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci]])
731cb0ef41Sopenharmony_ci  ],[ax_cv_uts_namespace=yes],[ax_cv_uts_namespace=no],[ax_cv_uts_namespace=no])
741cb0ef41Sopenharmony_ci AC_LANG_POP([C])
751cb0ef41Sopenharmony_ci ])
761cb0ef41Sopenharmony_ci if test "$ax_cv_uts_namespace" = yes; then
771cb0ef41Sopenharmony_ci   AC_DEFINE([HAVE_UTS_NAMESPACE],[1],[Whether UTS namespaces are available])
781cb0ef41Sopenharmony_ci fi
791cb0ef41Sopenharmony_ci]) # AX_CHECK_UTS_NAMESPACE
80