diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a8a11c318..587426151 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+Thu Aug 10 15:17:53 2000  Christopher Faylor <cgf@cygnus.com>
+
+	* dir.cc (readdir): Ensure that errno is *only* set when we've run out
+	of filenames.
+	* fhandler.cc (fhandler_disk_file::fstat): Use modern method for saving
+	errno, making it effective for the whole function.
+
 Tue Aug  8 22:25:39 2000  Christopher Faylor <cgf@cygnus.com>
 
 	* select.cc (allocfd_set): Zero allocated fd_set.
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index 89d85be3f..f9cb83baf 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -128,8 +128,7 @@ readdir (DIR * dir)
 {
   WIN32_FIND_DATA buf;
   HANDLE handle;
-  struct dirent *res = 0;
-  int prior_errno;
+  struct dirent *res = NULL;
 
   if (dir->__d_cookie != __DIRENT_COOKIE)
     {
@@ -138,40 +137,28 @@ readdir (DIR * dir)
       return res;
     }
 
-  if (dir->__d_u.__d_data.__handle != INVALID_HANDLE_VALUE)
+  if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
     {
-      if (FindNextFileA (dir->__d_u.__d_data.__handle, &buf) == 0)
+      handle = FindFirstFileA (dir->__d_dirname, &buf);
+      DWORD lasterr = GetLastError ();
+      dir->__d_u.__d_data.__handle = handle;
+      if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES))
 	{
-	  prior_errno = get_errno();
-	  (void) FindClose (dir->__d_u.__d_data.__handle);
-	  dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
-	  __seterrno ();
-	  /* POSIX says you shouldn't set errno when readdir can't
-	     find any more files; if another error we leave it set. */
-	  if (get_errno () == ENMFILE)
-	      set_errno (prior_errno);
-	  syscall_printf ("%p = readdir (%p)", res, dir);
+	  seterrno_from_win_error (__FILE__, __LINE__, lasterr);
 	  return res;
 	}
     }
-  else
+  else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf))
     {
-      handle = FindFirstFileA (dir->__d_dirname, &buf);
-
-      if (handle == INVALID_HANDLE_VALUE)
-	{
-	  /* It's possible that someone else deleted or emptied the directory
-	     or some such between the opendir () call and here.  */
-	  prior_errno = get_errno ();
-	  __seterrno ();
-	  /* POSIX says you shouldn't set errno when readdir can't
-	     find any more files; if another error we leave it set. */
-	  if (get_errno () == ENMFILE)
-	      set_errno (prior_errno);
-	  syscall_printf ("%p = readdir (%p)", res, dir);
-	  return res;
-	}
-      dir->__d_u.__d_data.__handle = handle;
+      DWORD lasterr = GetLastError ();
+      (void) FindClose (dir->__d_u.__d_data.__handle);
+      dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
+      /* POSIX says you shouldn't set errno when readdir can't
+	 find any more files; so, if another error we leave it set. */
+      if (lasterr != ERROR_NO_MORE_FILES)
+	  seterrno_from_win_error (__FILE__, __LINE__, lasterr);
+      syscall_printf ("%p = readdir (%p)", res, dir);
+      return res;
     }
 
   /* We get here if `buf' contains valid data.  */
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 5e96c2518..46fb51e35 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -865,7 +865,7 @@ fhandler_disk_file::fstat (struct stat *buf)
 {
   int res = 0;	// avoid a compiler warning
   BY_HANDLE_FILE_INFORMATION local;
-  int old_errno = get_errno ();
+  save_errno saved_errno;
 
   memset (buf, 0, sizeof (*buf));
 
@@ -907,12 +907,10 @@ fhandler_disk_file::fstat (struct stat *buf)
 
   if (!get_win32_name ())
     {
-      set_errno (ENOENT);
+      saved_errno.set (ENOENT);
       return -1;
     }
 
-  set_errno (old_errno);
-
   buf->st_atime   = to_time_t (&local.ftLastAccessTime);
   buf->st_mtime   = to_time_t (&local.ftLastWriteTime);
   buf->st_ctime   = to_time_t (&local.ftCreationTime);