--- grep.c.old	2005-03-13 02:55:30.000000000 +0100
+++ grep.c	2005-03-13 03:34:42.000000000 +0100
@@ -179,7 +179,12 @@
     SKIP_DEVICES
   } devices = READ_DEVICES;
 
-static int grepdir PARAMS ((char const *, struct stats const *));
+static int grep_parameter PARAMS ((char const *file, struct stats *stats));
+static int grep_dir PARAMS ((char const *, struct stats const *));
+static int grep_fd PARAMS ((int fd, char const *file, struct stats *stats));
+static int grep_stdin PARAMS ((void));
+static int grep_result PARAMS ((int count));
+
 #if defined(HAVE_DOS_FILE_CONTENTS)
 static inline int undossify_input PARAMS ((register char *, size_t));
 #endif
@@ -246,7 +251,7 @@
 /* Reset the buffer for a new file, returning zero if we should skip it.
    Initialize on the first time through. */
 static int
-reset (int fd, char const *file, struct stats *stats)
+reset (int fd, struct stats *stats)
 {
   if (! pagesize)
     {
@@ -263,7 +268,7 @@
 
   if (S_ISREG (stats->stat.st_mode))
     {
-      if (file)
+      if (fd != STDIN_FILENO)
 	bufoffset = 0;
       else
 	{
@@ -777,7 +782,7 @@
    but if the file is a directory and we search it recursively, then
    return -2 if there was a match, and -1 otherwise.  */
 static int
-grep (int fd, char const *file, struct stats *stats)
+grep_fd (int fd, char const *file, struct stats *stats)
 {
   int nlines, i;
   int not_text;
@@ -787,7 +792,7 @@
   char *lim;
   char eol = eolbyte;
 
-  if (!reset (fd, file, stats))
+  if (!reset (fd, stats))
     return 0;
 
   if (file && directories == RECURSE_DIRECTORIES
@@ -797,7 +802,7 @@
 	 when we recurse deeply.  */
       if (close (fd) != 0)
 	error (0, errno, "%s", file);
-      return grepdir (file, stats) - 2;
+      return grep_dir (file, stats) - 2;
     }
 
   totalcc = 0;
@@ -908,75 +913,92 @@
 }
 
 static int
-grepfile (char const *file, struct stats *stats)
+grep_stdin (void) {
+  struct stats s; char* file; int count;
+  s.parent = 0;
+  
+  file = label ? label : _("(standard input)");
+
+  if (fstat (STDIN_FILENO, &s.stat) != 0)
+    {
+      suppressible_error (file, errno);
+      return 0;
+    }
+  
+  count = grep_fd(STDIN_FILENO, file, &s);
+
+  if (1) {
+    off_t required_offset = outleft ? bufoffset : after_last_match;
+    if ((bufmapped || required_offset != bufoffset)
+	&& lseek (STDIN_FILENO, required_offset, SEEK_SET) < 0
+	&& S_ISREG (s.stat.st_mode))
+      error (0, errno, "%s", file);
+  }
+
+  return grep_result (count);
+}
+
+static int
+grep_parameter (char const *file, struct stats *stats)
 {
   int desc;
   int count;
-  int status;
 
-  if (! file)
+  if (stat (file, &stats->stat) != 0)
     {
-      desc = 0;
-      filename = label ? label : _("(standard input)");
+      suppressible_error (file, errno);
+      return 1;
     }
-  else
-    {
-      if (stat (file, &stats->stat) != 0)
-        {
-          suppressible_error (file, errno);
-          return 1;
-        }
-      if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
-        return 1;
+  if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
+    return 1;
 #ifndef DJGPP
-      if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode)))
+  if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode)))
 #else
-      if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode)))
+    if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode)))
 #endif
