(root)/
strace-6.5/
tests-mx32/
strace--syscall-limit.c
       1  /*
       2   * Test --syscall-limit option.
       3   *
       4   * Copyright (c) 2023 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  
      13  #include <errno.h>
      14  #include <fcntl.h>
      15  #include <stdio.h>
      16  #include <stdlib.h>
      17  #include <unistd.h>
      18  #include <sys/types.h>
      19  #include <sys/wait.h>
      20  
      21  #ifndef PRINT_VALID
      22  # define PRINT_VALID 1
      23  #endif
      24  #ifndef PRINT_INVALID
      25  # define PRINT_INVALID 1
      26  #endif
      27  #ifndef PRINT_STATS
      28  # define PRINT_STATS 0
      29  #endif
      30  #ifndef UNLINKAT_CNT
      31  # define UNLINKAT_CNT 1
      32  #endif
      33  #ifndef TOTAL_CNT
      34  # define TOTAL_CNT 3
      35  #endif
      36  
      37  static int
      38  write_status(const char *name, int value)
      39  {
      40  	FILE *fp = fopen(name, "w");
      41  	if (!fp)
      42  		perror_msg_and_fail("fopen: %s", name);
      43  	if (fprintf(fp, "%d\n", value) <= 0)
      44  		perror_msg_and_fail("fprintf: %s", name);
      45  	if (fclose(fp))
      46  		perror_msg_and_fail("fclose: %s", name);
      47  	fflush(stdout);
      48  	return value;
      49  }
      50  
      51  static const char valid_path[] = ".";
      52  static const char invalid_path[] = "invalid.dir";
      53  
      54  static void
      55  test_chdir(int pid, bool print)
      56  {
      57  	if (chdir(valid_path))
      58  		perror_msg_and_fail("chdir: %s", valid_path);
      59  
      60  	if (print) {
      61  #if PRINT_VALID
      62  		printf("%-5u chdir(\"%s\") = 0\n", pid, valid_path);
      63  #else /* !PRINT_VALID */
      64  		if (chdir(invalid_path) == 0)
      65  			error_msg_and_fail("chdir: %s", invalid_path);
      66  # if PRINT_INVALID
      67  		printf("%-5u chdir(\"%s\") = %s\n", pid, invalid_path, sprintrc(-1));
      68  # endif
      69  #endif /* PRINT_VALID */
      70  	} else {
      71  		if (chdir(invalid_path) == 0)
      72  			error_msg_and_fail("chdir: %s", invalid_path);
      73  	}
      74  }
      75  
      76  static void
      77  test_rmdir(int pid, bool print)
      78  {
      79  #ifndef AT_FDCWD
      80  # define AT_FDCWD -100
      81  #endif
      82  #ifndef AT_REMOVEDIR
      83  # define AT_REMOVEDIR 0x200
      84  #endif
      85  	if (syscall(__NR_unlinkat, AT_FDCWD, "invalid.dir", AT_REMOVEDIR) == 0)
      86  		error_msg_and_fail("unlinkat: %s", invalid_path);
      87  #if PRINT_INVALID
      88  	if (print)
      89  		printf("%-5u unlinkat(AT_FDCWD, \"%s\", AT_REMOVEDIR) = %s\n",
      90  		       pid, invalid_path, sprintrc(-1));
      91  #endif
      92  }
      93  
      94  int
      95  main(void)
      96  {
      97  	int pid = getpid();
      98  
      99  	test_chdir(pid, /* print */ true);
     100  
     101  	fflush(stdout);
     102  	pid_t child = fork();
     103  	if (child < 0)
     104  		perror_msg_and_fail("fork");
     105  
     106  	if (child == 0) {
     107  		int pid = getpid();
     108  
     109  		test_rmdir(pid, /* print */ true);
     110  		test_chdir(pid, /* print */ true);
     111  
     112  		/*
     113  		 * the tracer is expected to detach at this point
     114  		 * if TOTAL_CNT < 4.
     115  		 */
     116  
     117  		test_rmdir(pid, /* print */ TOTAL_CNT > 3);
     118  
     119  		exit(0);
     120  	}
     121  
     122  	int status;
     123  	while ((waitpid(child, &status, 0)) != child) {
     124  		if (errno == EINTR)
     125  			continue;
     126  		perror_msg_and_fail("waitpid: %d", child);
     127  	}
     128  
     129  	/* the tracer is expected to detach at this point */
     130  
     131  	test_chdir(pid, /* print */ false);
     132  
     133  #if PRINT_STATS
     134  # if defined MPERS_IS_m32
     135  	printf("System call usage summary for 32 bit mode:\n");
     136  # endif
     137  # if defined MPERS_IS_mx32
     138  	printf("System call usage summary for x32 mode:\n");
     139  # endif
     140  	printf("%9s %s\n", "calls", "syscall");
     141  	printf("--------- ----------------\n");
     142  	printf("%9d %s\n", 2, "chdir");
     143  	printf("%9d %s\n", UNLINKAT_CNT, "unlinkat");
     144  	printf("--------- ----------------\n");
     145  	printf("%9d %s\n", TOTAL_CNT, "total");
     146  #endif /* PRINT_STATS */
     147  
     148  	return write_status("parent_status",
     149  			    WIFEXITED(status) ? WEXITSTATUS(status) : 1);
     150  }