* Paul Eggert ([email protected]) [20100812 01:26]:
> On 08/11/10 14:34, Philipp Thomas wrote:
> > I got the following question from our ksh maintainer
> > (https://bugzilla.novell.com/show_bug.cgi?id=627524)
> 
> I can't read that; it's behind some sort of registration wall.

I forgot, sorry to have mentioned it.
 
> Your email doesn't mention ksh or diff version numbers, or platform,
> which makes things a bit hard to diagnose, but I'll give it a try
> anyhow.

As I wrote in the subject diff is 2.8.1. ksh is at 93t 2010-03-09 and
platform is SUSE LINUX Enterprise 11 SP1.

> Nor do I.  Nor can I reproduce the problem on my system (RHEL 5, ksh
> 93t+ 2010-02-02, diff 2.8.1).

I asked my collegue to do a ltrace and that identified the culprit. diff
(and cmp) do a reopen if input or output isn't a terminal. The solution is
to stat the file first and then add  a test for ! S_ISSOCK before reopening.
The patch I came up with is attached.

Philipp
Index: src/diff.c
===================================================================
--- src/diff.c.orig	2008-01-10 15:43:11.000000000 +0100
+++ src/diff.c	2010-08-11 15:56:27.154686094 +0200
@@ -509,9 +509,14 @@ main (int argc, char **argv)
 
 	case BINARY_OPTION:
 #if O_BINARY
-	  binary = true;
-	  if (! isatty (STDOUT_FILENO))
-	    freopen (NULL, "wb", stdout);
+      {
+        struct stat st;
+	    binary = true;
+
+	    fstat (STDOUT_FILENO, &st);
+	    if (! S_ISSOCK(st.st_mode) && ! isatty (STDOUT_FILENO))
+	      freopen (NULL, "wb", stdout);
+      }
 #endif
 	  break;
 
@@ -1080,26 +1085,27 @@ compare_files (struct comparison const *
 	  else if (strcmp (cmp.file[f].name, "-") == 0)
 	    {
 	      cmp.file[f].desc = STDIN_FILENO;
-	      if (binary && ! isatty (STDIN_FILENO))
-		freopen (NULL, "rb", stdin);
+
 	      if (fstat (STDIN_FILENO, &cmp.file[f].stat) != 0)
 		cmp.file[f].desc = ERRNO_ENCODE (errno);
-	      else
-		{
-		  if (S_ISREG (cmp.file[f].stat.st_mode))
-		    {
-		      off_t pos = lseek (STDIN_FILENO, 0, SEEK_CUR);
-		      if (pos < 0)
-			cmp.file[f].desc = ERRNO_ENCODE (errno);
-		      else
-			cmp.file[f].stat.st_size =
-			  MAX (0, cmp.file[f].stat.st_size - pos);
-		    }
-
-		  /* POSIX 1003.1-2001 requires current time for
-		     stdin.  */
-		  set_mtime_to_now (&cmp.file[f].stat);
-		}
+
+	      if (binary && ! S_ISSOCK(cmp.file[f].stat.st_mode)
+	          && ! isatty (STDIN_FILENO))
+		freopen (NULL, "rb", stdin);
+
+              if (S_ISREG (cmp.file[f].stat.st_mode))
+                {
+                  off_t pos = lseek (STDIN_FILENO, 0, SEEK_CUR);
+                  if (pos < 0)
+                    cmp.file[f].desc = ERRNO_ENCODE (errno);
+                  else
+                    cmp.file[f].stat.st_size =
+                      MAX (0, cmp.file[f].stat.st_size - pos);
+                }
+
+              /* POSIX 1003.1-2001 requires current time for
+                 stdin.  */
+              set_mtime_to_now (&cmp.file[f].stat);
 	    }
 	  else if (stat (cmp.file[f].name, &cmp.file[f].stat) != 0)
 	    cmp.file[f].desc = ERRNO_ENCODE (errno);
Index: src/cmp.c
===================================================================
--- src/cmp.c.orig	2007-11-25 01:09:43.000000000 +0100
+++ src/cmp.c	2010-08-11 16:05:34.941178248 +0200
@@ -283,7 +283,9 @@ main (int argc, char **argv)
       if (strcmp (file[f1], "-") == 0)
 	{
 	  file_desc[f1] = STDIN_FILENO;
-	  if (O_BINARY && ! isatty (STDIN_FILENO))
+	  fstat (file_desc[f1], stat_buf + f1);
+	  if (O_BINARY && ! S_ISSOCK((stat_buf + f1).st_mode)
+	      && ! isatty (STDIN_FILENO))
 	    freopen (NULL, "rb", stdin);
 	}
       else

Reply via email to