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

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