(root)/
strace-6.5/
tests/
fork--pidns-translation.c
       1  /*
       2   * Test PID namespace translation
       3   *
       4   * Copyright (c) 2020 Ákos Uzonyi <uzonyi.akos@gmail.com>
       5   * Copyright (c) 2020-2022 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  #include "pidns.h"
      14  
      15  #ifdef __NR_fork
      16  
      17  # include <errno.h>
      18  # include <limits.h>
      19  # include <sched.h>
      20  # include <signal.h>
      21  # include <stdio.h>
      22  # include <stdlib.h>
      23  # include <sys/wait.h>
      24  # include <unistd.h>
      25  # include <linux/sched.h>
      26  # include <linux/nsfs.h>
      27  
      28  static int
      29  fork_chain(int depth)
      30  {
      31  	if (!depth)
      32  		return 0;
      33  
      34  	int pid = syscall(__NR_fork);
      35  	if (pid < 0)
      36  		return errno;
      37  
      38  	if (!pid)
      39  		_exit(fork_chain(depth - 1));
      40  
      41  	int status;
      42  	if (waitpid(pid, &status, 0) < 0) {
      43  		if (errno == ECHILD)
      44  			_exit(fork_chain(depth - 1));
      45  		return errno;
      46  	}
      47  
      48  	if (!WIFEXITED(status))
      49  		return -1;
      50  
      51  	return WEXITSTATUS(status);
      52  }
      53  
      54  int main(void)
      55  {
      56  	check_ns_ioctl();
      57  
      58  	if (unshare(CLONE_NEWPID | CLONE_NEWUSER) < 0) {
      59  		if (errno == EPERM)
      60  			perror_msg_and_skip("unshare");
      61  
      62  		perror_msg_and_fail("unshare");
      63  	}
      64  
      65  	errno = fork_chain(2);
      66  	if (errno)
      67  		perror_msg_and_fail("fork_chain");
      68  	return 0;
      69  }
      70  
      71  #else
      72  
      73  SKIP_MAIN_UNDEFINED("__NR_fork")
      74  
      75  #endif