From caa2fe5d39b5e598a5504fd6c1b88171f3eda94b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 12 Dec 1995 03:37:15 +0000 Subject: [HAVE_D_NAMLEN]: Define this for __GNU_LIBRARY__ > 1. (D_NAMLEN): Macro removed. (FAKE_DIR_ENTRY): New macro. (dir_contents_file_exists_p): Test HAVE_D_NAMLEN instead of using D_NAMLEN. (read_dirstream): Return a struct dirent * for new glob interface. (init_dir): Function removed. (dir_setup_glob): New function. --- dir.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 15 deletions(-) (limited to 'dir.c') diff --git a/dir.c b/dir.c index d87cb1c..95f2bcd 100644 --- a/dir.c +++ b/dir.c @@ -20,14 +20,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__) #include -#ifndef __GNU_LIBRARY__ -#define D_NAMLEN(d) strlen((d)->d_name) -#else /* GNU C library. */ -#define D_NAMLEN(d) ((d)->d_namlen) -#endif /* Not GNU C library. */ +#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 +#define HAVE_D_NAMLEN +#endif /* GNU C library. */ #else /* Not POSIX or HAVE_DIRENT_H. */ #define direct dirent -#define D_NAMLEN(d) ((d)->d_namlen) +#define HAVE_D_NAMLEN #ifdef HAVE_SYS_NDIR_H #include #endif /* HAVE_SYS_NDIR_H */ @@ -43,8 +41,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ #define REAL_DIR_ENTRY(dp) 1 +#define FAKE_DIR_ENTRY(dp) #else #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1) #endif /* POSIX */ #ifdef __MSDOS__ @@ -179,7 +179,7 @@ find_directory (name) /* The directory is not in the name hash table. Find its device and inode numbers, and look it up by them. */ - if (safe_stat (name, &st) < 0) + if (stat (name, &st) < 0) /* Couldn't stat the directory. Mark this by setting the `contents' member to a nil pointer. */ dir->contents = 0; @@ -295,9 +295,13 @@ dir_contents_file_exists_p (dir, filename) if (!REAL_DIR_ENTRY (d)) continue; - len = D_NAMLEN (d); +#ifdef HAVE_D_NAMLEN + len = d->d_namlen; while (d->d_name[len - 1] == '\0') --len; +#else + len = strlen (d->d_name); +#endif for (i = 0; i < len; ++i) HASH (newhash, d->d_name[i]); @@ -557,7 +561,7 @@ struct dirstream /* Forward declarations. */ static __ptr_t open_dirstream __P ((const char *)); -static const char *read_dirstream __P ((__ptr_t)); +static struct dirent *read_dirstream __P ((__ptr_t)); static __ptr_t open_dirstream (directory) @@ -584,12 +588,14 @@ open_dirstream (directory) return (__ptr_t) new; } -static const char * +static struct dirent * read_dirstream (stream) __ptr_t stream; { struct dirstream *const ds = (struct dirstream *) stream; register struct dirfile *df; + static char *buf; + static unsigned int bufsz; while (ds->bucket < DIRFILE_BUCKETS) { @@ -597,7 +603,28 @@ read_dirstream (stream) { ds->elt = df->next; if (!df->impossible) - return df->name; + { + /* The glob interface wants a `struct dirent', + so mock one up. */ + struct dirent *d; + unsigned int len = strlen (df->name) + 1; + if (sizeof *d - sizeof d->d_name + len > bufsz) + { + if (buf != 0) + free (buf); + bufsz *= 2; + if (sizeof *d - sizeof d->d_name + len > bufsz) + bufsz = sizeof *d - sizeof d->d_name + len; + buf = xmalloc (bufsz); + d = (struct dirent *) buf; + d->d_ino = 1; +#ifdef HAVE_D_NAMLEN + d->d_namlen = len - 1; +#endif + memcpy (d->d_name, df->name, len); + return d; + } + } } if (++ds->bucket == DIRFILE_BUCKETS) break; @@ -608,9 +635,17 @@ read_dirstream (stream) } void -init_dir () +dir_setup_glob (gl) + glob_t *gl; { - __glob_opendir_hook = open_dirstream; - __glob_readdir_hook = read_dirstream; - __glob_closedir_hook = (void (*) __P ((__ptr_t stream))) free; + extern int lstat (), stat (); + +#ifdef HAVE_LSTAT +#define lstat stat +#endif + gl->gl_opendir = &open_dirstream; + gl->gl_readdir = &read_dirstream; + gl->gl_closedir = &free; + gl->gl_lstat = &lstat; + gl->gl_stat = &stat; } -- cgit v1.2.3