Blame sysdeps/unix/sysv/linux/tst-readdir64-compat.c

Packit Service 3c6fec
/* Test readdir64 compatibility symbol.
Packit Service 3c6fec
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit Service 3c6fec
   This file is part of the GNU C Library.
Packit Service 3c6fec
Packit Service 3c6fec
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 3c6fec
   modify it under the terms of the GNU Lesser General Public
Packit Service 3c6fec
   License as published by the Free Software Foundation; either
Packit Service 3c6fec
   version 2.1 of the License, or (at your option) any later version.
Packit Service 3c6fec
Packit Service 3c6fec
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 3c6fec
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 3c6fec
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 3c6fec
   Lesser General Public License for more details.
Packit Service 3c6fec
Packit Service 3c6fec
   You should have received a copy of the GNU Lesser General Public
Packit Service 3c6fec
   License along with the GNU C Library; if not, see
Packit Service 3c6fec
   <http://www.gnu.org/licenses/>.  */
Packit Service 3c6fec
Packit Service 3c6fec
#include <dirent.h>
Packit Service 3c6fec
#include <dlfcn.h>
Packit Service 3c6fec
#include <errno.h>
Packit Service 3c6fec
#include <shlib-compat.h>
Packit Service 3c6fec
#include <stdbool.h>
Packit Service 3c6fec
#include <stdio.h>
Packit Service 3c6fec
#include <string.h>
Packit Service 3c6fec
#include <support/check.h>
Packit Service 3c6fec
Packit Service 3c6fec
/* Copied from <olddirent.h>.  */
Packit Service 3c6fec
struct __old_dirent64
Packit Service 3c6fec
  {
Packit Service 3c6fec
    __ino_t d_ino;
Packit Service 3c6fec
    __off64_t d_off;
Packit Service 3c6fec
    unsigned short int d_reclen;
Packit Service 3c6fec
    unsigned char d_type;
Packit Service 3c6fec
    char d_name[256];
Packit Service 3c6fec
  };
Packit Service 3c6fec
Packit Service 3c6fec
typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
Packit Service 3c6fec
Packit Service 3c6fec
#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
Packit Service 3c6fec
struct __old_dirent64 *compat_readdir64 (DIR *);
Packit Service 3c6fec
compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
Packit Service 3c6fec
#endif
Packit Service 3c6fec
Packit Service 3c6fec
static int
Packit Service 3c6fec
do_test (void)
Packit Service 3c6fec
{
Packit Service 3c6fec
#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
Packit Service 3c6fec
Packit Service 3c6fec
  /* Directory stream using the non-compat readdir64 symbol.  The test
Packit Service 3c6fec
     checks against this.  */
Packit Service 3c6fec
  DIR *dir_reference = opendir (".");
Packit Service 3c6fec
  TEST_VERIFY_EXIT (dir_reference != NULL);
Packit Service 3c6fec
  DIR *dir_test = opendir (".");
Packit Service 3c6fec
  TEST_VERIFY_EXIT (dir_test != NULL);
Packit Service 3c6fec
Packit Service 3c6fec
  /* This loop assumes that the enumeration order is consistent for
Packit Service 3c6fec
     two different handles.  Nothing should write to the current
Packit Service 3c6fec
     directory (in the source tree) while this test runs, so there
Packit Service 3c6fec
     should not be any difference due to races.  */
Packit Service 3c6fec
  size_t count = 0;
Packit Service 3c6fec
  while (true)
Packit Service 3c6fec
    {
Packit Service 3c6fec
      errno = 0;
Packit Service 3c6fec
      struct dirent64 *entry_reference = readdir64 (dir_reference);
Packit Service 3c6fec
      if (entry_reference == NULL && errno != 0)
Packit Service 3c6fec
        FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
Packit Service 3c6fec
      struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
Packit Service 3c6fec
      if (entry_reference == NULL)
Packit Service 3c6fec
        {
Packit Service 3c6fec
          if (errno == EOVERFLOW)
Packit Service 3c6fec
            {
Packit Service 3c6fec
              TEST_VERIFY (entry_reference->d_ino
Packit Service 3c6fec
                           != (__ino_t) entry_reference->d_ino);
Packit Service 3c6fec
              printf ("info: inode number overflow at entry %zu\n", count);
Packit Service 3c6fec
              break;
Packit Service 3c6fec
            }
Packit Service 3c6fec
          if (errno != 0)
Packit Service 3c6fec
            FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
Packit Service 3c6fec
        }
Packit Service 3c6fec
Packit Service 3c6fec
      /* Check that both streams end at the same time.  */
Packit Service 3c6fec
      if (entry_reference == NULL)
Packit Service 3c6fec
        {
Packit Service 3c6fec
          TEST_VERIFY (entry_test == NULL);
Packit Service 3c6fec
          break;
Packit Service 3c6fec
        }
Packit Service 3c6fec
      else
Packit Service 3c6fec
        TEST_VERIFY_EXIT (entry_test != NULL);
Packit Service 3c6fec
Packit Service 3c6fec
      /* Check that the entries are the same.  */
Packit Service 3c6fec
      TEST_COMPARE_BLOB (entry_reference->d_name,
Packit Service 3c6fec
                         strlen (entry_reference->d_name),
Packit Service 3c6fec
                         entry_test->d_name, strlen (entry_test->d_name));
Packit Service 3c6fec
      TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
Packit Service 3c6fec
      TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
Packit Service 3c6fec
      TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
Packit Service 3c6fec
      TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
Packit Service 3c6fec
Packit Service 3c6fec
      ++count;
Packit Service 3c6fec
    }
Packit Service 3c6fec
  printf ("info: %zu directory entries found\n", count);
Packit Service 3c6fec
  TEST_VERIFY (count >= 3);     /* ".", "..", and some source files.  */
Packit Service 3c6fec
Packit Service 3c6fec
  TEST_COMPARE (closedir (dir_test), 0);
Packit Service 3c6fec
  TEST_COMPARE (closedir (dir_reference), 0);
Packit Service 3c6fec
#endif
Packit Service 3c6fec
  return 0;
Packit Service 3c6fec
}
Packit Service 3c6fec
Packit Service 3c6fec
#include <support/test-driver.c>