Blame gnulib/tests/test-readlink.h

Packit Service a2ae7a
/* Tests of readlink.
Packit Service a2ae7a
   Copyright (C) 2009-2019 Free Software Foundation, Inc.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is free software: you can redistribute it and/or modify
Packit Service a2ae7a
   it under the terms of the GNU General Public License as published by
Packit Service a2ae7a
   the Free Software Foundation; either version 3 of the License, or
Packit Service a2ae7a
   (at your option) any later version.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is distributed in the hope that it will be useful,
Packit Service a2ae7a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2ae7a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a2ae7a
   GNU General Public License for more details.
Packit Service a2ae7a
Packit Service a2ae7a
   You should have received a copy of the GNU General Public License
Packit Service a2ae7a
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service a2ae7a
Packit Service a2ae7a
/* Written by Eric Blake <ebb9@byu.net>, 2009.  */
Packit Service a2ae7a
Packit Service a2ae7a
/* This file is designed to test both readlink(a,b,c) and
Packit Service a2ae7a
   readlinkat(AT_FDCWD,a,b,c).  FUNC is the function to test.  Assumes
Packit Service a2ae7a
   that BASE and ASSERT are already defined, and that appropriate
Packit Service a2ae7a
   headers are already included.  If PRINT, warn before skipping
Packit Service a2ae7a
   symlink tests with status 77.  */
Packit Service a2ae7a
Packit Service a2ae7a
static int
Packit Service a2ae7a
test_readlink (ssize_t (*func) (char const *, char *, size_t), bool print)
Packit Service a2ae7a
{
Packit Service a2ae7a
  char buf[80];
Packit Service a2ae7a
Packit Service a2ae7a
  /* Sanity checks of failures.  Mingw lacks symlink, but readlink can
Packit Service a2ae7a
     still distinguish between various errors.  */
Packit Service a2ae7a
  memset (buf, 0xff, sizeof buf);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func ("no_such", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == ENOENT);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func ("no_such/", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == ENOENT);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func ("", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == ENOENT || errno == EINVAL);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (".", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == EINVAL);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func ("./", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == EINVAL);
Packit Service a2ae7a
  ASSERT (close (creat (BASE "file", 0600)) == 0);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (BASE "file", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == EINVAL);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (BASE "file/", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == ENOTDIR || errno == EINVAL); /* AIX yields EINVAL */
Packit Service a2ae7a
Packit Service a2ae7a
  /* Now test actual symlinks.  */
Packit Service a2ae7a
  if (symlink (BASE "dir", BASE "link"))
Packit Service a2ae7a
    {
Packit Service a2ae7a
      ASSERT (unlink (BASE "file") == 0);
Packit Service a2ae7a
      if (print)
Packit Service a2ae7a
        fputs ("skipping test: symlinks not supported on this file system\n",
Packit Service a2ae7a
               stderr);
Packit Service a2ae7a
      return 77;
Packit Service a2ae7a
    }
Packit Service a2ae7a
  ASSERT (mkdir (BASE "dir", 0700) == 0);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (BASE "link/", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == EINVAL);
Packit Service a2ae7a
  ASSERT (symlink (BASE "link", BASE "link2") == 0);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (BASE "link2/", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == EINVAL);
Packit Service a2ae7a
  ASSERT (unlink (BASE "link2") == 0);
Packit Service a2ae7a
  ASSERT (symlink (BASE "file", BASE "link2") == 0);
Packit Service a2ae7a
  errno = 0;
Packit Service a2ae7a
  ASSERT (func (BASE "link2/", buf, sizeof buf) == -1);
Packit Service a2ae7a
  ASSERT (errno == ENOTDIR || errno == EINVAL); /* AIX yields EINVAL */
Packit Service a2ae7a
  ASSERT (unlink (BASE "file") == 0);
Packit Service a2ae7a
  ASSERT (unlink (BASE "link2") == 0);
Packit Service a2ae7a
  {
Packit Service a2ae7a
    /* Up till now, no readlink has been successful, so buf should be
Packit Service a2ae7a
       unchanged.  */
Packit Service a2ae7a
    int i;
Packit Service a2ae7a
    for (i = 0; i < sizeof buf; i++)
Packit Service a2ae7a
      ASSERT (buf[i] == (char) 0xff);
Packit Service a2ae7a
  }
Packit Service a2ae7a
  {
Packit Service a2ae7a
    size_t len = strlen (BASE "dir");
Packit Service a2ae7a
    /* When passing too small of a buffer, expect the truncated
Packit Service a2ae7a
       length, or an ERANGE failure.  However, a size of 0 is not
Packit Service a2ae7a
       portable enough to test.  */
Packit Service a2ae7a
    ssize_t result;
Packit Service a2ae7a
    errno = 0;
Packit Service a2ae7a
    result = readlink (BASE "link", buf, 1);
Packit Service a2ae7a
    if (result == -1)
Packit Service a2ae7a
      {
Packit Service a2ae7a
        ASSERT (errno == ERANGE);
Packit Service a2ae7a
        ASSERT (buf[0] == (char) 0xff);
Packit Service a2ae7a
      }
Packit Service a2ae7a
    else
Packit Service a2ae7a
      {
Packit Service a2ae7a
        ASSERT (result == 1);
Packit Service a2ae7a
        ASSERT (buf[0] == BASE[0]);
Packit Service a2ae7a
      }
Packit Service a2ae7a
    ASSERT (buf[1] == (char) 0xff);
Packit Service a2ae7a
    ASSERT (func (BASE "link", buf, len) == len);
Packit Service a2ae7a
    ASSERT (strncmp (buf, BASE "dir", len) == 0);
Packit Service a2ae7a
    ASSERT (buf[len] == (char) 0xff);
Packit Service a2ae7a
    ASSERT (func (BASE "link", buf, sizeof buf) == len);
Packit Service a2ae7a
    ASSERT (strncmp (buf, BASE "dir", len) == 0);
Packit Service a2ae7a
    /* POSIX says rest of buf is unspecified; but in practice, it is
Packit Service a2ae7a
       either left alone, or NUL-terminated.  */
Packit Service a2ae7a
    ASSERT (buf[len] == '\0' || buf[len] == (char) 0xff);
Packit Service a2ae7a
  }
Packit Service a2ae7a
  ASSERT (rmdir (BASE "dir") == 0);
Packit Service a2ae7a
  ASSERT (unlink (BASE "link") == 0);
Packit Service a2ae7a
Packit Service a2ae7a
  return 0;
Packit Service a2ae7a
}