1 /* Test glob compat symbol which avoid call GLOB_ALTDIRFUNC/gl_lstat.
2 Copyright (C) 2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
23 #include <sys/types.h>
25 #include <sys/types.h>
31 #include <shlib-compat.h>
32 #include <support/check.h>
33 #include <support/temp_file.h>
35 #if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)
38 compat_symbol_reference (libc
, glob
, glob
, GLIBC_2_0
);
40 /* Compat glob should not call gl_lstat since for some old binaries it
41 might be unitialized (for instance GNUmake). Check if it is indeed
43 static bool stat_called
;
44 static bool lstat_called
;
55 { "dir1lev1", 1, DT_UNKNOWN
},
58 { "file1lev2", 2, DT_REG
},
59 { "file2lev2", 2, DT_REG
},
61 static const size_t nfiles
= sizeof (filesystem
) / sizeof (filesystem
[0]);
68 char room_for_dirent
[NAME_MAX
];
72 find_file (const char *s
)
87 if (strcmp (s
, ".") == 0)
90 if (s
[0] == '.' && s
[1] == '/')
95 char *endp
= strchrnul (s
, '/');
97 while (idx
< nfiles
&& filesystem
[idx
].level
>= level
)
99 if (filesystem
[idx
].level
== level
100 && memcmp (s
, filesystem
[idx
].name
, endp
- s
) == 0
101 && filesystem
[idx
].name
[endp
- s
] == '\0')
106 if (idx
== nfiles
|| filesystem
[idx
].level
< level
)
115 if (filesystem
[idx
].type
!= DT_DIR
116 && (idx
+ 1 >= nfiles
117 || filesystem
[idx
].level
>= filesystem
[idx
+ 1].level
))
134 my_opendir (const char *s
)
136 long int idx
= find_file (s
);
137 if (idx
== -1 || filesystem
[idx
].type
!= DT_DIR
)
140 my_DIR
*dir
= malloc (sizeof (my_DIR
));
142 FAIL_EXIT1 ("cannot allocate directory handle");
144 dir
->level
= filesystem
[idx
].level
;
150 static struct dirent
*
151 my_readdir (void *gdir
)
158 while (dir
->idx
< nfiles
&& filesystem
[dir
->idx
].level
> dir
->level
)
161 if (dir
->idx
== nfiles
|| filesystem
[dir
->idx
].level
< dir
->level
)
167 dir
->d
.d_ino
= 1; /* glob should not skip this entry. */
169 #ifdef _DIRENT_HAVE_D_TYPE
170 dir
->d
.d_type
= filesystem
[dir
->idx
].type
;
173 strcpy (dir
->d
.d_name
, filesystem
[dir
->idx
].name
);
181 my_closedir (void *dir
)
187 my_stat (const char *name
, struct stat
*st
)
191 long int idx
= find_file (name
);
195 memset (st
, '\0', sizeof (*st
));
197 if (filesystem
[idx
].type
== DT_UNKNOWN
)
198 st
->st_mode
= DTTOIF (idx
+ 1 < nfiles
199 && filesystem
[idx
].level
< filesystem
[idx
+ 1].level
200 ? DT_DIR
: DT_REG
) | 0777;
202 st
->st_mode
= DTTOIF (filesystem
[idx
].type
) | 0777;
207 my_lstat (const char *name
, struct stat
*st
)
211 long int idx
= find_file (name
);
215 memset (st
, '\0', sizeof (*st
));
217 if (filesystem
[idx
].type
== DT_UNKNOWN
)
218 st
->st_mode
= DTTOIF (idx
+ 1 < nfiles
219 && filesystem
[idx
].level
< filesystem
[idx
+ 1].level
220 ? DT_DIR
: DT_REG
) | 0777;
222 st
->st_mode
= DTTOIF (filesystem
[idx
].type
) | 0777;
231 memset (&gl
, '\0', sizeof (gl
));
233 gl
.gl_closedir
= my_closedir
;
234 gl
.gl_readdir
= my_readdir
;
235 gl
.gl_opendir
= my_opendir
;
236 gl
.gl_lstat
= my_lstat
;
237 gl
.gl_stat
= my_stat
;
239 int flags
= GLOB_ALTDIRFUNC
;
242 lstat_called
= false;
244 TEST_VERIFY_EXIT (glob ("*/file1lev2", flags
, NULL
, &gl
) == 0);
245 TEST_VERIFY_EXIT (gl
.gl_pathc
== 1);
246 TEST_VERIFY_EXIT (strcmp (gl
.gl_pathv
[0], "dir1lev1/file1lev2") == 0);
248 TEST_VERIFY_EXIT (stat_called
== true);
249 TEST_VERIFY_EXIT (lstat_called
== false);
254 #else /* TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) */
263 #include <support/test-driver.c>