bug-textutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug in close_stdout_status on Solaris 2.7 and 2.8?


From: Jim Meyering
Subject: Re: Bug in close_stdout_status on Solaris 2.7 and 2.8?
Date: Sun, 25 Aug 2002 19:27:17 +0200
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/21.3.50 (i686-pc-linux-gnu)

"Shei, Shing-Shong" <address@hidden> wrote:
> I recently compiled and installed textutils 2.1 on Solaris 2.7 and 2.8.
> Today we found a strange behavior in the 'cat':
>
>       % cat /usr/demo/SOUND/sounds/ring.au > /dev/audio
>
> (or any small size audio files there) just produces a click sound while
> you can hear the correct sound if using /usr/bin/cat or cat from version
> 1.22 instead.  I have traced the problem to that if I add 'fclose (stderr)'
> to the following block; i.e., from
>
>   if (e && __fpending (stdout) == 0)
>     return;
>
> to
>
>   if (e && __fpending (stdout) == 0) {
>     fclose (stdout);
>     return;
>   }
>
> then it starts to work.  (It doesn't if I use fflush instead of fclose.)
> Is this a problem with Solaris 2.7 and 2.8?  (Since I have compiled it
> usgin both gcc and SUN's stock and both failed, I don't think it's a
> compilation problem.)

Thank you for the complete report.

The only reason to do `fclose (stdout)' would be if there
were pending (not flushed) data.  And since cat doesn't use stdio.h --
except when printing --version or --help output --
there won't be such data any in the usual case.

Could it be due to the fact that textutils-2.1's cat doesn't `close'
the descriptor for standard output?
Maybe Sun's close function does something magic to such a device?

Would you please send me the two trace-* files produced by running
these commands?

  truss -o trace-gnu cat /usr/demo/SOUND/sounds/ring.au > /dev/audio
  truss -o trace-sun /usr/bin/cat /usr/demo/SOUND/sounds/ring.au > /dev/audio

Here's a patch that might solve the problem.
Would you please try it and let me know if it does?
It makes cat close file descriptor 1, as is done in dd.c.

Index: cat.c
===================================================================
RCS file: /fetish/cu/src/cat.c,v
retrieving revision 1.80
diff -u -p -u -p -r1.80 cat.c
--- cat.c       2 Jul 2002 09:06:33 -0000       1.80
+++ cat.c       25 Aug 2002 17:06:34 -0000
@@ -482,6 +482,17 @@ cat (
     }
 }
 
+/* This is gross, but necessary, because of the way close_stdout
+   works and because this program closes STDOUT_FILENO directly.  */
+static void (*closeout_func) (void) = close_stdout;
+
+static void
+close_stdout_wrapper (void)
+{
+  if (closeout_func)
+    (*closeout_func) ();
+}
+
 int
 main (int argc, char **argv)
 {
@@ -554,7 +565,9 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
-  atexit (close_stdout);
+  /* Arrange to close stdout if we exit via the
+     case_GETOPT_HELP_CHAR or case_GETOPT_VERSION_CHAR code.  */
+  atexit (close_stdout_wrapper);
 
   /* Parse command line options.  */
 
@@ -641,6 +654,9 @@ main (int argc, char **argv)
        }
     }
 
+  /* Don't close stdout on exit from here on.  */
+  closeout_func = NULL;
+
   /* Get device, i-node number, and optimal blocksize of output.  */
 
   if (fstat (STDOUT_FILENO, &stat_buf) < 0)
@@ -832,8 +848,11 @@ main (int argc, char **argv)
     }
   while (++argind < argc);
 
-  if (have_read_stdin && close (0) < 0)
-    error (EXIT_FAILURE, errno, "-");
+  if (have_read_stdin && close (STDIN_FILENO) < 0)
+    error (EXIT_FAILURE, errno, _("closing standard input"));
+
+  if (close (STDOUT_FILENO) < 0)
+    error (EXIT_FAILURE, errno, _("closing standard output"));
 
   exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]