
# From Gnulib:
#   http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=0b78641d85af3b72e3b9d94cb7b94e45f3c08ee5
# We don't need this directly, but it's required so that 21_getcwd_chroot
# applies cleanly.
#
# 2005-10-29  Paul Eggert  <eggert@cs.ucla.edu>
#
# 	* getcwd.c (__getcwd): Don't assume that system calls after readdir
# 	leave errno alone.  Problem reported by Dmitry V. Levin.

--- cvs-1.12.13-old/lib/getcwd.c
+++ cvs-1.12.13/lib/getcwd.c
@@ -201,6 +201,8 @@ __getcwd (char *buf, size_t size)
       ino_t dotino;
       bool mount_point;
       int parent_status;
+      size_t dirroom;
+      size_t namlen;
 
       /* Look at the parent directory.  */
 #ifdef AT_FDCWD
@@ -241,11 +243,20 @@ __getcwd (char *buf, size_t size)
 	goto lose;
       dotlist[dotlen++] = '/';
 #endif
-      /* Clear errno to distinguish EOF from error if readdir returns
-	 NULL.  */
-      __set_errno (0);
-      while ((d = __readdir (dirstream)) != NULL)
+      for (;;)
 	{
+	  /* Clear errno to distinguish EOF from error if readdir returns
+	     NULL.  */
+	  __set_errno (0);
+	  d = __readdir (dirstream);
+	  if (d == NULL)
+	    {
+	      if (errno == 0)
+		/* EOF on dirstream, which means that the current directory
+		   has been removed.  */
+		__set_errno (ENOENT);
+	      goto lose;
+	    }
 	  if (d->d_name[0] == '.' &&
 	      (d->d_name[1] == '\0' ||
 	       (d->d_name[1] == '.' && d->d_name[2] == '\0')))
@@ -303,48 +314,38 @@ __getcwd (char *buf, size_t size)
 		break;
 	    }
 	}
-      if (d == NULL)
-	{
-	  if (errno == 0)
-	    /* EOF on dirstream, which means that the current directory
-	       has been removed.  */
-	    __set_errno (ENOENT);
-	  goto lose;
-	}
-      else
-	{
-	  size_t dirroom = dirp - dir;
-	  size_t namlen = _D_EXACT_NAMLEN (d);
 
-	  if (dirroom <= namlen)
+      dirroom = dirp - dir;
+      namlen = _D_EXACT_NAMLEN (d);
+
+      if (dirroom <= namlen)
+	{
+	  if (size != 0)
 	    {
-	      if (size != 0)
-		{
-		  __set_errno (ERANGE);
-		  goto lose;
-		}
-	      else
-		{
-		  char *tmp;
-		  size_t oldsize = allocated;
+	      __set_errno (ERANGE);
+	      goto lose;
+	    }
+	  else
+	    {
+	      char *tmp;
+	      size_t oldsize = allocated;
 
-		  allocated += MAX (allocated, namlen);
-		  if (allocated < oldsize
-		      || ! (tmp = realloc (dir, allocated)))
-		    goto memory_exhausted;
+	      allocated += MAX (allocated, namlen);
+	      if (allocated < oldsize
+		  || ! (tmp = realloc (dir, allocated)))
+		goto memory_exhausted;
 
-		  /* Move current contents up to the end of the buffer.
-		     This is guaranteed to be non-overlapping.  */
-		  dirp = memcpy (tmp + allocated - (oldsize - dirroom),
-				 tmp + dirroom,
-				 oldsize - dirroom);
-		  dir = tmp;
-		}
+	      /* Move current contents up to the end of the buffer.
+		 This is guaranteed to be non-overlapping.  */
+	      dirp = memcpy (tmp + allocated - (oldsize - dirroom),
+			     tmp + dirroom,
+			     oldsize - dirroom);
+	      dir = tmp;
 	    }
-	  dirp -= namlen;
-	  memcpy (dirp, d->d_name, namlen);
-	  *--dirp = '/';
 	}
+      dirp -= namlen;
+      memcpy (dirp, d->d_name, namlen);
+      *--dirp = '/';
 
       thisdev = dotdev;
       thisino = dotino;

