Line data Source code
1 : /* Tests of stat.
2 : Copyright (C) 2009-2020 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 Eric Blake <ebb9@byu.net>, 2009. */
18 :
19 : /* This file is designed to test both stat(n,buf) and
20 : fstatat(AT_FDCWD,n,buf,0). FUNC is the function to test. Assumes
21 : that BASE and ASSERT are already defined, and that appropriate
22 : headers are already included. If PRINT, warn before skipping
23 : symlink tests with status 77. */
24 :
25 : static int
26 1 : test_stat_func (int (*func) (char const *, struct stat *), bool print)
27 : {
28 : struct stat st1;
29 : struct stat st2;
30 1 : char *cwd = getcwd (NULL, 0);
31 :
32 1 : ASSERT (cwd);
33 1 : ASSERT (func (".", &st1) == 0);
34 1 : ASSERT (func ("./", &st2) == 0);
35 : #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
36 1 : ASSERT (SAME_INODE (st1, st2));
37 : #endif
38 1 : ASSERT (func (cwd, &st2) == 0);
39 : #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
40 1 : ASSERT (SAME_INODE (st1, st2));
41 : #endif
42 1 : ASSERT (func ("/", &st1) == 0);
43 1 : ASSERT (func ("///", &st2) == 0);
44 : #if !(defined _WIN32 && !defined __CYGWIN__ && !_GL_WINDOWS_STAT_INODES)
45 1 : ASSERT (SAME_INODE (st1, st2));
46 : #endif
47 :
48 1 : errno = 0;
49 1 : ASSERT (func ("", &st1) == -1);
50 1 : ASSERT (errno == ENOENT);
51 1 : errno = 0;
52 1 : ASSERT (func ("nosuch", &st1) == -1);
53 1 : ASSERT (errno == ENOENT);
54 1 : errno = 0;
55 1 : ASSERT (func ("nosuch/", &st1) == -1);
56 1 : ASSERT (errno == ENOENT);
57 :
58 1 : ASSERT (close (creat (BASE "file", 0600)) == 0);
59 1 : ASSERT (func (BASE "file", &st1) == 0);
60 1 : errno = 0;
61 1 : ASSERT (func (BASE "file/", &st1) == -1);
62 1 : ASSERT (errno == ENOTDIR);
63 :
64 : /* Now for some symlink tests, where supported. We set up:
65 : link1 -> directory
66 : link2 -> file
67 : link3 -> dangling
68 : link4 -> loop
69 : then test behavior with trailing slash.
70 : */
71 1 : if (symlink (".", BASE "link1") != 0)
72 : {
73 0 : ASSERT (unlink (BASE "file") == 0);
74 0 : if (print)
75 0 : fputs ("skipping test: symlinks not supported on this file system\n",
76 : stderr);
77 0 : return 77;
78 : }
79 1 : ASSERT (symlink (BASE "file", BASE "link2") == 0);
80 1 : ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
81 1 : ASSERT (symlink (BASE "link4", BASE "link4") == 0);
82 :
83 1 : ASSERT (func (BASE "link1/", &st1) == 0);
84 1 : ASSERT (S_ISDIR (st1.st_mode));
85 :
86 1 : errno = 0;
87 1 : ASSERT (func (BASE "link2/", &st1) == -1);
88 1 : ASSERT (errno == ENOTDIR);
89 :
90 1 : errno = 0;
91 1 : ASSERT (func (BASE "link3/", &st1) == -1);
92 1 : ASSERT (errno == ENOENT);
93 :
94 1 : errno = 0;
95 1 : ASSERT (func (BASE "link4/", &st1) == -1);
96 1 : ASSERT (errno == ELOOP);
97 :
98 : /* Cleanup. */
99 1 : ASSERT (unlink (BASE "file") == 0);
100 1 : ASSERT (unlink (BASE "link1") == 0);
101 1 : ASSERT (unlink (BASE "link2") == 0);
102 1 : ASSERT (unlink (BASE "link3") == 0);
103 1 : ASSERT (unlink (BASE "link4") == 0);
104 1 : free (cwd);
105 :
106 1 : return 0;
107 : }
|