-        return 1;
-      while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
-	continue;
-
-      if (desc < 0)
+      return 1;
+  while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
+    continue;
+    
+  if (desc < 0)
+    {
+      int e = errno;
+	
+      if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
 	{
-	  int e = errno;
-
-	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
+	  if (stat (file, &stats->stat) != 0)
 	    {
-	      if (stat (file, &stats->stat) != 0)
-		{
-		  error (0, errno, "%s", file);
-		  return 1;
-		}
-
-	      return grepdir (file, stats);
+	      error (0, errno, "%s", file);
+	      return 1;
 	    }
-
-	  if (!suppress_errors)
-	    {
-	      if (directories == SKIP_DIRECTORIES)
-		switch (e)
-		  {
+	    
+	  return grep_dir (file, stats);
+	}
+	
+      if (!suppress_errors)
+	{
+	  if (directories == SKIP_DIRECTORIES)
+	    switch (e)
+	      {
 #if defined(EISDIR)
-		  case EISDIR:
-		    return 1;
+	      case EISDIR:
+		return 1;
 #endif
-		  case EACCES:
-		    /* When skipping directories, don't worry about
-		       directories that can't be opened.  */
-		    if (isdir (file))
-		      return 1;
-		    break;
-		  }
-	    }
-
-	  suppressible_error (file, e);
-	  return 1;
+	      case EACCES:
+		/* When skipping directories, don't worry about
+		   directories that can't be opened.  */
+		if (isdir (file))
+		  return 1;
+		break;
+	      }
 	}
-
-      filename = file;
-    }
-
+	
+      suppressible_error (file, e);
+      return 1;
+    }
+    
+  filename = file;
+  
 #if defined(SET_BINARY)
   /* Set input to binary mode.  Pipes are simulated with files
      on DOS, so this includes the case of "foo | grep bar".  */
@@ -984,7 +1006,27 @@
     SET_BINARY (desc);
 #endif
 
-  count = grep (desc, file, stats);
+  count = grep_fd (desc, file, stats);
+
+  if (count >= 0) {
+    while (close (desc) != 0) {
+      if (errno != EINTR)
+        {
+          error (0, errno, "%s", file);
+          break;
+        }
+    }
+  }
+
+  return grep_result (count);
+}
+
+/* perform after-grep actions and return a grep status */
+static int
+grep_result (int count)
+{
+  int status;
+
   if (count < 0)
     status = count + 2;
   else
@@ -995,33 +1037,17 @@
 	    printf ("%s%c", filename, ':' & filename_mask);
 	  printf ("%d\n", count);
 	}
-
+      
       status = !count;
       if (list_files == 1 - 2 * status)
 	printf ("%s%c", filename, '\n' & filename_mask);
-
-      if (! file)
-	{
-	  off_t required_offset = outleft ? bufoffset : after_last_match;
-	  if ((bufmapped || required_offset != bufoffset)
-	      && lseek (desc, required_offset, SEEK_SET) < 0
-	      && S_ISREG (stats->stat.st_mode))
-	    error (0, errno, "%s", filename);
-	}
-      else
-	while (close (desc) != 0)
-	  if (errno != EINTR)
-	    {
-	      error (0, errno, "%s", file);
-	      break;
-	    }
     }
-
+  
   return status;
 }
 
 static int
-grepdir (char const *dir, struct stats const *stats)
+grep_dir (char const *dir, struct stats const *stats)
 {
   int status = 1;
   struct stats const *ancestor;
@@ -1068,7 +1094,7 @@
 	  file[dirlen] = '/';
 	  strcpy (file + dirlen + needs_slash, namep);
 	  namep += namelen + 1;
-	  status &= grepfile (file, &child);
+	  status &= grep_parameter (file, &child);
 	}
       out_file -= !no_filenames;
       if (file)
@@ -1784,27 +1810,30 @@
 
   if (optind < argc)
     {
-	status = 1;
-	do
+      status = 1;
+      do
 	{
 	  char *file = argv[optind];
-	  if ((included_patterns || excluded_patterns)
-	      && !isdir (file))
-	    {
-	      if (included_patterns &&
-		  ! excluded_filename (included_patterns, file, 0))
-		continue;
-	      if (excluded_patterns &&
-		  excluded_filename (excluded_patterns, file, 0))
-		continue;
-	    }
-	  status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
-			      &stats_base);
+	  if (strcmp (file, "-") == 0)
+	    status &= grep_stdin ();
+	  else {
+	    if ((included_patterns || excluded_patterns)
+		&& !isdir (file))
+	      {
+		if (included_patterns &&
+		    ! excluded_filename (included_patterns, file, 0))
+		  continue;
+		if (excluded_patterns &&
+		    excluded_filename (excluded_patterns, file, 0))
+		  continue;
+	      }
+	    status &= grep_parameter (file, &stats_base);
+	  }
 	}
-	while ( ++optind < argc);
+      while ( ++optind < argc);
     }
   else
-    status = grepfile ((char *) NULL, &stats_base);
+    status = grep_stdin ();
 
   /* We register via atexit() to test stdout.  */
   exit (errseen ? 2 : status);
