Page MenuHome GnuPG

--search-keys output disappears if stdout is not a tty
Closed, ResolvedPublic

Description

Release: 1.2.3rc2

Environment

NetBSD/i386 1.6.1(ish)

Description

(Originally noticed in 1.2.2; verified still extant in 1.2.3rc2)

When piping stdout to anything other than a direct tty file descriptor, the list of keys returned by --search-keys disappears. No combination of "--foo-fd 2" can make it reappear on another fd, even if the fd (stderr in the case of 2) is indeed a tty.

The "Enter number..." prompt, which goes to stderr, is unaffected, so you can select keys from the now invisible menu. So, other than the absent key list, the command functions properly.

This afflicts any frontend application that wishes to provide integration functionality, such as pgpenvelope (http://pgpenvelope.sourceforge.net/) which is only capable of using --recv-keys due to this problem.

How To Repeat

$ gpg --keyserver pgp.mit.edu --search-keys foo@bar | tee

The above command will simply pipe stdout rather than presenting a tty, so otherwise the display *should* be identical to the display without "| tee". However, the command above doesn't list the found keys.

Fix

Added a fflush (stdout) before printing the prompt. This does not harm but schould solve Todd's problem.

Release Note

The fix is in 1.2.4.

Event Timeline

The buffering oddity you are seeing with "tee" is because
tee doesn't finish pocessing until the input file is closed.
That's a "tee" thing, not a GnuPG thing.

I'm not sure exactly what you expected to happen.

dshaw added a project: Restricted Project.Aug 19 2003, 6:14 AM

On Tue, 19 Aug 2003 dshaw@jabberwocky.com wrote:

: State-Changed-From-To: open->feedback

: The buffering oddity you are seeing with "tee" is because
: tee doesn't finish pocessing until the input file is closed.

Uh, no, wrong. tee will process anything it gets, at least on NetBSD; it
works "properly" on explicitly line-buffered output. But now that you
mention it and I think about the stdout buffering aspect -- if I hit "Q",
the hidden key list finally shows up.

(Remember that my problem comes from PGP/GPG frontends, which will usually
redirect stdout through a filtered pipe for screen formatting purposes.
Since that means stdout is not a tty in gpg, the OS chooses a block-buffered
rather than line-buffered strategy for stdout.)

So, it appears that gpg is depending on the OS to choose the proper
buffering strategy for stdout, which is wrong for an inherently interactive
operation. gpg should either (1) do a setlinebuf() or setvbuf() on stdout
to guarantee line buffering for the interactive output of --search-keys, or
(2) do a fflush(stdout) after printing the whole key list.

I'm happy with either solution but prefer (2), and the change is trivial.
It is implemented here against GnuPG 1.2.2:

  • g10/keyserver.c.orig Mon Aug 18 22:45:39 2003

+++ g10/keyserver.c Mon Aug 18 22:47:42 2003
@@ -1078,6 +1078,8 @@

      if(i%10==0 || rl==0)
	{

+ /* flush printed keylist before prompt */
+ fflush(stdout);

	  answer=cpr_get_no_help("keysearch.prompt",
				 _("Enter number(s), N)ext, or Q)uit > "));
	  /* control-d */
  • Todd Vierling <tv@pobox.com>
werner removed a project: Restricted Project.

fixed in 1.2.4