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

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