[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r1462 - in /fsf/trunk/libc: ./ posix/ sysdeps/i386/i486/bits/ sysdeps/x86_64/bits/



Author: eglibc
Date: Thu Feb 15 00:01:38 2007
New Revision: 1462

Log:
Import glibc-mainline for 2007-02-15

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/posix/glob.c
    fsf/trunk/libc/posix/globtest.sh
    fsf/trunk/libc/sysdeps/i386/i486/bits/atomic.h
    fsf/trunk/libc/sysdeps/x86_64/bits/atomic.h

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Feb 15 00:01:38 2007
@@ -1,3 +1,27 @@
+2007-02-14  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* sysdeps/x86_64/bits/atomic;h: Fix asm parameters for some
+	byte variants.
+
+	[BZ #4040]
+	* sysdeps/i386/i486/bits/atomic.h: Fix asm parameters for some
+	byte variants.  Patch mostly be tom@xxxxxxxxxxx
+
+2007-02-14  Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	[BZ #3996]
+	* posix/glob.c (attribute_hidden): Define if not defined.
+	(glob): Unescape dirname, filename or username when needed and not
+	GLOB_NOESCAPE.  Handle \/ correctly.  Handle GLOB_MARK if filename
+	is NULL.  Handle unescaped [ in pattern without closing ].
+	Don't pass GLOB_CHECK down to recursive glob for directories.
+	(__glob_pattern_type): New function.
+	(__glob_pattern_p): Implement using __glob_pattern_type.
+	(glob_in_dir): Handle GLOB_NOCHECK patterns containing no meta
+	characters and backslashes if not GLOB_NOESCAPE or unterminated [.
+	Remove unreachable code.
+	* posix/globtest.sh: Add a couple of new tests.
+
 2007-02-13  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* po/ru.po: Update from translation team.

Modified: fsf/trunk/libc/posix/glob.c
==============================================================================
--- fsf/trunk/libc/posix/glob.c (original)
+++ fsf/trunk/libc/posix/glob.c Thu Feb 15 00:01:38 2007
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
+   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
@@ -192,9 +193,15 @@
 
 #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
 
+#ifndef attribute_hidden
+# define attribute_hidden
+#endif
+
 static int glob_in_dir (const char *pattern, const char *directory,
 			int flags, int (*errfunc) (const char *, int),
 			glob_t *pglob);
+extern int __glob_pattern_type (const char *pattern, int quote)
+    attribute_hidden;
 
 #if !defined _LIBC || !defined GLOB_ONLY_P
 static int prefix_array (const char *prefix, char **array, size_t n) __THROW;
@@ -250,6 +257,9 @@
   size_t dirlen;
   int status;
   size_t oldcount;
+  int meta;
+  int dirname_modified;
+  glob_t dirs;
 
   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
     {
@@ -418,6 +428,7 @@
   if (filename == NULL)
     filename = strchr (pattern, ':');
 #endif /* __MSDOS__ || WINDOWS32 */
+  dirname_modified = 0;
   if (filename == NULL)
     {
       /* This can mean two things: a simple name or "~name".  The latter
@@ -486,10 +497,32 @@
 	  && dirlen > 1)
 	/* "pattern/".  Expand "pattern", appending slashes.  */
 	{
+	  int orig_flags = flags;
+	  if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
+	    {
+	      /* "pattern\\/".  Remove the final backslash if it hasn't
+		 been quoted.  */
+	      char *p = (char *) &dirname[dirlen - 1];
+
+	      while (p > dirname && p[-1] == '\\') --p;
+	      if ((&dirname[dirlen] - p) & 1)
+		{
+		  *(char *) &dirname[--dirlen] = '\0';
+		  flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
+		}
+	    }
 	  int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
 	  if (val == 0)
 	    pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
 			       | (flags & GLOB_MARK));
+	  else if (val == GLOB_NOMATCH && flags != orig_flags)
+	    {
+	      /* Make sure globfree (&dirs); is a nop.  */
+	      dirs.gl_pathv = NULL;
+	      flags = orig_flags;
+	      oldcount = pglob->gl_pathc + pglob->gl_offs;
+	      goto no_matches;
+	    }
 	  return val;
 	}
     }
@@ -517,7 +550,9 @@
 #ifndef VMS
   if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
     {
-      if (dirname[1] == '\0' || dirname[1] == '/')
+      if (dirname[1] == '\0' || dirname[1] == '/'
+	  || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
+	      && (dirname[2] == '\0' || dirname[2] == '/')))
 	{
 	  /* Look up home directory.  */
 	  const char *home_dir = getenv ("HOME");
@@ -594,7 +629,10 @@
 # endif
 	  /* Now construct the full directory.  */
 	  if (dirname[1] == '\0')
-	    dirname = home_dir;
+	    {
+	      dirname = home_dir;
+	      dirlen = strlen (dirname);
+	    }
 	  else
 	    {
 	      char *newp;
@@ -603,7 +641,9 @@
 	      mempcpy (mempcpy (newp, home_dir, home_len),
 		       &dirname[1], dirlen);
 	      dirname = newp;
-	    }
+	      dirlen += home_len - 1;
+	    }
+	  dirname_modified = 1;
 	}
 # if !defined _AMIGA && !defined WINDOWS32
       else
@@ -611,15 +651,52 @@
 	  char *end_name = strchr (dirname, '/');
 	  const char *user_name;
 	  const char *home_dir;
-
+	  char *unescape = NULL;
+
+	  if (!(flags & GLOB_NOESCAPE))
+	    {
+	      if (end_name == NULL)
+		{
+		  unescape = strchr (dirname, '\\');
+		  if (unescape)
+		    end_name = strchr (unescape, '\0');
+		}
+	      else
+		unescape = memchr (dirname, '\\', end_name - dirname);
+	    }
 	  if (end_name == NULL)
 	    user_name = dirname + 1;
 	  else
 	    {
 	      char *newp;
 	      newp = (char *) __alloca (end_name - dirname);
-	      *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
-		= '\0';
+	      if (unescape != NULL)
+		{
+		  char *p = mempcpy (newp, dirname + 1,
+				     unescape - dirname - 1);
+		  char *q = unescape;
+		  while (*q != '\0')
+		    {
+		      if (*q == '\\')
+			{
+			  if (q[1] == '\0')
+			    {
+			      /* "~fo\\o\\" unescape to user_name "foo\\",
+				 but "~fo\\o\\/" unescape to user_name
+				 "foo".  */
+			      if (filename == NULL)
+				*p++ = '\\';
+			      break;
+			    }
+			  ++q;
+			}
+		      *p++ = *q++;
+		    }
+		  *p = '\0';
+		}
+	      else
+		*((char *) mempcpy (newp, dirname + 1, end_name - dirname))
+		  = '\0';
 	      user_name = newp;
 	    }
 
@@ -673,6 +750,8 @@
 	      *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
 				  end_name, rest_len)) = '\0';
 	      dirname = newp;
+	      dirlen = home_len + rest_len;
+	      dirname_modified = 1;
 	    }
 	  else
 	    if (flags & GLOB_TILDE_CHECK)
