(root)/
coreutils-9.4/
gnulib-tests/
test-lstat.h
       1  /* Test of lstat() function.
       2     Copyright (C) 2008-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Simon Josefsson, 2008; and Eric Blake, 2009.  */
      18  
      19  /* This file is designed to test both lstat(n,buf) and
      20     fstatat(AT_FDCWD,n,buf,AT_SYMLINK_NOFOLLOW).  FUNC is the function
      21     to test.  Assumes that BASE and ASSERT are already defined, and
      22     that appropriate headers are already included.  If PRINT, warn
      23     before skipping symlink tests with status 77.  */
      24  
      25  static int
      26  test_lstat_func (int (*func) (char const *, struct stat *), bool print)
      27  {
      28    struct stat st1;
      29    struct stat st2;
      30  
      31    /* Test for common directories.  */
      32    ASSERT (func (".", &st1) == 0);
      33    ASSERT (func ("./", &st2) == 0);
      34  #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
      35    ASSERT (SAME_INODE (st1, st2));
      36  #endif
      37    ASSERT (S_ISDIR (st1.st_mode));
      38    ASSERT (S_ISDIR (st2.st_mode));
      39    ASSERT (func ("/", &st1) == 0);
      40    ASSERT (func ("///", &st2) == 0);
      41  #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
      42    ASSERT (SAME_INODE (st1, st2));
      43  #endif
      44    ASSERT (S_ISDIR (st1.st_mode));
      45    ASSERT (S_ISDIR (st2.st_mode));
      46    ASSERT (func ("..", &st1) == 0);
      47    ASSERT (S_ISDIR (st1.st_mode));
      48  
      49    /* Test for error conditions.  */
      50    errno = 0;
      51    ASSERT (func ("", &st1) == -1);
      52    ASSERT (errno == ENOENT);
      53    errno = 0;
      54    ASSERT (func ("nosuch", &st1) == -1);
      55    ASSERT (errno == ENOENT);
      56    errno = 0;
      57    ASSERT (func ("nosuch/", &st1) == -1);
      58    ASSERT (errno == ENOENT);
      59  
      60    ASSERT (close (creat (BASE "file", 0600)) == 0);
      61    ASSERT (func (BASE "file", &st1) == 0);
      62    ASSERT (S_ISREG (st1.st_mode));
      63    errno = 0;
      64    ASSERT (func (BASE "file/", &st1) == -1);
      65    ASSERT (errno == ENOTDIR);
      66  
      67    /* Now for some symlink tests, where supported.  We set up:
      68       link1 -> directory
      69       link2 -> file
      70       link3 -> dangling
      71       link4 -> loop
      72       then test behavior both with and without trailing slash.
      73    */
      74    if (symlink (".", BASE "link1") != 0)
      75      {
      76        ASSERT (unlink (BASE "file") == 0);
      77        if (print)
      78          fputs ("skipping test: symlinks not supported on this file system\n",
      79                 stderr);
      80        return 77;
      81      }
      82    ASSERT (symlink (BASE "file", BASE "link2") == 0);
      83    ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
      84    ASSERT (symlink (BASE "link4", BASE "link4") == 0);
      85  
      86    ASSERT (func (BASE "link1", &st1) == 0);
      87    ASSERT (S_ISLNK (st1.st_mode));
      88    ASSERT (func (BASE "link1/", &st1) == 0);
      89    ASSERT (stat (BASE "link1", &st2) == 0);
      90    ASSERT (S_ISDIR (st1.st_mode));
      91    ASSERT (S_ISDIR (st2.st_mode));
      92  #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
      93    ASSERT (SAME_INODE (st1, st2));
      94  #endif
      95  
      96    ASSERT (func (BASE "link2", &st1) == 0);
      97    ASSERT (S_ISLNK (st1.st_mode));
      98    errno = 0;
      99    ASSERT (func (BASE "link2/", &st1) == -1);
     100    ASSERT (errno == ENOTDIR);
     101  
     102    ASSERT (func (BASE "link3", &st1) == 0);
     103    ASSERT (S_ISLNK (st1.st_mode));
     104    errno = 0;
     105    ASSERT (func (BASE "link3/", &st1) == -1);
     106    ASSERT (errno == ENOENT);
     107  
     108    ASSERT (func (BASE "link4", &st1) == 0);
     109    ASSERT (S_ISLNK (st1.st_mode));
     110    errno = 0;
     111    ASSERT (func (BASE "link4/", &st1) == -1);
     112    ASSERT (errno == ELOOP);
     113  
     114    /* Cleanup.  */
     115    ASSERT (unlink (BASE "file") == 0);
     116    ASSERT (unlink (BASE "link1") == 0);
     117    ASSERT (unlink (BASE "link2") == 0);
     118    ASSERT (unlink (BASE "link3") == 0);
     119    ASSERT (unlink (BASE "link4") == 0);
     120  
     121    return 0;
     122  }