* 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