@@ -714,9 +793,22 @@
 	    }
 	  pglob->gl_pathv = new_gl_pathv;
 
-	   pglob->gl_pathv[newcount] = strdup (dirname);
-	  if (pglob->gl_pathv[newcount] == NULL)
-	    goto nospace;
+	  if (flags & GLOB_MARK)
+	    {
+	      char *p;
+	      pglob->gl_pathv[newcount] = malloc (dirlen + 2);
+	      if (pglob->gl_pathv[newcount] == NULL)
+		goto nospace;
+	      p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
+	      p[0] = '/';
+	      p[1] = '\0';
+	    }
+	  else
+	    {
+	      pglob->gl_pathv[newcount] = strdup (dirname);
+	      if (pglob->gl_pathv[newcount] == NULL)
+		goto nospace;
+	    }
 	  pglob->gl_pathv[++newcount] = NULL;
 	  ++pglob->gl_pathc;
 	  pglob->gl_flags = flags;
@@ -728,13 +820,29 @@
       return GLOB_NOMATCH;
     }
 
-  if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
+  meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
+  /* meta is 1 if correct glob pattern containing metacharacters.
+     If meta has bit (1 << 2) set, it means there was an unterminated
+     [ which we handle the same, using fnmatch.  Broken unterminated
+     pattern bracket expressions ought to be rare enough that it is
+     not worth special casing them, fnmatch will do the right thing.  */
+  if (meta & 5)
     {
       /* The directory name contains metacharacters, so we
 	 have to glob for the directory, and then glob for
 	 the pattern in each directory found.  */
-      glob_t dirs;
       size_t i;
+
+      if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
+	{
+	  /* "foo\\/bar".  Remove the final backslash from dirname
+	     if it has not been quoted.  */
+	  char *p = (char *) &dirname[dirlen - 1];
+
+	  while (p > dirname && p[-1] == '\\') --p;
+	  if ((&dirname[dirlen] - p) & 1)
+	    *(char *) &dirname[--dirlen] = '\0';
+	}
 
       if ((flags & GLOB_ALTDIRFUNC) != 0)
 	{
@@ -748,12 +856,16 @@
 	}
 
       status = glob (dirname,
-		     ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
+		     ((flags & (GLOB_ERR | GLOB_NOESCAPE
 				| GLOB_ALTDIRFUNC))
 		      | GLOB_NOSORT | GLOB_ONLYDIR),
 		     errfunc, &dirs);
       if (status != 0)
-	return status;
+	{
+	  if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
+	    return status;
+	  goto no_matches;
+	}
 
       /* We have successfully globbed the preceding directory name.
 	 For each name we found, call glob_in_dir on it and FILENAME,
@@ -811,6 +923,7 @@
 	 flag was set we must return the input pattern itself.  */
       if (pglob->gl_pathc + pglob->gl_offs == oldcount)
 	{
+	no_matches:
 	  /* No matches.  */
 	  if (flags & GLOB_NOCHECK)
 	    {
@@ -854,10 +967,44 @@
   else
     {
       int old_pathc = pglob->gl_pathc;
-
+      int orig_flags = flags;
+
+      if (meta & 2)
+	{
+	  char *p = strchr (dirname, '\\'), *q;
+	  /* We need to unescape the dirname string.  It is certainly
+	     allocated by alloca, as otherwise filename would be NULL
+	     or dirname wouldn't contain backslashes.  */
+	  q = p;
+	  do
+	    {
+	      if (*p == '\\')
+		{
+		  *q = *++p;
+		  --dirlen;
+		}
+	      else
+		*q = *p;
+	      ++q;
+	    }
+	  while (*p++ != '\0');
+	  dirname_modified = 1;
+	}
+      if (dirname_modified)
+	flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
       status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
       if (status != 0)
-	return status;
+	{
+	  if (status == GLOB_NOMATCH && flags != orig_flags
+	      && pglob->gl_pathc + pglob->gl_offs == oldcount)
+	    {
+	      /* Make sure globfree (&dirs); is a nop.  */
+	      dirs.gl_pathv = NULL;
+	      flags = orig_flags;
+	      goto no_matches;
+	    }
+	  return status;
+	}
 
       if (dirlen > 0)
 	{
@@ -1015,6 +1162,43 @@
 
 /* We must not compile this function twice.  */
 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
+int
+__glob_pattern_type (pattern, quote)
+     const char *pattern;
+     int quote;
+{
+  register const char *p;
+  int ret = 0;
+
+  for (p = pattern; *p != '\0'; ++p)
+    switch (*p)
+      {
+      case '?':
+      case '*':
+	return 1;
+
+      case '\\':
+	if (quote)
+	  {
+	    if (p[1] != '\0')
+	      ++p;
+	    ret |= 2;
+	  }
+	break;
+
+      case '[':
+	ret |= 4;
+	break;
+
+      case ']':
+	if (ret & 4)
+	  return 1;
+	break;
+      }
+
+  return ret;
+}
+
 /* Return nonzero if PATTERN contains any metacharacters.
    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
 int
@@ -1022,32 +1206,7 @@
      const char *pattern;
      int quote;
 {
-  register const char *p;
-  int open = 0;
-
-  for (p = pattern; *p != '\0'; ++p)
-    switch (*p)
-      {
-      case '?':
-      case '*':
-	return 1;
-
-      case '\\':
-	if (quote && p[1] != '\0')
-	  ++p;
-	break;
-
-      case '[':
-	open = 1;
-	break;
-
-      case ']':
-	if (open)
-	  return 1;
-	break;
-      }
-
-  return 0;
+  return __glob_pattern_type (pattern, quote) == 1;
 }
 # ifdef _LIBC
 weak_alias (__glob_pattern_p, glob_pattern_p)
@@ -1109,7 +1268,7 @@
   init_names.next = NULL;
   init_names.count = INITIAL_COUNT;
 
-  meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
+  meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
   if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
     {
       /* We need not do any tests.  The PATTERN contains no meta
@@ -1117,8 +1276,7 @@
 	 result will always contain exactly one name.  */
       flags |= GLOB_NOCHECK;
     }
-  else if (meta == 0 &&
-	   ((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL))
+  else if (meta == 0)
     {
       /* Since we use the normal file functions we can also use stat()
 	 to verify the file is there.  */
@@ -1139,119 +1297,104 @@
     }
   else
     {
-      if (pattern[0] == '\0')
-	{
-	  /* This is a special case for matching directories like in
-	     "*a/".  */
-	  names->name[cur] = (char *) malloc (1);
-	  if (names->name[cur] == NULL)
-	    goto memory_error;
-	  *names->name[cur++] = '\0';
-	  nfound = 1;
-	  meta = 0;
+      stream = ((flags & GLOB_ALTDIRFUNC)
+		? (*pglob->gl_opendir) (directory)
+		: opendir (directory));
+      if (stream == NULL)
+	{
+	  if (errno != ENOTDIR
+	      && ((errfunc != NULL && (*errfunc) (directory, errno))
+		  || (flags & GLOB_ERR)))
+	    return GLOB_ABORTED;
 	}
       else
 	{
-	  stream = ((flags & GLOB_ALTDIRFUNC)
-		    ? (*pglob->gl_opendir) (directory)
-		    : opendir (directory));
-	  if (stream == NULL)
-	    {
-	      if (errno != ENOTDIR
-		  && ((errfunc != NULL && (*errfunc) (directory, errno))
-		      || (flags & GLOB_ERR)))
-		return GLOB_ABORTED;
-	      meta = 0;
-	    }
-	  else
-	    {
-	      int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
-			       | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
+	  int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
+			   | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
 #if defined _AMIGA || defined VMS
-			       | FNM_CASEFOLD
-#endif
-			       );
-	      flags |= GLOB_MAGCHAR;
-
-	      while (1)
-		{
-		  const char *name;
-		  size_t len;
+			   | FNM_CASEFOLD
+#endif
+			   );
+	  flags |= GLOB_MAGCHAR;
+
+	  while (1)
+	    {
+	      const char *name;
+	      size_t len;
 #if defined _LIBC && !defined COMPILE_GLOB64
-		  struct dirent64 *d;
-		  union
+	      struct dirent64 *d;
+	      union
+		{
+		  struct dirent64 d64;
+		  char room [offsetof (struct dirent64, d_name[0])
+			     + NAME_MAX + 1];
+		}
+	      d64buf;
+
+	      if (flags & GLOB_ALTDIRFUNC)
+		{
+		  struct dirent *d32 = (*pglob->gl_readdir) (stream);
+		  if (d32 != NULL)
 		    {
-		      struct dirent64 d64;
-		      char room [offsetof (struct dirent64, d_name[0])
-				 + NAME_MAX + 1];
-		    }
-		  d64buf;
-
-		  if (flags & GLOB_ALTDIRFUNC)
-		    {
-		      struct dirent *d32 = (*pglob->gl_readdir) (stream);
-		      if (d32 != NULL)
-			{
-			  CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
-			  d = &d64buf.d64;
-			}
-		      else
-			d = NULL;
+		      CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
+		      d = &d64buf.d64;
 		    }
 		  else
-		    d = __readdir64 (stream);
+		    d = NULL;
+		}
+	      else
+		d = __readdir64 (stream);
 #else
-		  struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
-				      ? ((struct dirent *)
-					 (*pglob->gl_readdir) (stream))
-				      : __readdir (stream));
-#endif
-		  if (d == NULL)
-		    break;
-		  if (! REAL_DIR_ENTRY (d))
-		    continue;
-
-		  /* If we shall match only directories use the information
-		     provided by the dirent call if possible.  */
-		  if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
-		    continue;
-
-		  name = d->d_name;
-
-		  if (fnmatch (pattern, name, fnm_flags) == 0)
+	      struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
+				  ? ((struct dirent *)
+				     (*pglob->gl_readdir) (stream))
+				  : __readdir (stream));
+#endif
+	      if (d == NULL)
+		break;
+	      if (! REAL_DIR_ENTRY (d))
+		continue;
+
+	      /* If we shall match only directories use the information
+		 provided by the dirent call if possible.  */
+	      if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
+		continue;
+
+	      name = d->d_name;
+
+	      if (fnmatch (pattern, name, fnm_flags) == 0)
+		{
+		  /* If the file we found is a symlink we have to
+		     make sure the target file exists.  */
+		  if (!DIRENT_MIGHT_BE_SYMLINK (d)
+		      || link_exists_p (directory, dirlen, name, pglob,
+					flags))
 		    {
-		      /* If the file we found is a symlink we have to
-			 make sure the target file exists.  */
-		      if (!DIRENT_MIGHT_BE_SYMLINK (d)
-			  || link_exists_p (directory, dirlen, name, pglob,
-					    flags))
+		      if (cur == names->count)
 			{
-			  if (cur == names->count)
-			    {
-			      struct globnames *newnames;
-			      size_t count = names->count * 2;
-			      size_t size = (sizeof (struct globnames)
-					     + ((count - INITIAL_COUNT)
-						* sizeof (char *)));
-			      allocasize += size;
-			      if (__libc_use_alloca (allocasize))
-				newnames = names_alloca = __alloca (size);
-			      else if ((newnames = malloc (size))
-				       == NULL)
-				goto memory_error;
-			      newnames->count = count;
-			      newnames->next = names;
-			      names = newnames;
-			      cur = 0;
-			    }
-			  len = NAMLEN (d);
-			  names->name[cur] = (char *) malloc (len + 1);
-			  if (names->name[cur] == NULL)
+			  struct globnames *newnames;
+			  size_t count = names->count * 2;
+			  size_t size = (sizeof (struct globnames)
+					 + ((count - INITIAL_COUNT)
+					    * sizeof (char *)));
+			  allocasize += size;
+			  if (__libc_use_alloca (allocasize))
+			    newnames = names_alloca = __alloca (size);
+			  else if ((newnames = malloc (size))
+				   == NULL)
 			    goto memory_error;
-			  *((char *) mempcpy (names->name[cur++], name, len))
-			    = '\0';
-			  ++nfound;
+			  newnames->count = count;
+			  newnames->next = names;
+			  names = newnames;
+			  cur = 0;
 			}
+		      len = NAMLEN (d);
+		      names->name[cur] = (char *) malloc (len + 1);
+		      if (names->name[cur] == NULL)
+			goto memory_error;
+		      *((char *) mempcpy (names->name[cur++], name, len))
+			= '\0';
+		      ++nfound;
 		    }
 		}
 	    }

Modified: fsf/trunk/libc/posix/globtest.sh
==============================================================================
--- fsf/trunk/libc/posix/globtest.sh (original)
+++ fsf/trunk/libc/posix/globtest.sh Thu Feb 15 00:01:38 2007
@@ -706,6 +706,77 @@
   result=1
 fi
 
+mkdir $testdir/'dir3*'
+echo 1 > $testdir/'dir3*'/file1
+mkdir $testdir/'dir4[a'
+echo 2 > $testdir/'dir4[a'/file1
+echo 3 > $testdir/'dir4[a'/file2
+mkdir $testdir/'dir5[ab]'
+echo 4 > $testdir/'dir5[ab]'/file1
+echo 5 > $testdir/'dir5[ab]'/file2
+mkdir $testdir/dir6
+echo 6 > $testdir/dir6/'file1[a'
+echo 7 > $testdir/dir6/'file1[ab]'
+failed=0
+v=`${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+   ${common_objpfx}posix/globtest "$testdir" 'dir3\*/file2'`
+test "$v" != 'GLOB_NOMATCH' && echo "$v" >> $logfile && failed=1
+${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+${common_objpfx}posix/globtest -c "$testdir" \
+'dir3\*/file1' 'dir3\*/file2' 'dir1/file\1_1' 'dir1/file\1_9' \
+'dir2\/' 'nondir\/' 'dir4[a/fil*1' 'di*r4[a/file2' 'dir5[ab]/file[12]' \
+'dir6/fil*[a' 'dir*6/file1[a' 'dir6/fi*l[ab]' 'dir*6/file1[ab]' |
+sort > $testout
+cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
+`di*r4[a/file2'
+`dir*6/file1[a'
+`dir*6/file1[ab]'
+`dir1/file1_1'
+`dir1/file\1_9'
+`dir2/'
+`dir3*/file1'
+`dir3\*/file2'
+`dir4[a/fil*1'
+`dir5[ab]/file[12]'
+`dir6/fi*l[ab]'
+`dir6/fil*[a'
+`nondir\/'
+EOF
+HOME="$testdir" \
+${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+${common_objpfx}posix/globtest -ct "$testdir" \
+'~/dir1/file1_1' '~/dir1/file1_9' '~/dir3\*/file1' '~/dir3\*/file2' \
+'~\/dir1/file1_2' |
+sort > $testout
+cat <<EOF | $CMP - $testout >> $logfile || failed=1
+\`$testdir/dir1/file1_1'
+\`$testdir/dir1/file1_2'
+\`$testdir/dir3*/file1'
+\`~/dir1/file1_9'
+\`~/dir3\\*/file2'
+EOF
+if eval test -d ~"$USER"/; then
+  user=`echo "$USER" | sed -n -e 's/^\([^\\]\)\([^\\][^\\]*\)$/~\1\\\\\2/p'`
+  if test -n "$user"; then
+    ${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+    ${common_objpfx}posix/globtest -ctq "$testdir" "$user/" |
+    sort > $testout
+    eval echo ~$USER/ | $CMP - $testout >> $logfile || failed=1
+    ${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+    ${common_objpfx}posix/globtest -ctq "$testdir" "$user\\/" |
+    sort > $testout
+    eval echo ~$USER/ | $CMP - $testout >> $logfile || failed=1
+    ${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+    ${common_objpfx}posix/globtest -ctq "$testdir" "$user" |
+    sort > $testout
+    eval echo ~$USER | $CMP - $testout >> $logfile || failed=1
+  fi
+fi
+if test $failed -ne 0; then
+  echo "Escape tests failed" >> $logfile
+  result=1
+fi
+
 if test $result -eq 0; then
     chmod 777 $testdir/noread
     rm -fr $testdir $testout

Modified: fsf/trunk/libc/sysdeps/i386/i486/bits/atomic.h
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i486/bits/atomic.h (original)
+++ fsf/trunk/libc/sysdeps/i386/i486/bits/atomic.h Thu Feb 15 00:01:38 2007
@@ -199,7 +199,7 @@
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
        __asm __volatile ("xchgb %b0, %1"				      \
-			 : "=r" (result), "=m" (*mem)			      \
+			 : "=q" (result), "=m" (*mem)			      \
 			 : "0" (newvalue), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile ("xchgw %w0, %1"				      \
@@ -222,7 +222,7 @@
      __typeof (value) __addval = (value);				      \
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (lock "xaddb %b0, %1"				      \
-			 : "=r" (__result), "=m" (*mem)			      \
+			 : "=q" (__result), "=m" (*mem)			      \
 			 : "0" (__addval), "m" (*mem),			      \
 			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 2)					      \
@@ -272,7 +272,7 @@
     else if (sizeof (*mem) == 1)					      \
       __asm __volatile (lock "addb %b1, %0"				      \
 			: "=m" (*mem)					      \
-			: "ir" (value), "m" (*mem),			      \
+			: "iq" (value), "m" (*mem),			      \
 			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (lock "addw %w1, %0"				      \
@@ -331,7 +331,7 @@
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (LOCK_PREFIX "addb %b2, %0; setz %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
-			 : "ir" (value), "m" (*mem));			      \
+			 : "iq" (value), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile (LOCK_PREFIX "addw %w2, %0; setz %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
@@ -464,7 +464,7 @@
     if (sizeof (*mem) == 1)						      \
       __asm __volatile (LOCK_PREFIX "orb %b2, %0"			      \
 			: "=m" (*mem)					      \
-			: "m" (*mem), "ir" (1 << (bit)));		      \
+			: "m" (*mem), "iq" (1 << (bit)));		      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (LOCK_PREFIX "orw %w2, %0"			      \
 			: "=m" (*mem)					      \
@@ -503,9 +503,9 @@
 #define atomic_and(mem, mask) \
   do {									      \
     if (sizeof (*mem) == 1)						      \
-      __asm __volatile (LOCK_PREFIX "andb %1, %b0"			      \
-			: "=m" (*mem)					      \
-			: "ir" (mask), "m" (*mem));			      \
+      __asm __volatile (LOCK_PREFIX "andb %b1, %0"			      \
+			: "=m" (*mem)					      \
+			: "iq" (mask), "m" (*mem));			      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (LOCK_PREFIX "andw %1, %w0"			      \
 			: "=m" (*mem)					      \
@@ -522,9 +522,9 @@
 #define __arch_or_body(lock, mem, mask) \
   do {									      \
     if (sizeof (*mem) == 1)						      \
-      __asm __volatile (lock "orb %1, %b0"				      \
-			: "=m" (*mem)					      \
-			: "ir" (mask), "m" (*mem),			      \
+      __asm __volatile (lock "orb %b1, %0"				      \
+			: "=m" (*mem)					      \
+			: "iq" (mask), "m" (*mem),			      \
 			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (lock "orw %1, %w0"				      \

Modified: fsf/trunk/libc/sysdeps/x86_64/bits/atomic.h
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/bits/atomic.h (original)
+++ fsf/trunk/libc/sysdeps/x86_64/bits/atomic.h Thu Feb 15 00:01:38 2007
@@ -144,7 +144,7 @@
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
        __asm __volatile ("xchgb %b0, %1"				      \
-			 : "=r" (result), "=m" (*mem)			      \
+			 : "=q" (result), "=m" (*mem)			      \
 			 : "0" (newvalue), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile ("xchgw %w0, %1"				      \
@@ -165,7 +165,7 @@
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (lock "xaddb %b0, %1"				      \
-			 : "=r" (result), "=m" (*mem)			      \
+			 : "=q" (result), "=m" (*mem)			      \
 			 : "0" (value), "m" (*mem),			      \
 			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 2)					      \
@@ -209,7 +209,7 @@
     else if (sizeof (*mem) == 1)					      \
       __asm __volatile (lock "addb %b1, %0"				      \
 			: "=m" (*mem)					      \
-			: "ir" (value), "m" (*mem),			      \
+			: "iq" (value), "m" (*mem),			      \
 			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (lock "addw %w1, %0"				      \
@@ -243,7 +243,7 @@
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (LOCK_PREFIX "addb %b2, %0; sets %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
-			 : "ir" (value), "m" (*mem));			      \
+			 : "iq" (value), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile (LOCK_PREFIX "addw %w2, %0; sets %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
@@ -264,7 +264,7 @@
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (LOCK_PREFIX "addb %b2, %0; setz %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
-			 : "ir" (value), "m" (*mem));			      \
+			 : "iq" (value), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile (LOCK_PREFIX "addw %w2, %0; setz %1"		      \
 			 : "=m" (*mem), "=qm" (__result)		      \
@@ -393,7 +393,7 @@
     if (sizeof (*mem) == 1)						      \
       __asm __volatile (LOCK_PREFIX "orb %b2, %0"			      \
 			: "=m" (*mem)					      \
-			: "m" (*mem), "ir" (1L << (bit)));		      \
+			: "m" (*mem), "iq" (1L << (bit)));		      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (LOCK_PREFIX "orw %w2, %0"			      \
 			: "=m" (*mem)					      \
@@ -418,7 +418,7 @@
      if (sizeof (*mem) == 1)						      \
        __asm __volatile (LOCK_PREFIX "btsb %3, %1; setc %0"		      \
 			 : "=q" (__result), "=m" (*mem)			      \
-			 : "m" (*mem), "ir" (bit));			      \
+			 : "m" (*mem), "iq" (bit));			      \
      else if (sizeof (*mem) == 2)					      \
        __asm __volatile (LOCK_PREFIX "btsw %3, %1; setc %0"		      \
 			 : "=q" (__result), "=m" (*mem)			      \
@@ -440,30 +440,30 @@
 #define atomic_and(mem, mask) \
   do {									      \
     if (sizeof (*mem) == 1)						      \
-      __asm __volatile (LOCK_PREFIX "andb %1, %b0"			      \
+      __asm __volatile (LOCK_PREFIX "andb %b1, %0"			      \
+			: "=m" (*mem)					      \
+			: "iq" (mask), "m" (*mem));			      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (LOCK_PREFIX "andw %1, %w0"			      \
 			: "=m" (*mem)					      \
 			: "ir" (mask), "m" (*mem));			      \
-    else if (sizeof (*mem) == 2)					      \
-      __asm __volatile (LOCK_PREFIX "andw %1, %w0"			      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (LOCK_PREFIX "andl %1, %0"			      \
 			: "=m" (*mem)					      \
 			: "ir" (mask), "m" (*mem));			      \
-    else if (sizeof (*mem) == 4)					      \
-      __asm __volatile (LOCK_PREFIX "andl %1, %0"			      \
+    else								      \
+      __asm __volatile (LOCK_PREFIX "andq %1, %q0"			      \
 			: "=m" (*mem)					      \
 			: "ir" (mask), "m" (*mem));			      \
-    else								      \
-      __asm __volatile (LOCK_PREFIX "andq %1, %q0"			      \
-			: "=m" (*mem)					      \
-			: "ir" (mask), "m" (*mem));			      \
   } while (0)
 
 
 #define __arch_or_body(lock, mem, mask)					      \
   do {									      \
     if (sizeof (*mem) == 1)						      \
-      __asm __volatile (lock "orb %1, %b0"				      \
-			: "=m" (*mem)					      \
-			: "ir" (mask), "m" (*mem),			      \
+      __asm __volatile (lock "orb %b1, %0"				      \
+			: "=m" (*mem)					      \
+			: "iq" (mask), "m" (*mem),			      \
 			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
     else if (sizeof (*mem) == 2)					      \
       __asm __volatile (lock "orw %1, %w0"				      \