aboutsummaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/Makefile8
-rw-r--r--posix/glob.c269
-rw-r--r--posix/globtest.c46
-rwxr-xr-xposix/globtest.sh98
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: