This is the mail archive of the libc-alpha@cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[Sergei Ivanov <svivanov@pdmi.ras.ru>] libc/1032: GLOB_ONLYDIR does not work



I can reproduce the reported problem with glibc 2.1 and Solaris 7.
This makes me wonder if this is really a bug.

Anybody volunteering to look into this?

Andreas




>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:




-- 
 Andreas Jaeger   aj@arthur.rhein-neckar.de    jaeger@informatik.uni-kl.de
  for pgp-key finger ajaeger@aixd1.rhrk.uni-kl.de

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]