- To: bugs@gnu.org
- Subject: libc/1032: GLOB_ONLYDIR does not work
- From: Sergei Ivanov <svivanov@pdmi.ras.ru>
- Date: Sat, 20 Mar 1999 19:15:49 +0300 (MSK)
- Xref: arthur.rhein-neckar.de mail.gnats-libc-bugs:2846
>Number: 1032
>Category: libc
>Synopsis: glob does opendir on a non-directory and fails via ERRFUNC
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: libc-gnats
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Sat Mar 20 11:30:01 EST 1999
>Last-Modified:
>Originator: Sergei Ivanov <svivanov@pdmi.ras.ru>
>Organization:
>Release: libc-2.1
>Environment:
Host type: i586-pc-linux-gnu
System: Linux localhost 2.2.3 #1 Thu Mar 11 18:51:20 MSK 1999 i586 unknown
Architecture: i586
Addons: crypt linuxthreads
Build CFLAGS: -pipe -O2
Build CC: gcc
Compiler version: egcs-2.91.66 19990314 (egcs-1.1.2 release)
Kernel headers: 2.2.3
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: yes
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio
>Description:
When glob is called with a pattern containing directory components
(like "*/*") and a non-nil 3rd argument (errfunc), it calls errfunc
with ENOTDIR for a regular file that matches the directory component.
The result is a bogus glob failure (unless errfunc contains some kludge
for this particular case). I observed this problem in rpm.
I tracked this down to an internal call to glob with the (undocumented)
flag GLOB_ONLYDIR. This flag does not work. This is so on Linux/i386,
and I guess on any system with similar dirent behavior.
>How-To-Repeat:
#include <stdio.h>
#include <glob.h>
#include <string.h>
int errfn (const char *name, int n)
{
fprintf (stderr, "errfn: %s: %s\n", name, strerror(n));
return 1;
}
main()
{
glob_t res;
switch ( glob ("*/*",0,errfn,&res) ) {
case 0: printf ("Success\n"); break;
case GLOB_ABORTED: printf ("GLOB_ABORTED\n"); break;
case GLOB_NOMATCH: printf ("GLOB_NOMATCH\n"); break;
case GLOB_NOSPACE: printf ("GLOB_NOSPACE\n"); break;
default: printf ("Unknown error\n");
}
return 0;
}
===========
Running the above program in a certain directory yields:
errfn: a.c: Not a directory
GLOB_ABORTED
The output of `ls -R' in the same directory is:
.:
a.c a.out subdir
subdir:
x.c
>Fix:
A quick workaround for the errfunc case:
--- glibc-2.1/sysdeps/generic/glob.c.ori Mon Oct 12 23:55:13 1998
+++ glibc-2.1/sysdeps/generic/glob.c Sat Mar 20 17:31:46 1999
@@ -1253,7 +1253,7 @@
: (__ptr_t) opendir (directory));
if (stream == NULL)
{
- if ((errfunc != NULL && (*errfunc) (directory, errno))
+ if ((errfunc != NULL && errno != ENOTDIR && (*errfunc) (directory, errno))
|| (flags & GLOB_ERR))
return GLOB_ABORTED;
nfound = 0;
>Audit-Trail:
>Unformatted: