Howdy.  With nmh-1.0, if you pipe mhshow's output (or show's output when
it's calling mhshow) to a program, it hangs at the "Press <return> to show
content..." prompt.

The reason is that it uses a faulty means to determine the terminal's file
descriptor.  It passes 'fileno (stdout)' to read(), but of course that's
wrong if our output is being piped to a program.

Following is a patch that fixes this bug by having it open /dev/tty when
stdout isn't the terminal.  A side-effect is that the prompt doesn't show up 
in "standout" (usu. inverse) mode in this case.  Getting rid of that side
effect would take more time than I currently have available to hack at this.

Here's the patch:

*** uip/mhshowsbr.c.orig        Wed Sep  9 13:59:17 1998
--- uip/mhshowsbr.c     Fri Apr  9 18:28:41 1999
***************
*** 488,512 ****
      }
  
      if (xlist) {
!       char prompt[BUFSIZ];
  
        if (ct->c_type == CT_MULTIPART)
            list_content (ct, -1, 1, 0, 0);
        else
            list_switch (ct, -1, 1, 0, 0);
  
-       if (xpause && SOprintf ("Press <return> to show content..."))
-           printf ("Press <return> to show content...");
- 
        if (xpause) {
            int intr;
            SIGNAL_HANDLER istat;
  
            istat = SIGNAL (SIGINT, intrser);
            if ((intr = sigsetjmp (intrenv, 1)) == OK) {
!               fflush (stdout);
                prompt[0] = 0;
!               read (fileno (stdout), prompt, sizeof(prompt));
            }
            SIGNAL (SIGINT, istat);
            if (intr != OK) {
--- 488,543 ----
      }
  
      if (xlist) {
!       char          prompt[BUFSIZ];
!       static FILE*  tty_FILE = NULL;
!       static int    tty_fd;
! 
!       /* Patch: This routine used to get the terminal file descriptor with
!          'fileno (stdout)', but this is wrong when our output is being piped
!          to a program, as in 'show -form mhl.body | pgpv', causing mhshow to
!          hang at the prompt below.  If stdout isn't a terminal, get the
!          terminal file descriptor using the special "/dev/tty" pseudonym.
!          -- Dan Harkless <[EMAIL PROTECTED]>, 1999-04-09 */
!       if (tty_FILE == NULL) {
!           if (isatty(STDOUT_FILENO))
!               tty_FILE = stdout;
!           else
!               tty_FILE = fopen("/dev/tty", "r+");
!           tty_fd = fileno(tty_FILE);
!       }
  
        if (ct->c_type == CT_MULTIPART)
            list_content (ct, -1, 1, 0, 0);
        else
            list_switch (ct, -1, 1, 0, 0);
  
        if (xpause) {
            int intr;
            SIGNAL_HANDLER istat;
  
+           /* Patch: Don't call SOprintf() to print the prompt if stdout isn't
+              a terminal -- who knows what the program on the other end is
+              doing with the output (if it's pgpv 5.0i, for instance, the user
+              will never see the prompt).  In this situation, use the fallback
+              routine, which was a printf(), and I've changed to being an
+              fprintf(tty_FILE), so that the user will be sure to see the
+              prompt.  Because we aren't using SOprintf(), the user won't get
+              the prompt in standout mode when our output is going to a
+              program.  Ideally, there should be an SOfprintf(), or else
+              SOprintf() and related routines should be modified to always use
+              the terminal rather than stdout.  I started going down this path,
+              but it was taking too long to get working completely, so I'm
+              settling for the standout-lossage behavior for now.
+              -- Dan Harkless <[EMAIL PROTECTED]>, 1999-04-09 */
+           if (tty_FILE != stdout ||
+               SOprintf("Press <return> to show content...") != OK)
+               fprintf(tty_FILE, "Press <return> to show content...");
+ 
            istat = SIGNAL (SIGINT, intrser);
            if ((intr = sigsetjmp (intrenv, 1)) == OK) {
!               fflush(tty_FILE);
                prompt[0] = 0;
!               read(tty_fd, prompt, sizeof(prompt));
            }
            SIGNAL (SIGINT, istat);
            if (intr != OK) {

-----------------------------------------------------------------------
Dan Harkless  | To prevent SPAM contamination, please do not post this 
[EMAIL PROTECTED] | private email address to the USENET or WWW.  Thank you.

Reply via email to