diff options
Diffstat (limited to 'posix')
-rw-r--r-- | posix/Makefile | 8 | ||||
-rw-r--r-- | posix/glob.c | 269 | ||||
-rw-r--r-- | posix/globtest.c | 46 | ||||
-rwxr-xr-x | posix/globtest.sh | 98 |
4 files changed, 304 insertions, 117 deletions
diff --git a/posix/Makefile b/posix/Makefile index 285f3b306c..2b14fac138 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -28,7 +28,8 @@ headers := sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h \ bits/waitflags.h bits/waitstatus.h sys/unistd.h sched.h \ bits/sched.h re_comp.h wait.h -distribute := confstr.h TESTS TESTS2C.sed testcases.h +distribute := confstr.h TESTS TESTS2C.sed testcases.h \ + globtest.c globtest.sh routines := \ uname \ @@ -60,6 +61,11 @@ before-compile := testcases.h include ../Rules +ifeq (no,$(cross-compiling)) +tests: $(objpfx)globtest + $(SHELL) -e globtest.sh $(common-objpfx) +endif + CFLAGS-regex.c = -Wno-unused -Wno-strict-prototypes CFLAGS-getaddrinfo.c = -DRESOLVER diff --git a/posix/glob.c b/posix/glob.c index b6e087e5eb..f0cb6d377b 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -21,12 +21,12 @@ #endif #ifdef HAVE_CONFIG_H -#include <config.h> +# include <config.h> #endif /* Enable GNU extensions in glob.h. */ #ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 +# define _GNU_SOURCE 1 #endif #include <errno.h> @@ -49,45 +49,45 @@ it is simpler to just do this in the source for each such file. */ #define GLOB_INTERFACE_VERSION 1 -#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 -#include <gnu-versions.h> -#if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION -#define ELIDE_CODE -#endif +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include <gnu-versions.h> +# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION +# define ELIDE_CODE +# endif #endif #ifndef ELIDE_CODE -#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__) -#include <stddef.h> +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include <stddef.h> #endif #if defined HAVE_UNISTD_H || defined _LIBC -#include <unistd.h> -#ifndef POSIX -#ifdef _POSIX_VERSION -#define POSIX -#endif -#endif +# include <unistd.h> +# ifndef POSIX +# ifdef _POSIX_VERSION +# define POSIX +# endif +# endif #endif -#if !defined (_AMIGA) && !defined (VMS) && !defined(WINDOWS32) -#include <pwd.h> +#if !defined _AMIGA && !defined VMS && !defined WINDOWS32 +# include <pwd.h> #endif -#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS extern int errno; #endif #ifndef __set_errno -#define __set_errno(val) errno = (val) +# define __set_errno(val) errno = (val) #endif #ifndef NULL -#define NULL 0 +# define NULL 0 #endif -#if defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__) +#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ # include <dirent.h> # define NAMLEN(dirent) strlen((dirent)->d_name) #else @@ -110,36 +110,36 @@ extern int errno; /* In GNU systems, <dirent.h> defines this macro for us. */ #ifdef _D_NAMLEN -#undef NAMLEN -#define NAMLEN(d) _D_NAMLEN(d) +# undef NAMLEN +# define NAMLEN(d) _D_NAMLEN(d) #endif -#if (defined (POSIX) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__) +#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ /* 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 REAL_DIR_ENTRY(dp) 1 #else -#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) #endif /* POSIX */ -#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) -#include <stdlib.h> -#include <string.h> -#define ANSI_STRING +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include <stdlib.h> +# include <string.h> +# define ANSI_STRING #else /* No standard headers. */ extern char *getenv (); -#ifdef HAVE_STRING_H -#include <string.h> -#define ANSI_STRING -#else -#include <strings.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif +# ifdef HAVE_STRING_H +# include <string.h> +# define ANSI_STRING +# else +# include <strings.h> +# endif +# ifdef HAVE_MEMORY_H +# include <memory.h> +# endif extern char *malloc (), *realloc (); extern void free (); @@ -151,35 +151,35 @@ extern void abort (), exit (); #ifndef ANSI_STRING -#ifndef bzero +# ifndef bzero extern void bzero (); -#endif -#ifndef bcopy +# endif +# ifndef bcopy extern void bcopy (); -#endif +# endif -#define memcpy(d, s, n) bcopy ((s), (d), (n)) -#define strrchr rindex +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define strrchr rindex /* memset is only used for zero here, but let's be paranoid. */ -#define memset(s, better_be_zero, n) \ +# define memset(s, better_be_zero, n) \ ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) #endif /* Not ANSI_STRING. */ #if !defined HAVE_STRCOLL && !defined _LIBC -#define strcoll strcmp +# define strcoll strcmp #endif #ifndef __GNU_LIBRARY__ -#ifdef __GNUC__ +# ifdef __GNUC__ __inline -#endif -#ifndef __SASC -#ifdef WINDOWS32 +# endif +# ifndef __SASC +# ifdef WINDOWS32 static void * -#else +# else static char * -#endif +# endif my_realloc (p, n) char *p; unsigned int n; @@ -190,47 +190,47 @@ my_realloc (p, n) return (char *) malloc (n); return (char *) realloc (p, n); } -#define realloc my_realloc -#endif /* __SASC */ +# define realloc my_realloc +# endif /* __SASC */ #endif /* __GNU_LIBRARY__ */ -#if !defined(__alloca) && !defined(__GNU_LIBRARY__) +#if !defined __alloca && !defined __GNU_LIBRARY__ -#ifdef __GNUC__ -#undef alloca -#define alloca(n) __builtin_alloca (n) -#else /* Not GCC. */ -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#else /* Not HAVE_ALLOCA_H. */ -#ifndef _AIX -#ifdef WINDOWS32 -#include <malloc.h> -#else +# ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +# else /* Not GCC. */ +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else /* Not HAVE_ALLOCA_H. */ +# ifndef _AIX +# ifdef WINDOWS32 +# include <malloc.h> +# else extern char *alloca (); -#endif /* WINDOWS32 */ -#endif /* Not _AIX. */ -#endif /* sparc or HAVE_ALLOCA_H. */ -#endif /* GCC. */ +# endif /* WINDOWS32 */ +# endif /* Not _AIX. */ +# endif /* sparc or HAVE_ALLOCA_H. */ +# endif /* GCC. */ -#define __alloca alloca +# define __alloca alloca #endif #ifndef __GNU_LIBRARY__ -#define __stat stat -#ifdef STAT_MACROS_BROKEN -#undef S_ISDIR -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif +# define __stat stat +# ifdef STAT_MACROS_BROKEN +# undef S_ISDIR +# endif +# ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# endif #endif -#if !(defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) -#undef size_t -#define size_t unsigned int +#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) +# undef size_t +# define size_t unsigned int #endif /* Some system header files erroneously define these. @@ -508,18 +508,18 @@ glob (pattern, flags, errfunc, pglob) { /* Look up home directory. */ char *home_dir = getenv ("HOME"); -#ifdef _AMIGA +# ifdef _AMIGA if (home_dir == NULL || home_dir[0] == '\0') home_dir = "SYS:"; -#else -#ifdef WINDOWS32 +# else +# ifdef WINDOWS32 if (home_dir == NULL || home_dir[0] == '\0') home_dir = "c:/users/default"; /* poor default */ -#else +# else if (home_dir == NULL || home_dir[0] == '\0') { int success; -#if defined HAVE_GETLOGIN_R || defined _LIBC +# if defined HAVE_GETLOGIN_R || defined _LIBC extern int getlogin_r __P ((char *, size_t)); size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; char *name; @@ -531,15 +531,15 @@ glob (pattern, flags, errfunc, pglob) name = (char *) __alloca (buflen); success = getlogin_r (name, buflen) >= 0; -#else +# else extern char *getlogin __P ((void)); char *name; success = (name = getlogin ()) != NULL; -#endif +# endif if (success) { -#if defined HAVE_GETPWNAM_R || defined _LIBC +# if defined HAVE_GETPWNAM_R || defined _LIBC size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf; struct passwd pwbuf, *p; @@ -548,18 +548,18 @@ glob (pattern, flags, errfunc, pglob) success = (__getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) >= 0); -#else +# else struct passwd *p = getpwnam (name); success = p != NULL; -#endif +# endif if (success) home_dir = p->pw_dir; } } if (home_dir == NULL || home_dir[0] == '\0') home_dir = (char *) "~"; /* No luck. */ -#endif /* WINDOWS32 */ -#endif +# endif /* WINDOWS32 */ +# endif /* Now construct the full directory. */ if (dirname[1] == '\0') dirname = home_dir; @@ -573,7 +573,7 @@ glob (pattern, flags, errfunc, pglob) dirname = newp; } } -#if !defined _AMIGA && !defined WINDOWS32 +# if !defined _AMIGA && !defined WINDOWS32 else { char *end_name = strchr (dirname, '/'); @@ -591,7 +591,7 @@ glob (pattern, flags, errfunc, pglob) /* Look up specific user's home directory. */ { -#if defined HAVE_GETPWNAM_R || defined _LIBC +# if defined HAVE_GETPWNAM_R || defined _LIBC size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); char *pwtmpbuf = (char *) __alloca (buflen); struct passwd pwbuf, *p; @@ -599,13 +599,13 @@ glob (pattern, flags, errfunc, pglob) home_dir = p->pw_dir; else home_dir = NULL; -#else +# else struct passwd *p = getpwnam (user_name); if (p != NULL) home_dir = p->pw_dir; else home_dir = NULL; -#endif +# endif } /* If we found a home directory use this. */ if (home_dir != NULL) @@ -620,7 +620,7 @@ glob (pattern, flags, errfunc, pglob) dirname = newp; } } -#endif /* Not Amiga && not WINDOWS32. */ +# endif /* Not Amiga && not WINDOWS32. */ } #endif /* Not VMS. */ @@ -912,8 +912,42 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) if (!__glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE))) { - stream = NULL; - flags |= GLOB_NOCHECK; + /* We must check whether the file in this directory exists. */ + stream = ((flags & GLOB_ALTDIRFUNC) ? + (*pglob->gl_opendir) (directory) : + (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if ((errfunc != NULL && (*errfunc) (directory, errno)) || + (flags & GLOB_ERR)) + return GLOB_ABORTED; + } + else + while (1) + { + struct dirent *d = ((flags & GLOB_ALTDIRFUNC) ? + (*pglob->gl_readdir) (stream) : + readdir ((DIR *) stream)); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + + if (strcmp (pattern, d->d_name) == 0) + { + size_t len = NAMLEN (d); + names = + (struct globlink *) __alloca (sizeof (struct globlink)); + names->name = (char *) malloc (len + 1); + if (names->name == NULL) + goto memory_error; + memcpy ((__ptr_t) names->name, pattern, len); + names->name[len] = '\0'; + names->next = NULL; + nfound = 1; + break; + } + } } else { @@ -984,24 +1018,27 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) names->name[len] = '\0'; } - pglob->gl_pathv - = (char **) realloc (pglob->gl_pathv, - (pglob->gl_pathc + - ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + - nfound + 1) * - sizeof (char *)); - if (pglob->gl_pathv == NULL) - goto memory_error; + if (nfound != 0) + { + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; - if (flags & GLOB_DOOFFS) - while (pglob->gl_pathc < pglob->gl_offs) - pglob->gl_pathv[pglob->gl_pathc++] = NULL; + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; - for (; names != NULL; names = names->next) - pglob->gl_pathv[pglob->gl_pathc++] = names->name; - pglob->gl_pathv[pglob->gl_pathc] = NULL; + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; - pglob->gl_flags = flags; + pglob->gl_flags = flags; + } if (stream != NULL) { diff --git a/posix/globtest.c b/posix/globtest.c new file mode 100644 index 0000000000..589e91b973 --- /dev/null +++ b/posix/globtest.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include <glob.h> + +int +main (int argc, char *argv[]) +{ + int i; + int glob_flags = GLOB_NOSORT; + glob_t filenames; + + i = glob (argv[1], glob_flags, NULL, &filenames); + + if (i == GLOB_NOSPACE) + puts ("GLOB_NOSPACE"); + else if (i == GLOB_ABEND) + puts ("GLOB_ABEND"); + else if (i == GLOB_NOMATCH) + puts ("GLOB_NOMATCH"); + + printf ("%sNULL\n", filenames.gl_pathv ? "not " : ""); + + if (filenames.gl_pathv) + { + for (i = 0; i < filenames.gl_pathc; ++i) + printf ("`%s'\n", filenames.gl_pathv[i]); + } + return 0; +} diff --git a/posix/globtest.sh b/posix/globtest.sh new file mode 100755 index 0000000000..c51655b9b3 --- /dev/null +++ b/posix/globtest.sh @@ -0,0 +1,98 @@ +#! /bin/sh + +common_objpfx=$1; shift + +# Create the arena +: ${TMPDIR=/tmp} +testdir=$TMPDIR/globtest-dir +testout=$TMPDIR/globtest-out + +trap 'rm -fr $testdir $testout' 1 2 3 15 + +rm -fr $testdir +mkdir $testdir +echo 1 > $testdir/file1 +echo 2 > $testdir/file2 +mkdir $testdir/dir1 +mkdir $testdir/dir2 +echo 1_1 > $testdir/dir1/file1_1 +echo 1_2 > $testdir/dir1/file1_2 + +# Run some tests. +result=0 +here=`pwd` + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +`dir1' +`dir2' +`file1' +`file2' +not NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/*") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +`dir1/file1_1' +`dir1/file1_2' +not NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/1") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +GLOB_NOMATCH +NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/*1_1") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +`dir1/file1_1' +not NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*/file1_1") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +`dir1/file1_1' +not NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*-/*") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +GLOB_NOMATCH +NULL +EOF + +(cd $testdir && + LD_LIBRARY_PATH=$common_objpfx $common_objpfx/posix/globtest "*-") | +sort > $testout +cat <<"EOF" | cmp - $testout || result=1 +GLOB_NOMATCH +NULL +EOF + +if test $result -eq 0; then + rm -fr $testdir $testout +fi + +exit $result + +# Preserve executable bits for this shell script. +Local Variables: +eval:(defun frobme () (set-file-modes buffer-file-name file-mode)) +eval:(make-local-variable 'file-mode) +eval:(setq file-mode (file-modes (buffer-file-name))) +eval:(make-local-variable 'after-save-hook) +eval:(add-hook 'after-save-hook 'frobme) +End: |