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

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