(root)/
glibc-2.38/
misc/
tst-fd_to_filename.c
       1  /* Test for /proc/self/fd (or /dev/fd) pathname construction.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <fcntl.h>
      20  #include <fd_to_filename.h>
      21  #include <stdio.h>
      22  #include <support/check.h>
      23  #include <support/xunistd.h>
      24  
      25  /* Run a check on one value.  */
      26  static void
      27  check (int value)
      28  {
      29    if (value < 0)
      30      /* Negative descriptor values violate the precondition.  */
      31      return;
      32  
      33    struct fd_to_filename storage;
      34    char *actual = __fd_to_filename (value, &storage);
      35    char expected[100];
      36    snprintf (expected, sizeof (expected), FD_TO_FILENAME_PREFIX "%d", value);
      37    TEST_COMPARE_STRING (actual, expected);
      38  }
      39  
      40  /* Check various ranges constructed around powers.  */
      41  static void
      42  check_ranges (int base)
      43  {
      44    unsigned int power = 1;
      45    do
      46      {
      47        for (int factor = 1; factor < base; ++factor)
      48          for (int shift = -1000; shift <= 1000; ++shift)
      49            check (factor * power + shift);
      50      }
      51    while (!__builtin_mul_overflow (power, base, &power));
      52  }
      53  
      54  /* Check that it is actually possible to use a the constructed
      55     name.  */
      56  static void
      57  check_open (void)
      58  {
      59    int pipes[2];
      60    xpipe (pipes);
      61  
      62    struct fd_to_filename storage;
      63    int read_alias = xopen (__fd_to_filename (pipes[0], &storage), O_RDONLY, 0);
      64    int write_alias = xopen (__fd_to_filename (pipes[1], &storage), O_WRONLY, 0);
      65  
      66    /* Ensure that all the descriptor numbers are different.  */
      67    TEST_VERIFY (pipes[0] < pipes[1]);
      68    TEST_VERIFY (pipes[1] < read_alias);
      69    TEST_VERIFY (read_alias < write_alias);
      70  
      71    xwrite (write_alias, "1", 1);
      72    char buf[16];
      73    TEST_COMPARE_BLOB ("1", 1, buf, read (pipes[0], buf, sizeof (buf)));
      74  
      75    xwrite (pipes[1], "2", 1);
      76    TEST_COMPARE_BLOB ("2", 1, buf, read (read_alias, buf, sizeof (buf)));
      77  
      78    xwrite (write_alias, "3", 1);
      79    TEST_COMPARE_BLOB ("3", 1, buf, read (read_alias, buf, sizeof (buf)));
      80  
      81    xwrite (pipes[1], "4", 1);
      82    TEST_COMPARE_BLOB ("4", 1, buf, read (pipes[0], buf, sizeof (buf)));
      83  
      84    xclose (write_alias);
      85    xclose (read_alias);
      86    xclose (pipes[1]);
      87    xclose (pipes[0]);
      88  }
      89  
      90  static int
      91  do_test (void)
      92  {
      93    check_ranges (2);
      94    check_ranges (10);
      95  
      96    check_open ();
      97  
      98    return 0;
      99  }
     100  
     101  #include <support/test-driver.c>