1  /* Tests of functions to access `dev_t' values.
       2     Copyright (C) 2016-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 <sys/types.h>
      20  #include <sys/sysmacros.h>
      21  #include <stdio.h>
      22  #include <inttypes.h>
      23  
      24  /* Confirm that makedev (major (d), minor (d)) == d.  */
      25  static int
      26  do_test_split_combine (dev_t d1)
      27  {
      28    unsigned int maj = major (d1);
      29    unsigned int min = minor (d1);
      30    dev_t d2 = makedev (maj, min);
      31    if (d1 != d2)
      32      {
      33        printf ("FAIL: %016" PRIx64 " != %016" PRIx64 " (maj %08x min %08x)\n",
      34  	      (uint64_t)d2, (uint64_t)d1, maj, min);
      35        return 1;
      36      }
      37    else
      38      return 0;
      39  }
      40  
      41  /* Confirm that major (makedev (maj, min)) == maj and
      42     minor (makedev (maj, min)) == min.  */
      43  static int
      44  do_test_combine_split (unsigned int maj1, unsigned int min1)
      45  {
      46    dev_t d = makedev (maj1, min1);
      47    unsigned int maj2 = major (d);
      48    unsigned int min2 = minor (d);
      49    if (maj1 != maj2 && min1 != min2)
      50      {
      51        printf ("FAIL: %08x != %08x, %08x != %08x (dev %016" PRIx64 ")\n",
      52  	      maj2, maj1, min2, min1, (uint64_t)d);
      53        return 1;
      54      }
      55    else if (maj1 != maj2)
      56      {
      57        printf ("FAIL: %08x != %08x, %08x == %08x (dev %016" PRIx64 ")\n",
      58  	      maj2, maj1, min2, min1, (uint64_t)d);
      59        return 1;
      60      }
      61    else if (min1 != min2)
      62      {
      63        printf ("FAIL: %08x == %08x, %08x != %08x (dev %016" PRIx64 ")\n",
      64  	      maj2, maj1, min2, min1, (uint64_t)d);
      65        return 1;
      66      }
      67    else
      68      return 0;
      69  }
      70  
      71  static int
      72  do_test (void)
      73  {
      74    dev_t d;
      75    unsigned int maj, min;
      76    int status = 0;
      77  
      78    /* Test the traditional range (16-bit dev_t, 8-bit each maj/min)
      79       exhaustively.  */
      80    for (d = 0; d <= 0xFFFF; d++)
      81      status |= do_test_split_combine (d);
      82  
      83    for (maj = 0; maj <= 0xFF; maj++)
      84      for (min = 0; min <= 0xFF; min++)
      85        status |= do_test_combine_split (maj, min);
      86  
      87    /* Test glibc's expanded range (64-bit dev_t, 32-bit each maj/min).
      88       Exhaustive testing would take much too long, instead we shift a
      89       pair of 1-bits over each range.  */
      90    {
      91      unsigned int a, b;
      92      for (a = 0; a <= 63; a++)
      93        do_test_split_combine (((dev_t) 0x03) << a);
      94  
      95      for (a = 0; a < 31; a++)
      96        for (b = 0; b <= 31; b++)
      97  	do_test_combine_split (0x03u << a, 0x03u << b);
      98    }
      99  
     100    return status;
     101  }
     102  
     103  #define TEST_FUNCTION do_test ()
     104  #include "../test-skeleton.c"