(root)/
strace-6.5/
tests/
at_fdcwd-pathmax.c
       1  /*
       2   * Check corner cases of AT_FDCWD path decoding.
       3   *
       4   * Copyright (c) 2021 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 <fcntl.h>
      14  #include <limits.h>
      15  #include <stdio.h>
      16  #include <string.h>
      17  #include <unistd.h>
      18  #include <sys/stat.h>
      19  #include <sys/types.h>
      20  
      21  /*
      22   * This test is designed to cover cases where AT_FDCWD path decoding
      23   * cannot happen because paths length exceed PATH_MAX.
      24   * It should be executed with -y or a similar option.
      25   */
      26  
      27  int main(void)
      28  {
      29  	/*
      30  	 * Make sure the current workdir of the tracee
      31  	 * is different from the current workdir of the tracer.
      32  	 */
      33  	create_and_enter_subdir("pathmax_subdir");
      34  
      35  	char *topdir = get_fd_path(get_dir_fd("."));
      36  
      37  	/*
      38  	 * AT_FDCWD path decoding
      39  	 */
      40  	char name[NAME_MAX + 1];
      41  	memset(name, 'x', sizeof(name) - 1);
      42  	name[sizeof(name) - 1] = '\0';
      43  
      44  	unsigned int count = 0;
      45  	for (size_t len = strlen(topdir);
      46  	     len <= PATH_MAX;
      47  	     len += sizeof(name), ++count) {
      48  		if (mkdir(name, 0700))
      49  			perror_msg_and_fail("mkdir, count=%u", count);
      50  		if (chdir(name))
      51  			perror_msg_and_fail("chdir, count=%u", count);
      52  	}
      53  
      54  	/* AT_FDCWD is not be printed since path cannot be resolved.  */
      55  
      56  	int fd = syscall(__NR_openat, AT_FDCWD, "sample", O_RDONLY);
      57  	printf("openat(AT_FDCWD, \"sample\", O_RDONLY) = %s\n",
      58  	       sprintrc(fd));
      59  
      60  	/* Go back one dir and verify it's printed.  */
      61  
      62  	--count;
      63  	if (chdir(".."))
      64  		perror_msg_and_fail("chdir");
      65  	if (rmdir(name))
      66  		perror_msg_and_fail("rmdir");
      67  
      68  	char *cwd = get_fd_path(get_dir_fd("."));
      69  
      70  	fd = syscall(__NR_openat, AT_FDCWD, "sample", O_RDONLY);
      71  	printf("openat(AT_FDCWD<%s>, \"sample\", O_RDONLY) = %s\n",
      72  	       cwd, sprintrc(fd));
      73  
      74  	/* Create a dir for which exact PATH_MAX size is returned.  */
      75  
      76  	char dir[NAME_MAX + 1];
      77  	memset(dir, 'x', sizeof(dir) - 1);
      78  	dir[PATH_MAX - (strlen(cwd) + 1)] = '\0';
      79  	if (mkdir(dir, 0700))
      80  		perror_msg_and_fail("mkdir");
      81  	if (chdir(dir))
      82  		perror_msg_and_fail("chdir");
      83  
      84  	/* AT_FDCWD is not printed since path cannot be resolved fully.  */
      85  
      86  	fd = syscall(__NR_openat, AT_FDCWD, "sample", O_RDONLY);
      87  	printf("openat(AT_FDCWD, \"sample\", O_RDONLY) = %s\n",
      88  	       sprintrc(fd));
      89  
      90  	if (chdir(".."))
      91  		perror_msg_and_fail("chdir");
      92  	if (rmdir(dir))
      93  		perror_msg_and_fail("rmdir");
      94  
      95  	for (; count > 0; --count) {
      96  		if (chdir(".."))
      97  			perror_msg_and_fail("chdir, count=%u", count);
      98  		if (rmdir(name))
      99  			perror_msg_and_fail("rmdir, count=%u", count);
     100  	}
     101  
     102  	leave_and_remove_subdir();
     103  
     104  	puts("+++ exited with 0 +++");
     105  	return 0;
     106  }