about summary refs log tree commit diff
path: root/sysdeps/generic/glob.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/generic/glob.c')
-rw-r--r--sysdeps/generic/glob.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/sysdeps/generic/glob.c b/sysdeps/generic/glob.c
index 63347bdb20..5f96554bf2 100644
--- a/sysdeps/generic/glob.c
+++ b/sysdeps/generic/glob.c
@@ -240,6 +240,7 @@ extern char *alloca ();
 #endif
 
 #ifdef _LIBC
+# define strdup(str) __strdup (str)
 # define sysconf(id) __sysconf (id)
 # define closedir(dir) __closedir (dir)
 # define opendir(name) __opendir (name)
@@ -494,10 +495,13 @@ glob (pattern, flags, errfunc, pglob)
 	 case is nothing but a notation for a directory.  */
       if ((flags & GLOB_TILDE) && pattern[0] == '~')
 	{
-	  dirname = pattern;
+	  dirname = (char *) pattern;
 	  dirlen = strlen (pattern);
 
-	  filename = "";
+	  /* Set FILENAME to NULL as a special flag.  This is ugly but
+	     other solutions would requiremuch more code.  We test for
+	     this special case below.  */
+	  filename = NULL;
 	}
       else
 	{
@@ -686,6 +690,59 @@ glob (pattern, flags, errfunc, pglob)
     }
 #endif	/* Not VMS.  */
 
+  /* Now test whether we looked for "~" or "~NAME".  In this case we
+     can give the answer now.  */
+  if (filename == NULL)
+    {
+      struct stat st;
+
+      /* Return the directory if we don't check for error or if it exists.  */
+      if ((flags & GLOB_NOCHECK)
+	  || (((flags & GLOB_ALTDIRFUNC)
+	       ? (*pglob->gl_stat) (dirname, &st)
+	       : __stat (dirname, &st)) == 0
+	      && S_ISDIR (st.st_mode)))
+	{
+	  pglob->gl_pathv
+	    = (char **) realloc (pglob->gl_pathv,
+				 (pglob->gl_pathc +
+				  ((flags & GLOB_DOOFFS) ?
+				   pglob->gl_offs : 0) +
+				  1 + 1) *
+				 sizeof (char *));
+	  if (pglob->gl_pathv == NULL)
+	    return GLOB_NOSPACE;
+
+	  if (flags & GLOB_DOOFFS)
+	    while (pglob->gl_pathc < pglob->gl_offs)
+	      pglob->gl_pathv[pglob->gl_pathc++] = NULL;
+
+#if defined HAVE_STRDUP || defined _LIBC
+	  pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
+#else
+	  {
+	    size_t len = strlen (dirname) + 1;
+	    char *dircopy = malloc (len);
+	    if (dircopy != NULL)
+	      pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
+							 len);
+	  }
+#endif
+	  if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
+	    {
+	      free (pglob->gl_pathv);
+	      return GLOB_NOSPACE;
+	    }
+	  pglob->gl_pathv[++pglob->gl_pathc] = NULL;
+	  pglob->gl_flags = flags;
+
+	  return 0;
+	}
+
+      /* Not found.  */
+      return GLOB_NOMATCH;
+    }
+
   if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
     {
       /* The directory name contains metacharacters, so we