[git] GPG-ERROR - branch, master, updated. libgpg-error-1.26-16-g84aaa84

by Werner Koch cvs at cvs.gnupg.org
Mon Feb 27 00:29:32 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Error codes used by GnuPG et al.".

The branch, master has been updated
       via  84aaa84d41f17d6f5e2bb31930e101568df554e2 (commit)
       via  a52f12cc1879d171ddf309b5ac461bab06c8b5e2 (commit)
       via  be49b02a56e8b405eeb0c07c80eb24e71e841b4a (commit)
       via  915e1bf2ad1b23239b17843755376344e59a3110 (commit)
      from  c9e44c92e08187626e878d826cdedf4cd4e931fe (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 84aaa84d41f17d6f5e2bb31930e101568df554e2
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Feb 27 00:26:06 2017 +0100

    Use the new tracing ramework for estream.
    
    * src/estream.c: Add trace calls to some functions.
    * src/w32-estream.c: Replace existing trace calls by the new
    framework.
    --
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/estream.c b/src/estream.c
index f3d2269..c6c9a52 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -1,6 +1,6 @@
 /* estream.c - Extended Stream I/O Library
  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011,
- *               2014, 2015, 2016 g10 Code GmbH
+ *               2014, 2015, 2016, 2017 g10 Code GmbH
  *
  * This file is part of Libestream.
  *
@@ -92,12 +92,15 @@
 # include <windows.h>
 #endif
 
+/* Enable tracing.  The value is the module name to be printed.  */
+/*#define ENABLE_TRACING "estream"*/
 
 #include "gpgrt-int.h"
 #include "estream-printf.h"
 #include "thread.h"
 #include "lock.h"
 
+
 #ifndef O_BINARY
 # define O_BINARY 0
 #endif
@@ -910,6 +913,8 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close)
   estream_cookie_fd_t fd_cookie;
   int err;
 
+  trace (("enter: fd=%d mf=%u nc=%d", fd, modeflags, no_close));
+
   fd_cookie = mem_alloc (sizeof (*fd_cookie));
   if (! fd_cookie)
     err = -1;
@@ -927,6 +932,7 @@ func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close)
       err = 0;
     }
 
+  trace_errno (("leave: cookie=%p err=%d", *cookie, err));
   return err;
 }
 
@@ -941,6 +947,8 @@ func_fd_read (void *cookie, void *buffer, size_t size)
   estream_cookie_fd_t file_cookie = cookie;
   gpgrt_ssize_t bytes_read;
 
+  trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
   if (!size)
     bytes_read = -1; /* We don't know whether anything is pending.  */
   else if (IS_INVALID_FD (file_cookie->fd))
@@ -961,6 +969,7 @@ func_fd_read (void *cookie, void *buffer, size_t size)
         post_syscall_func ();
     }
 
+  trace_errno (("leave: bytes_read=%d", (int)bytes_read));
   return bytes_read;
 }
 
@@ -974,6 +983,8 @@ func_fd_write (void *cookie, const void *buffer, size_t size)
   estream_cookie_fd_t file_cookie = cookie;
   gpgrt_ssize_t bytes_written;
 
+  trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
   if (IS_INVALID_FD (file_cookie->fd))
     {
       _gpgrt_yield ();
@@ -994,6 +1005,7 @@ func_fd_write (void *cookie, const void *buffer, size_t size)
   else
     bytes_written = size; /* Note that for a flush SIZE should be 0.  */
 
+  trace_errno (("leave: bytes_written=%d", (int)bytes_written));
   return bytes_written;
 }
 
@@ -1085,6 +1097,8 @@ func_fd_destroy (void *cookie)
   estream_cookie_fd_t fd_cookie = cookie;
   int err;
 
+  trace (("enter: cookie=%p", cookie));
+
   if (fd_cookie)
     {
       if (IS_INVALID_FD (fd_cookie->fd))
@@ -1096,6 +1110,7 @@ func_fd_destroy (void *cookie)
   else
     err = 0;
 
+  trace_errno (("leave: err=%d", err));
   return err;
 }
 
@@ -1141,6 +1156,8 @@ func_w32_create (void **cookie, HANDLE hd,
   estream_cookie_w32_t w32_cookie;
   int err;
 
+  trace (("enter: hd=%p mf=%u nc=%d nsc=%d",
+          hd, modeflags, no_close, no_syscall_clamp));
   w32_cookie = mem_alloc (sizeof (*w32_cookie));
   if (!w32_cookie)
     err = -1;
@@ -1158,6 +1175,7 @@ func_w32_create (void **cookie, HANDLE hd,
       err = 0;
     }
 
+  trace_errno (("leave: cookie=%p err=%d", *cookie, err));
   return err;
 }
 
@@ -1173,6 +1191,8 @@ func_w32_read (void *cookie, void *buffer, size_t size)
   estream_cookie_w32_t w32_cookie = cookie;
   gpgrt_ssize_t bytes_read;
 
+  trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
   if (!size)
     bytes_read = -1; /* We don't know whether anything is pending.  */
   else if (w32_cookie->hd == INVALID_HANDLE_VALUE)
@@ -1207,6 +1227,7 @@ func_w32_read (void *cookie, void *buffer, size_t size)
         post_syscall_func ();
     }
 
+  trace_errno (("leave: bytes_read=%d", (int)bytes_read));
   return bytes_read;
 }
 
@@ -1223,6 +1244,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
   estream_cookie_w32_t w32_cookie = cookie;
   gpgrt_ssize_t bytes_written;
 
+  trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
   if (w32_cookie->hd == INVALID_HANDLE_VALUE)
     {
       _gpgrt_yield ();
@@ -1251,6 +1274,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
   else
     bytes_written = size; /* Note that for a flush SIZE should be 0.  */
 
+  trace_errno (("leave: bytes_written=%d", (int)bytes_written));
+
   return bytes_written;
 }
 
@@ -1321,6 +1346,8 @@ func_w32_destroy (void *cookie)
   estream_cookie_w32_t w32_cookie = cookie;
   int err;
 
+  trace (("enter: cookie=%p", cookie));
+
   if (w32_cookie)
     {
       if (w32_cookie->hd == INVALID_HANDLE_VALUE)
@@ -1342,6 +1369,7 @@ func_w32_destroy (void *cookie)
   else
     err = 0;
 
+  trace_errno (("leave: err=%d", err));
   return err;
 }
 
@@ -2164,6 +2192,8 @@ do_close (estream_t stream, int with_locked_list)
 {
   int err;
 
+  trace (("stream %p %s", stream, with_locked_list? "(with locked list)":""));
+
   if (stream)
     {
       do_list_remove (stream, with_locked_list);
@@ -2185,6 +2215,7 @@ do_close (estream_t stream, int with_locked_list)
   else
     err = 0;
 
+  trace_errno (("stream %p err=%d", stream, err));
   return err;
 }
 
@@ -4734,18 +4765,21 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
 {
   gpgrt_poll_t *item;
   int count = 0;
-#ifndef _WIN32
+  int idx;
+#ifndef HAVE_W32_SYSTEM
   fd_set readfds, writefds, exceptfds;
   int any_readfd, any_writefd, any_exceptfd;
   int max_fd;
   int fd, ret, any;
-#endif
-  int idx;
+#endif /*HAVE_W32_SYSTEM*/
+
+  trace (("enter: nfds=%u timeout=%d", nfds, timeout));
 
   if (!fds)
     {
       _set_errno (EINVAL);
-      return -1;
+      count = -1;
+      goto leave;
     }
 
   /* Clear all response fields (even for ignored items).  */
@@ -4785,7 +4819,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
     }
 
   if (count)
-    return count;  /* Early return without waiting.  */
+    goto leave;  /* Early return without waiting.  */
 
   /* Now do the real select.  */
 #ifdef HAVE_W32_SYSTEM
@@ -4864,10 +4898,18 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
     post_syscall_func ();
 
   if (ret == -1)
-    return -1;
+    {
+      trace_errno (("select failed: "));
+      count = -1;
+      goto leave;
+    }
   if (!ret)
-    return 0; /* Timeout.  Note that in this case we can't return
-                 got_err for an invalid stream.  */
+    {
+      /* Timeout.  Note that in this case we can't return got_err for
+       * an invalid stream.  */
+      count = 0;
+      goto leave;
+    }
 
   for (item = fds, idx = 0; idx < nfds; item++, idx++)
     {
@@ -4908,6 +4950,31 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
     }
 #endif /*!HAVE_W32_SYSTEM*/
 
+ leave:
+#ifdef ENABLE_TRACING
+  trace (("leave: count=%d", count));
+  if (count > 0)
+    {
+      for (item = fds, idx = 0; idx < nfds; item++, idx++)
+        {
+          trace (("     %3d  %c%c%c%c%c  %c%c%c%c%c%c%c",
+                  idx,
+                  fds[idx].want_read?  'r':'-',
+                  fds[idx].want_write? 'w':'-',
+                  fds[idx].want_oob?   'o':'-',
+                  fds[idx].want_rdhup? 'h':'-',
+                  fds[idx].ignore?     'i':'-',
+                  fds[idx].got_read?   'r':'-',
+                  fds[idx].got_write?  'w':'-',
+                  fds[idx].got_oob?    'o':'-',
+                  fds[idx].got_rdhup?  'h':'-',
+                  fds[idx].got_hup?    'H':'-',
+                  fds[idx].got_err?    'e':'-',
+                  fds[idx].got_nval?   'n':'-'
+                  ));
+        }
+    }
+#endif /*ENABLE_TRACING*/
   return count;
 }
 
diff --git a/src/w32-estream.c b/src/w32-estream.c
index 1603d30..722cb69 100644
--- a/src/w32-estream.c
+++ b/src/w32-estream.c
@@ -40,6 +40,9 @@
 #include <io.h>
 #include <windows.h>
 
+/* Enable tracing.  The value is the module name to be printed.  */
+/*#define ENABLE_TRACING "estream" */
+
 #include "gpgrt-int.h"
 
 /*
@@ -48,33 +51,6 @@
  * writer threads that use the original I/O functions.
  */
 
-

-
-/* Tracing/debugging support.  */
-#if 0
-#define TRACE(msg, ...)                                         \
-  fprintf (stderr, msg, ## __VA_ARGS__)
-#define TRACE_CTX(ctx, msg, ...)                                \
-  fprintf (stderr, "%p: " msg "\n", ctx, ## __VA_ARGS__)
-#define TRACE_ERR(ctx, err, msg, ...)	do {                    \
-    char error_message[128];                                    \
-    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM                    \
-                  | FORMAT_MESSAGE_IGNORE_INSERTS,              \
-                  NULL,                                         \
-                  err,                                          \
-                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),    \
-                  (LPTSTR) &error_message,                      \
-                  sizeof error_message, NULL );                 \
-    fprintf (stderr, "%p: " msg ": %d (%s)\n", ctx,             \
-             ## __VA_ARGS__, (int)(err), error_message);        \
-  } while (0)
-#else
-#define TRACE(msg, ...)			(void) 0
-#define TRACE_CTX(ctx, msg, ...)	(void) 0
-#define TRACE_ERR(ctx, err, msg, ...)	(void) 0
-#endif
-
-

 
 /* Calculate array dimension.  */
 #ifndef DIM
@@ -157,7 +133,7 @@ set_synchronize (HANDLE hd)
 			GetCurrentProcess (), &new_hd,
 			EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, 0))
     {
-      TRACE_ERR (NULL, GetLastError (), "DuplicateHandle failed");
+      trace_errno (("DuplicateHandle failed: ec=%d", (int)GetLastError ()));
       /* FIXME: Should translate the error code.  */
       _gpg_err_set_errno (EIO);
       return INVALID_HANDLE_VALUE;
@@ -175,7 +151,8 @@ reader (void *arg)
   struct reader_context_s *ctx = arg;
   int nbytes;
   ssize_t nread;
-  TRACE_CTX (ctx, "reader starting");
+
+  trace (("%p: reader starting", ctx));
 
   for (;;)
     {
@@ -186,11 +163,11 @@ reader (void *arg)
 	{
 	  /* Wait for space.  */
 	  if (!ResetEvent (ctx->have_space_ev))
-	    TRACE_ERR (ctx, GetLastError (), "ResetEvent failed");
+	    trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError()));
           LeaveCriticalSection (&ctx->mutex);
-	  TRACE_CTX (ctx, "waiting for space");
+          trace (("%p: waiting for space", ctx));
 	  WaitForSingleObject (ctx->have_space_ev, INFINITE);
-	  TRACE_CTX (ctx, "got space");
+	  trace (("%p: got space", ctx));
           EnterCriticalSection (&ctx->mutex);
         }
       assert (((ctx->writepos + 1) % READBUF_SIZE != ctx->readpos));
@@ -206,11 +183,11 @@ reader (void *arg)
 	nbytes = READBUF_SIZE - ctx->writepos;
       LeaveCriticalSection (&ctx->mutex);
 
-      TRACE_CTX (ctx, "reading up to %d bytes", nbytes);
+      trace (("%p: reading up to %d bytes", ctx, nbytes));
 
       nread = ctx->pcookie->next_functions.public.func_read
         (ctx->pcookie->next_cookie, ctx->buffer + ctx->writepos, nbytes);
-      TRACE_CTX (ctx, "got %d bytes", nread);
+      trace (("%p: got %d bytes", ctx, nread));
       if (nread < 0)
         {
           ctx->error_code = (int) errno;
@@ -219,12 +196,12 @@ reader (void *arg)
           if (ctx->error_code == ERROR_BROKEN_PIPE)
             {
               ctx->eof = 1;
-              TRACE_CTX (ctx, "got EOF (broken pipe)");
+              trace (("%p: got EOF (broken pipe)", ctx));
             }
           else
             {
               ctx->error = 1;
-              TRACE_ERR (ctx, ctx->error_code, "read error");
+              trace (("%p: read error: ec=%d", ctx, ctx->error_code));
             }
           break;
         }
@@ -238,23 +215,23 @@ reader (void *arg)
       if (!nread)
 	{
 	  ctx->eof = 1;
-	  TRACE_CTX (ctx, "got eof");
+	  trace (("%p: got eof", ctx));
           LeaveCriticalSection (&ctx->mutex);
 	  break;
         }
 
       ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE;
       if (!SetEvent (ctx->have_data_ev))
-	TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed",
-                   ctx->have_data_ev);
+	trace (("%p: SetEvent (%p) failed: ec=%d",
+                ctx, ctx->have_data_ev, (int)GetLastError ()));
       LeaveCriticalSection (&ctx->mutex);
     }
   /* Indicate that we have an error or EOF.  */
   if (!SetEvent (ctx->have_data_ev))
-    TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed",
-               ctx->have_data_ev);
+    trace (("%p: SetEvent (%p) failed: ec=%d",
+            ctx, ctx->have_data_ev, (int)GetLastError ()));
 
-  TRACE_CTX (ctx, "waiting for close");
+  trace (("%p: waiting for close", ctx));
   WaitForSingleObject (ctx->close_ev, INFINITE);
 
   CloseHandle (ctx->close_ev);
@@ -294,7 +271,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie)
     ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
   if (!ctx->have_data_ev || !ctx->have_space_ev || !ctx->close_ev)
     {
-      TRACE_ERR (ctx, GetLastError (), "CreateEvent failed");
+      trace (("%p: CreateEvent failed: ec=%d", ctx, (int)GetLastError ()));
       if (ctx->have_data_ev)
 	CloseHandle (ctx->have_data_ev);
       if (ctx->have_space_ev)
@@ -317,7 +294,7 @@ create_reader (estream_cookie_w32_pollable_t pcookie)
 
   if (!ctx->thread_hd)
     {
-      TRACE_ERR (ctx, GetLastError (), "CreateThread failed");
+      trace (("%p: CreateThread failed: ec=%d", ctx, (int)GetLastError ()));
       DeleteCriticalSection (&ctx->mutex);
       if (ctx->have_data_ev)
 	CloseHandle (ctx->have_data_ev);
@@ -364,7 +341,8 @@ destroy_reader (struct reader_context_s *ctx)
       if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK,
 			NULL, 0, NULL, 0, NULL, NULL))
 	{
-	  TRACE_ERR (ctx, GetLastError (), "unblock control call failed");
+	  trace (("%p: unblock control call failed: ec=%d",
+                  ctx, (int)GetLastError ()));
 	}
     }
 #endif
@@ -397,13 +375,13 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count)
         }
     }
 
-  TRACE_CTX (ctx, "pollable read buffer=%p, count=%u", buffer, count);
+  trace (("%p: read buffer=%p, count=%u", ctx, buffer, count));
 
   if (ctx->eof_shortcut)
     return 0;
 
   EnterCriticalSection (&ctx->mutex);
-  TRACE_CTX (ctx, "readpos: %d, writepos %d", ctx->readpos, ctx->writepos);
+  trace (("%p: readpos: %d, writepos %d", ctx, ctx->readpos, ctx->writepos));
   if (ctx->readpos == ctx->writepos && !ctx->error)
     {
       /* No data available.  */
@@ -417,9 +395,9 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count)
           return -1;
         }
 
-      TRACE_CTX (ctx, "waiting for data");
+      trace (("%p: waiting for data", ctx));
       WaitForSingleObject (ctx->have_data_ev, INFINITE);
-      TRACE_CTX (ctx, "data available");
+      trace (("%p: data available", ctx));
       EnterCriticalSection (&ctx->mutex);
     }
 
@@ -431,8 +409,8 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count)
 	return 0;
       if (!ctx->error)
 	{
-	  TRACE_CTX (ctx, "EOF but ctx->eof flag not set");
-	  return 0;
+	  trace (("%p: EOF but ctx->eof flag not set", ctx));
+          return 0;
 	}
       _gpg_err_set_errno (ctx->error_code);
       return -1;
@@ -449,7 +427,7 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count)
     {
       if (!ResetEvent (ctx->have_data_ev))
 	{
-	  TRACE_ERR (ctx, GetLastError (), "ResetEvent failed");
+	  trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ()));
           LeaveCriticalSection (&ctx->mutex);
 	  /* FIXME: Should translate the error code.  */
 	  _gpg_err_set_errno (EIO);
@@ -458,8 +436,8 @@ func_w32_pollable_read (void *cookie, void *buffer, size_t count)
     }
   if (!SetEvent (ctx->have_space_ev))
     {
-      TRACE_ERR (ctx, GetLastError (), "SetEvent (%p) failed",
-                 ctx->have_space_ev);
+      trace (("%p: SetEvent (%p) failed: ec=%d",
+              ctx, ctx->have_space_ev, (int)GetLastError ()));
       LeaveCriticalSection (&ctx->mutex);
       /* FIXME: Should translate the error code.  */
       _gpg_err_set_errno (EIO);
@@ -480,7 +458,7 @@ writer (void *arg)
   struct writer_context_s *ctx = arg;
   ssize_t nwritten;
 
-  TRACE_CTX (ctx, "writer starting");
+  trace (("%p: writer starting", ctx));
 
   for (;;)
     {
@@ -493,13 +471,13 @@ writer (void *arg)
       if (!ctx->nbytes)
 	{
 	  if (!SetEvent (ctx->is_empty))
-	    TRACE_ERR (ctx, GetLastError (), "SetEvent failed");
+	    trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ()));
 	  if (!ResetEvent (ctx->have_data))
-	    TRACE_ERR (ctx, GetLastError (), "ResetEvent failed");
+	    trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ()));
           LeaveCriticalSection (&ctx->mutex);
-	  TRACE_CTX (ctx, "idle");
+	  trace (("%p: idle", ctx));
 	  WaitForSingleObject (ctx->have_data, INFINITE);
-	  TRACE_CTX (ctx, "got data to write");
+	  trace (("%p: got data to write", ctx));
           EnterCriticalSection (&ctx->mutex);
         }
       if (ctx->stop_me && !ctx->nbytes)
@@ -509,24 +487,24 @@ writer (void *arg)
         }
       LeaveCriticalSection (&ctx->mutex);
 
-      TRACE_CTX (ctx, "writing up to %d bytes", ctx->nbytes);
+      trace (("%p: writing up to %d bytes", ctx, ctx->nbytes));
 
       nwritten = ctx->pcookie->next_functions.public.func_write
         (ctx->pcookie->next_cookie, ctx->buffer, ctx->nbytes);
-      TRACE_CTX (ctx, "wrote %d bytes", nwritten);
+      trace (("%p: wrote %d bytes", ctx, nwritten));
       if (nwritten < 1)
         {
           /* XXX */
           if (errno == ERROR_BUSY)
             {
               /* Probably stop_me is set now.  */
-              TRACE_CTX (ctx, "pipe busy (unblocked?)");
+              trace (("%p: pipe busy (unblocked?)", ctx));
               continue;
             }
 
           ctx->error_code = errno;
           ctx->error = 1;
-          TRACE_ERR (ctx, ctx->error_code, "write error");
+          trace (("%p: write error: ec=%d", ctx, ctx->error_code));
           break;
         }
 
@@ -536,19 +514,20 @@ writer (void *arg)
     }
   /* Indicate that we have an error.  */
   if (!SetEvent (ctx->is_empty))
-    TRACE_ERR (ctx, GetLastError (), "SetEvent failed");
+    trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ()));
 
-  TRACE_CTX (ctx, "waiting for close");
+  trace (("%p: waiting for close", ctx));
   WaitForSingleObject (ctx->close_ev, INFINITE);
 
   if (ctx->nbytes)
-    TRACE_CTX (ctx, "still %d bytes in buffer at close time", ctx->nbytes);
+    trace (("%p: still %d bytes in buffer at close time", ctx, ctx->nbytes));
 
   CloseHandle (ctx->close_ev);
   CloseHandle (ctx->have_data);
   CloseHandle (ctx->is_empty);
   CloseHandle (ctx->thread_hd);
   DeleteCriticalSection (&ctx->mutex);
+  trace (("%p: writer is destroyed", ctx));
   _gpgrt_free (ctx);
 
   return 0;
@@ -581,7 +560,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie)
     ctx->close_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
   if (!ctx->have_data || !ctx->is_empty || !ctx->close_ev)
     {
-      TRACE_ERR (ctx, GetLastError (), "CreateEvent failed");
+      trace (("%p: CreateEvent failed: ec=%d", ctx, (int)GetLastError ()));
       if (ctx->have_data)
 	CloseHandle (ctx->have_data);
       if (ctx->is_empty)
@@ -604,7 +583,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie)
 
   if (!ctx->thread_hd)
     {
-      TRACE_ERR (ctx, GetLastError (), "CreateThread failed");
+      trace (("%p: CreateThread failed: ec=%d", ctx, (int)GetLastError ()));
       DeleteCriticalSection (&ctx->mutex);
       if (ctx->have_data)
 	CloseHandle (ctx->have_data);
@@ -632,12 +611,16 @@ create_writer (estream_cookie_w32_pollable_t pcookie)
 static void
 destroy_writer (struct writer_context_s *ctx)
 {
+  trace (("%p: enter pollable_destroy_writer", ctx));
   EnterCriticalSection (&ctx->mutex);
+  trace (("%p: setting stopme", ctx));
   ctx->stop_me = 1;
   if (ctx->have_data)
     SetEvent (ctx->have_data);
   LeaveCriticalSection (&ctx->mutex);
 
+  trace (("%p: waiting for empty", ctx));
+
   /* Give the writer a chance to flush the buffer.  */
   WaitForSingleObject (ctx->is_empty, INFINITE);
 
@@ -650,12 +633,15 @@ destroy_writer (struct writer_context_s *ctx)
   if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK,
 			NULL, 0, NULL, 0, NULL, NULL))
     {
-      TRACE_ERR (ctx, GetLastError (), "unblock control call failed");
+      trace (("%p: unblock control call failed: ec=%d",
+              ctx, (int)GetLastError ()));
     }
 #endif
 
   /* After setting this event CTX is void.  */
+  trace (("%p: set close_ev", ctx));
   SetEvent (ctx->close_ev);
+  trace (("%p: leave pollable_destroy_writer", ctx));
 }
 
 
@@ -666,12 +652,12 @@ static gpgrt_ssize_t
 func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
 {
   estream_cookie_w32_pollable_t pcookie = cookie;
-  struct writer_context_s *ctx;
+  struct writer_context_s *ctx = pcookie->writer;
 
+  trace (("%p: buffer: %p count: %d", ctx, buffer, count));
   if (count == 0)
     return 0;
 
-  ctx = pcookie->writer;
   if (ctx == NULL)
     {
       pcookie->writer = ctx = create_writer (pcookie);
@@ -680,8 +666,8 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
     }
 
   EnterCriticalSection (&ctx->mutex);
-  TRACE_CTX (ctx, "pollable write buffer: %p, count: %d, nbytes: %d",
-         buffer, count, ctx->nbytes);
+  trace (("%p: buffer: %p, count: %d, nbytes: %d",
+          ctx, buffer, count, ctx->nbytes));
   if (!ctx->error && ctx->nbytes)
     {
       /* Bytes are pending for send.  */
@@ -689,7 +675,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
       /* Reset the is_empty event.  Better safe than sorry.  */
       if (!ResetEvent (ctx->is_empty))
 	{
-	  TRACE_ERR (ctx, GetLastError (), "ResetEvent failed");
+          trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ()));
           LeaveCriticalSection (&ctx->mutex);
 	  /* FIXME: Should translate the error code.  */
 	  _gpg_err_set_errno (EIO);
@@ -699,14 +685,14 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
 
       if (pcookie->modeflags & O_NONBLOCK)
         {
-          TRACE_CTX (ctx, "would block");
+          trace (("%p: would block", ctx));
           _gpg_err_set_errno (EAGAIN);
           return -1;
         }
 
-      TRACE_CTX (ctx, "waiting for empty buffer");
+      trace (("%p: waiting for empty buffer", ctx));
       WaitForSingleObject (ctx->is_empty, INFINITE);
-      TRACE_CTX (ctx, "buffer is empty");
+      trace (("%p: buffer is empty", ctx));
       EnterCriticalSection (&ctx->mutex);
     }
 
@@ -733,7 +719,7 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
      used by the select() implementation to probe the channel.  */
   if (!ResetEvent (ctx->is_empty))
     {
-      TRACE_ERR (ctx, GetLastError (), "ResetEvent failed");
+      trace (("%p: ResetEvent failed: ec=%d", ctx, (int)GetLastError ()));
       LeaveCriticalSection (&ctx->mutex);
       /* FIXME: Should translate the error code.  */
       _gpg_err_set_errno (EIO);
@@ -741,13 +727,15 @@ func_w32_pollable_write (void *cookie, const void *buffer, size_t count)
     }
   if (!SetEvent (ctx->have_data))
     {
-      TRACE_ERR (ctx, GetLastError (), "SetEvent failed");
+      trace (("%p: SetEvent failed: ec=%d", ctx, (int)GetLastError ()));
       LeaveCriticalSection (&ctx->mutex);
       /* FIXME: Should translate the error code.  */
       _gpg_err_set_errno (EIO);
       return -1;
     }
+  trace (("%p: nwritten=%d", ctx, count));
   LeaveCriticalSection (&ctx->mutex);
+  trace (("%p: pollable write buffer - leave", ctx));
 
   return (int) count;
 }
@@ -768,7 +756,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
  restart:
 #endif
 
-  TRACE ("poll on [ ");
+  trace_start (("poll on [ "));
   any = 0;
   nwait = 0;
   count = 0;
@@ -794,7 +782,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 	  if (fds[i].want_read)
 	    {
 	      struct reader_context_s *ctx = pcookie->reader;
-              TRACE ("%d/read ", i);
+              trace_append (("%d/read ", i));
               if (ctx == NULL)
                 {
                   pcookie->reader = ctx = create_reader (pcookie);
@@ -808,7 +796,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 
               if (nwait >= DIM (waitbuf))
                 {
-                  TRACE ("oops ]: Too many objects for WFMO!\n");
+                  trace_finish (("oops ]: Too many objects for WFMO!"));
                   /* FIXME: Should translate the error code.  */
                   _gpg_err_set_errno (EIO);
                   return -1;
@@ -820,12 +808,13 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 	  else if (fds[i].want_write)
 	    {
 	      struct writer_context_s *ctx = pcookie->writer;
-              TRACE ("%d/write ", i);
+              trace_append (("%d/write ", i));
               if (ctx == NULL)
                 {
                   pcookie->writer = ctx = create_writer (pcookie);
                   if (!ctx)
                     {
+                      trace_finish (("oops ]: create writer failed"));
                       /* FIXME:  Is the error code appropriate?  */
                       _gpg_err_set_errno (EBADF);
                       return -1;
@@ -834,7 +823,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 
               if (nwait >= DIM (waitbuf))
                 {
-                  TRACE ("oops ]: Too many objects for WFMO!");
+                  trace_finish (("oops ]: Too many objects for WFMO"));
                   /* FIXME: Should translate the error code.  */
                   _gpg_err_set_errno (EIO);
                   return -1;
@@ -845,7 +834,7 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
             }
         }
     }
-  TRACE ("]\n");
+  trace_finish (("]"));
   if (!any)
     return 0;
 
@@ -878,22 +867,22 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 	}
       if (!any)
 	{
-	  TRACE ("no signaled objects found after WFMO\n");
+	  trace (("no signaled objects found after WFMO"));
 	  count = -1;
 	}
     }
   else if (code == WAIT_TIMEOUT)
-    TRACE ("WFMO timed out\n");
+    trace (("WFMO timed out"));
   else if (code == WAIT_FAILED)
     {
-      TRACE_ERR (NULL, GetLastError (), "WFMO failed");
+      trace (("WFMO failed: ec=%d", (int)GetLastError ()));
 #if 0
       if (GetLastError () == ERROR_INVALID_HANDLE)
 	{
 	  int k;
 	  int j = handle_to_fd (waitbuf[i]);
 
-	  TRACE ("WFMO invalid handle %d removed\n", j);
+	  trace (("WFMO invalid handle %d removed", j));
 	  for (k = 0 ; k < nfds; k++)
 	    {
 	      if (fds[k].fd == j)
@@ -902,28 +891,28 @@ _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout)
 		  goto restart;
                 }
             }
-	  TRACE (" oops, or not???\n");
+	  trace ((" oops, or not???"));
         }
 #endif
       count = -1;
     }
   else
     {
-      TRACE ("WFMO returned %u\n", code);
+      trace (("WFMO returned %u", code));
       count = -1;
     }
 
   if (count > 0)
     {
-      TRACE ("poll OK [ ");
+      trace_start (("poll OK [ "));
       for (i = 0; i < nfds; i++)
 	{
 	  if (fds[i].ignore)
 	    continue;
 	  if (fds[i].got_read || fds[i].got_write)
-	    TRACE ("%c%d ", fds[i].want_read ? 'r' : 'w', i);
+	    trace_append (("%c%d ", fds[i].want_read ? 'r' : 'w', i));
         }
-      TRACE ("]\n");
+      trace_finish (("]"));
     }
 
   if (count < 0)

commit a52f12cc1879d171ddf309b5ac461bab06c8b5e2
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Feb 27 00:22:26 2017 +0100

    Add a tracing framework.
    
    * src/init.c (trace_save_errno, trace_arg_module)
    (trace_arg_file, trace_arg_line): New module vars.
    (do_internal_trace): New.
    (_gpgrt_internal_trace_printf): New.
    (_gpgrt_internal_trace): New.
    (_gpgrt_internal_trace_errno): New.
    (_gpgrt_internal_trace_end): New.
    * src/gpgrt-int.h (trace): New macro.
    (trace_errno): New macro.
    (trace_start): New macro.
    (trace_append): New macro.
    (trace_finish): New macro.
    --
    
    We want to be abale to use libgpg-error also with pre-c99 compilers
    and thus we can use the __VA_ARGS__ but resort to the common macro
    trick.

diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 8a2dae7..e1cf50b 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -49,6 +49,50 @@ gpg_err_code_t _gpgrt_lock_unlock (gpgrt_lock_t *lockhd);
 gpg_err_code_t _gpgrt_lock_destroy (gpgrt_lock_t *lockhd);
 gpg_err_code_t _gpgrt_yield (void);
 
+/* Trace support.  */
+
+void _gpgrt_internal_trace_begin (const char *mod, const char *file, int line);
+void _gpgrt_internal_trace (const char *format,
+                            ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_errno (const char *format,
+                                  ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_printf (const char *format,
+                                   ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_end (void);
+
+#ifdef ENABLE_TRACING
+# define trace(X) do { \
+                       _gpgrt_internal_trace_begin \
+                           (ENABLE_TRACING, __func__, __LINE__); \
+                       _gpgrt_internal_trace X; \
+                       _gpgrt_internal_trace_end (); \
+                     } while (0)
+# define trace_errno(X) do { \
+                       _gpgrt_internal_trace_begin \
+                           (ENABLE_TRACING, __func__, __LINE__); \
+                       _gpgrt_internal_trace_errno X; \
+                       _gpgrt_internal_trace_end (); \
+                     } while (0)
+# define trace_start(X) do { \
+                       _gpgrt_internal_trace_begin \
+                           (ENABLE_TRACING, __func__, __LINE__); \
+                       _gpgrt_internal_trace_printf X; \
+                     } while (0)
+# define trace_append(X) do { \
+                       _gpgrt_internal_trace_printf X; \
+                     } while (0)
+# define trace_finish(X) do { \
+                       _gpgrt_internal_trace_printf X; \
+                       _gpgrt_internal_trace_end (); \
+                     } while (0)
+#else
+# define trace(X) do { } while (0)
+# define trace_errno(X) do { } while (0)
+# define trace_start(X) do { } while (0)
+# define trace_append(X) do { } while (0)
+# define trace_finish(X) do { } while (0)
+#endif /*!ENABLE_TRACING*/
+
 
 /* Local definitions for estream.  */
 
diff --git a/src/init.c b/src/init.c
index f7207fe..e90bec5 100644
--- a/src/init.c
+++ b/src/init.c
@@ -214,6 +214,83 @@ _gpg_err_set_errno (int err)
 
 
 

+/* Internal tracing functions.  We use flockfile and funlockfile to
+ * protect their use. */
+static int trace_save_errno;
+static const char *trace_arg_module;
+static const char *trace_arg_file;
+static int trace_arg_line;
+
+void
+_gpgrt_internal_trace_begin (const char *module, const char *file, int line)
+{
+  int save_errno = errno;
+#ifdef HAVE_FLOCKFILE
+  flockfile (stderr);
+#endif
+  trace_save_errno = save_errno;
+  trace_arg_module = module;
+  trace_arg_file = file;
+  trace_arg_line = line;
+}
+
+
+static void
+do_internal_trace (const char *format, va_list arg_ptr, int with_errno)
+{
+  fprintf (stderr, "%s:%s:%d: ",
+           trace_arg_module, trace_arg_file, trace_arg_line);
+  vfprintf (stderr, format, arg_ptr);
+  if (with_errno)
+    fprintf (stderr, " errno=%s", strerror (trace_save_errno));
+  fputc ('\n', stderr);
+}
+
+void
+_gpgrt_internal_trace_printf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format) ;
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format) ;
+  do_internal_trace (format, arg_ptr, 0);
+  va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace_errno (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format) ;
+  do_internal_trace (format, arg_ptr, 1);
+  va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace_end (void)
+{
+  int save_errno = trace_save_errno;
+#ifdef HAVE_FLOCKFILE
+  funlockfile (stderr);
+#endif
+  errno = save_errno;
+}
+
+
+

 #ifdef HAVE_W32_SYSTEM
 /*****************************************
  ******** Below is only Windows code. ****

commit be49b02a56e8b405eeb0c07c80eb24e71e841b4a
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Feb 26 18:47:21 2017 +0100

    Rename internal functions of estream.
    
    * src/estream.c (_gpgrt_es_init): Rename to _gpgrt_estream_init.
    (es_fill): Rename to fill_stream.
    (es_fflush): Rename to flush_stream.
    (es_deinitialize): Rename to deinit_stream_obj.
    (es_create): Rename to create_stream
    (es_read_nbf): Rename to do_read_nbf.
    (es_read_lbf): Rename to do_read_lbf.
    (es_read_fbf): Rename to do_read_fbf.
    (es_peek): Rename to peek_stream.
    (es_skip): Rename to skip_stream.
    (es_print): Rename to do_print_stream.
    
    --
    
    The use of the "es_" was confusing.  Avoid that.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/estream.c b/src/estream.c
index db9de01..f3d2269 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -503,7 +503,7 @@ do_deinit (void)
  * Initialization of the estream module.
  */
 int
-_gpgrt_es_init (void)
+_gpgrt_estream_init (void)
 {
   static int initialized;
 
@@ -1825,7 +1825,7 @@ parse_mode (const char *modestr,
  */
 
 static int
-es_fill (estream_t stream)
+fill_stream (estream_t stream)
 {
   size_t bytes_read = 0;
   int err;
@@ -1880,7 +1880,7 @@ es_fill (estream_t stream)
 }
 
 static int
-es_flush (estream_t stream)
+flush_stream (estream_t stream)
 {
   gpgrt_cookie_write_function_t func_write = stream->intern->func_write;
   int err;
@@ -2022,10 +2022,11 @@ init_stream_obj (estream_t stream,
 
 
 /*
- * Deinitialize STREAM.
+ * Deinitialize the STREAM object.  This does _not_ free the memory,
+ * destroys the lock, or closes the underlying descriptor.
  */
 static int
-es_deinitialize (estream_t stream)
+deinit_stream_obj (estream_t stream)
 {
   gpgrt_cookie_close_function_t func_close;
   int err, tmp_err;
@@ -2035,7 +2036,7 @@ es_deinitialize (estream_t stream)
   err = 0;
   if (stream->flags.writing)
     {
-      tmp_err = es_flush (stream);
+      tmp_err = flush_stream (stream);
       if (!err)
         err = tmp_err;
     }
@@ -2061,13 +2062,15 @@ es_deinitialize (estream_t stream)
 
 
 /*
- * Create a new stream object and initialize it.
+ * Create a new stream and initialize it.  On success the new stream
+ * handle is tsored at R_STREAM.  On failure NULL is stored at
+ * R_STREAM.
  */
 static int
-es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
-           gpgrt_stream_backend_kind_t kind,
-	   struct cookie_io_functions_s functions, unsigned int modeflags,
-           unsigned int xmode, int with_locked_list)
+create_stream (estream_t *r_stream, void *cookie, es_syshd_t *syshd,
+               gpgrt_stream_backend_kind_t kind,
+               struct cookie_io_functions_s functions, unsigned int modeflags,
+               unsigned int xmode, int with_locked_list)
 {
   estream_internal_t stream_internal_new;
   estream_t stream_new;
@@ -2134,7 +2137,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
   if (err)
     goto out;
 
-  *stream = stream_new;
+  *r_stream = stream_new;
 
  out:
 
@@ -2142,7 +2145,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
     {
       if (stream_new)
 	{
-	  es_deinitialize (stream_new);
+	  deinit_stream_obj (stream_new);
           destroy_stream_lock (stream_new);
 	  mem_free (stream_new->intern);
 	  mem_free (stream_new);
@@ -2174,7 +2177,7 @@ do_close (estream_t stream, int with_locked_list)
           mem_free (stream->intern->onclose);
           stream->intern->onclose = tmp;
         }
-      err = es_deinitialize (stream);
+      err = deinit_stream_obj (stream);
       destroy_stream_lock (stream);
       mem_free (stream->intern);
       mem_free (stream);
@@ -2221,7 +2224,7 @@ do_onclose (estream_t stream, int mode,
  * unbuffered-mode, storing the amount of bytes read at BYTES_READ.
  */
 static int
-es_read_nbf (estream_t _GPGRT__RESTRICT stream,
+do_read_nbf (estream_t _GPGRT__RESTRICT stream,
 	     unsigned char *_GPGRT__RESTRICT buffer,
 	     size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read)
 {
@@ -2280,7 +2283,7 @@ check_pending_nbf (estream_t _GPGRT__RESTRICT stream)
  * BYTES_READ.
  */
 static int
-es_read_fbf (estream_t _GPGRT__RESTRICT stream,
+do_read_fbf (estream_t _GPGRT__RESTRICT stream,
 	     unsigned char *_GPGRT__RESTRICT buffer,
 	     size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read)
 {
@@ -2298,7 +2301,7 @@ es_read_fbf (estream_t _GPGRT__RESTRICT stream,
 	{
 	  /* Nothing more to read in current container, try to
 	     fill container with new data.  */
-	  err = es_fill (stream);
+	  err = fill_stream (stream);
 	  if (! err)
 	    if (! stream->data_len)
 	      /* Filling did not result in any data read.  */
@@ -2354,13 +2357,13 @@ check_pending_fbf (estream_t _GPGRT__RESTRICT stream)
  * line-buffered-mode, storing the amount of bytes read at BYTES_READ.
  */
 static int
-es_read_lbf (estream_t _GPGRT__RESTRICT stream,
+do_read_lbf (estream_t _GPGRT__RESTRICT stream,
 	     unsigned char *_GPGRT__RESTRICT buffer,
 	     size_t bytes_to_read, size_t *_GPGRT__RESTRICT bytes_read)
 {
   int err;
 
-  err = es_read_fbf (stream, buffer, bytes_to_read, bytes_read);
+  err = do_read_fbf (stream, buffer, bytes_to_read, bytes_read);
 
   return err;
 }
@@ -2386,7 +2389,7 @@ es_readn (estream_t _GPGRT__RESTRICT stream,
   if (stream->flags.writing)
     {
       /* Switching to reading mode -> flush output.  */
-      err = es_flush (stream);
+      err = flush_stream (stream);
       if (err)
 	goto out;
       stream->flags.writing = 0;
@@ -2404,17 +2407,17 @@ es_readn (estream_t _GPGRT__RESTRICT stream,
   switch (stream->intern->strategy)
     {
     case _IONBF:
-      err = es_read_nbf (stream,
+      err = do_read_nbf (stream,
 			 buffer + data_read_unread,
 			 bytes_to_read - data_read_unread, &data_read);
       break;
     case _IOLBF:
-      err = es_read_lbf (stream,
+      err = do_read_lbf (stream,
 			 buffer + data_read_unread,
 			 bytes_to_read - data_read_unread, &data_read);
       break;
     case _IOFBF:
-      err = es_read_fbf (stream,
+      err = do_read_fbf (stream,
 			 buffer + data_read_unread,
 			 bytes_to_read - data_read_unread, &data_read);
       break;
@@ -2441,7 +2444,7 @@ check_pending (estream_t _GPGRT__RESTRICT stream)
   if (stream->flags.writing)
     {
       /* Switching to reading mode -> flush output.  */
-      if (es_flush (stream))
+      if (flush_stream (stream))
 	return 0; /* Better return 0 on error.  */
       stream->flags.writing = 0;
     }
@@ -2515,7 +2518,7 @@ es_seek (estream_t _GPGRT__RESTRICT stream, gpgrt_off_t offset, int whence,
     {
       /* Flush data first in order to prevent flushing it to the wrong
 	 offset.  */
-      err = es_flush (stream);
+      err = flush_stream (stream);
       if (err)
 	goto out;
       stream->flags.writing = 0;
@@ -2635,7 +2638,7 @@ es_write_fbf (estream_t _GPGRT__RESTRICT stream,
     {
       if (stream->data_offset == stream->buffer_size)
 	/* Container full, flush buffer.  */
-	err = es_flush (stream);
+	err = flush_stream (stream);
 
       if (! err)
 	{
@@ -2677,7 +2680,7 @@ es_write_lbf (estream_t _GPGRT__RESTRICT stream,
     {
       /* Found a newline, directly write up to (including) this
 	 character.  */
-      err = es_flush (stream);
+      err = flush_stream (stream);
       if (!err)
 	err = es_write_nbf (stream, buffer, nlp - buffer + 1, &data_flushed);
     }
@@ -2751,16 +2754,16 @@ es_writen (estream_t _GPGRT__RESTRICT stream,
 
 
 static int
-es_peek (estream_t _GPGRT__RESTRICT stream,
-         unsigned char **_GPGRT__RESTRICT data,
-	 size_t *_GPGRT__RESTRICT data_len)
+peek_stream (estream_t _GPGRT__RESTRICT stream,
+             unsigned char **_GPGRT__RESTRICT data,
+             size_t *_GPGRT__RESTRICT data_len)
 {
   int err;
 
   if (stream->flags.writing)
     {
       /* Switching to reading mode -> flush output.  */
-      err = es_flush (stream);
+      err = flush_stream (stream);
       if (err)
 	goto out;
       stream->flags.writing = 0;
@@ -2769,7 +2772,7 @@ es_peek (estream_t _GPGRT__RESTRICT stream,
   if (stream->data_offset == stream->data_len)
     {
       /* Refill container.  */
-      err = es_fill (stream);
+      err = fill_stream (stream);
       if (err)
 	goto out;
     }
@@ -2788,7 +2791,7 @@ es_peek (estream_t _GPGRT__RESTRICT stream,
 
 /* Skip SIZE bytes of input data contained in buffer.  */
 static int
-es_skip (estream_t stream, size_t size)
+skip_stream (estream_t stream, size_t size)
 {
   int err;
 
@@ -2835,8 +2838,9 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length,
     goto out;
 
   memset (&syshd, 0, sizeof syshd);
-  err = es_create (&line_stream, line_stream_cookie, &syshd, BACKEND_MEM,
-		   estream_functions_mem, O_RDWR, 1, 0);
+  err = create_stream (&line_stream, line_stream_cookie,
+                       &syshd, BACKEND_MEM,
+                       estream_functions_mem, O_RDWR, 1, 0);
   if (err)
     goto out;
 
@@ -2849,7 +2853,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length,
         if (max_length && (space_left == 1))
           break;
 
-        err = es_peek (stream, &data, &data_len);
+        err = peek_stream (stream, &data, &data_len);
         if (err || (! data_len))
           break;
 
@@ -2865,7 +2869,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length,
               {
                 /* Not needed: space_left -= data_len */
                 line_size += data_len;
-                es_skip (stream, data_len);
+                skip_stream (stream, data_len);
                 break; /* endless loop */
               }
           }
@@ -2876,7 +2880,7 @@ doreadline (estream_t _GPGRT__RESTRICT stream, size_t max_length,
               {
                 space_left -= data_len;
                 line_size += data_len;
-                es_skip (stream, data_len);
+                skip_stream (stream, data_len);
               }
           }
         if (err)
@@ -2956,8 +2960,8 @@ print_writer (void *outfncarg, const char *buf, size_t buflen)
 
 /* The core of our printf function.  This is called in locked state. */
 static int
-es_print (estream_t _GPGRT__RESTRICT stream,
-	  const char *_GPGRT__RESTRICT format, va_list ap)
+do_print_stream (estream_t _GPGRT__RESTRICT stream,
+                 const char *_GPGRT__RESTRICT format, va_list ap)
 {
   int rc;
 
@@ -2978,7 +2982,7 @@ es_set_buffering (estream_t _GPGRT__RESTRICT stream,
   /* Flush or empty buffer depending on mode.  */
   if (stream->flags.writing)
     {
-      err = es_flush (stream);
+      err = flush_stream (stream);
       if (err)
 	goto out;
     }
@@ -3086,8 +3090,8 @@ _gpgrt_fopen (const char *_GPGRT__RESTRICT path,
   syshd.type = ES_SYSHD_FD;
   syshd.u.fd = fd;
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_FD,
-                   estream_functions_fd, modeflags, xmode, 0);
+  err = create_stream (&stream, cookie, &syshd, BACKEND_FD,
+                       estream_functions_fd, modeflags, xmode, 0);
   if (err)
     goto out;
 
@@ -3143,8 +3147,8 @@ _gpgrt_mopen (void *_GPGRT__RESTRICT data, size_t data_n, size_t data_len,
 
   memset (&syshd, 0, sizeof syshd);
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_MEM,
-                   estream_functions_mem, modeflags, xmode, 0);
+  err = create_stream (&stream, cookie, &syshd, BACKEND_MEM,
+                       estream_functions_mem, modeflags, xmode, 0);
 
  out:
 
@@ -3177,8 +3181,8 @@ _gpgrt_fopenmem (size_t memlimit, const char *_GPGRT__RESTRICT mode)
     return NULL;
 
   memset (&syshd, 0, sizeof syshd);
-  if (es_create (&stream, cookie, &syshd, BACKEND_MEM,
-                 estream_functions_mem, modeflags, xmode, 0))
+  if (create_stream (&stream, cookie, &syshd, BACKEND_MEM,
+                     estream_functions_mem, modeflags, xmode, 0))
     (*estream_functions_mem.public.func_close) (cookie);
 
   return stream;
@@ -3239,8 +3243,8 @@ _gpgrt_fopencookie (void *_GPGRT__RESTRICT cookie,
     goto out;
 
   memset (&syshd, 0, sizeof syshd);
-  err = es_create (&stream, cookie, &syshd, BACKEND_USER, io_functions,
-                   modeflags, xmode, 0);
+  err = create_stream (&stream, cookie, &syshd, BACKEND_USER, io_functions,
+                       modeflags, xmode, 0);
   if (err)
     goto out;
 
@@ -3253,17 +3257,13 @@ _gpgrt_fopencookie (void *_GPGRT__RESTRICT cookie,
 static estream_t
 do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list)
 {
+  int create_called = 0;
+  estream_t stream = NULL;
+  void *cookie = NULL;
   unsigned int modeflags, xmode;
-  int create_called;
-  estream_t stream;
-  void *cookie;
   int err;
   es_syshd_t syshd;
 
-  stream = NULL;
-  cookie = NULL;
-  create_called = 0;
-
   err = parse_mode (mode, &modeflags, &xmode, NULL);
   if (err)
     goto out;
@@ -3282,8 +3282,9 @@ do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list)
   syshd.type = ES_SYSHD_FD;
   syshd.u.fd = filedes;
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_FD, estream_functions_fd,
-                   modeflags, xmode, with_locked_list);
+  err = create_stream (&stream, cookie, &syshd,
+                       BACKEND_FD, estream_functions_fd,
+                       modeflags, xmode, with_locked_list);
 
   if (!err && stream)
     {
@@ -3318,16 +3319,12 @@ static estream_t
 do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list)
 {
   unsigned int modeflags, cmode, xmode;
-  int create_called;
-  estream_t stream;
-  void *cookie;
+  int create_called = 0;
+  estream_t stream = NULL;
+  void *cookie = NULL;
   int err;
   es_syshd_t syshd;
 
-  stream = NULL;
-  cookie = NULL;
-  create_called = 0;
-
   err = parse_mode (mode, &modeflags, &xmode, &cmode);
   if (err)
     goto out;
@@ -3348,11 +3345,11 @@ do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list)
   syshd.type = ES_SYSHD_FD;
   syshd.u.fd = fp? fileno (fp): -1;
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_FP, estream_functions_fp,
-                   modeflags, xmode, with_locked_list);
+  err = create_stream (&stream, cookie, &syshd,
+                       BACKEND_FP, estream_functions_fp,
+                       modeflags, xmode, with_locked_list);
 
  out:
-
   if (err && create_called)
     (*estream_functions_fp.public.func_close) (cookie);
 
@@ -3412,8 +3409,9 @@ do_w32open (HANDLE hd, const char *mode,
   syshd.type = ES_SYSHD_HANDLE;
   syshd.u.handle = hd;
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_W32,
-                   estream_functions_w32, modeflags, xmode, with_locked_list);
+  err = create_stream (&stream, cookie, &syshd,
+                       BACKEND_W32, estream_functions_w32,
+                       modeflags, xmode, with_locked_list);
 
  leave:
   if (err && create_called)
@@ -3554,7 +3552,9 @@ _gpgrt__get_std_stream (int fd)
 }
 
 /* Note: A "samethread" keyword given in "mode" is ignored and the
-   value used by STREAM is used instead. */
+ * value used by STREAM is used instead.  Note that this function is
+ * the reasons why some of the init and deinit code is split up into
+ * several functions.  */
 estream_t
 _gpgrt_freopen (const char *_GPGRT__RESTRICT path,
                 const char *_GPGRT__RESTRICT mode,
@@ -3577,7 +3577,7 @@ _gpgrt_freopen (const char *_GPGRT__RESTRICT path,
 
       lock_stream (stream);
 
-      es_deinitialize (stream);
+      deinit_stream_obj (stream);
 
       err = parse_mode (mode, &modeflags, &dummy, &cmode);
       if (err)
@@ -3615,7 +3615,7 @@ _gpgrt_freopen (const char *_GPGRT__RESTRICT path,
     {
       /* FIXME?  We don't support re-opening at the moment.  */
       _set_errno (EINVAL);
-      es_deinitialize (stream);
+      deinit_stream_obj (stream);
       do_close (stream, 0);
       stream = NULL;
     }
@@ -3668,7 +3668,7 @@ _gpgrt_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen)
 
       if (stream->flags.writing)
         {
-          err = es_flush (stream);
+          err = flush_stream (stream);
           if (err)
             goto leave;
           stream->flags.writing = 0;
@@ -3909,7 +3909,7 @@ do_fflush (estream_t stream)
   int err;
 
   if (stream->flags.writing)
-    err = es_flush (stream);
+    err = flush_stream (stream);
   else
     {
       es_empty (stream);
@@ -4403,7 +4403,7 @@ _gpgrt_vfprintf_unlocked (estream_t _GPGRT__RESTRICT stream,
                           const char *_GPGRT__RESTRICT format,
                           va_list ap)
 {
-  return es_print (stream, format, ap);
+  return do_print_stream (stream, format, ap);
 }
 
 
@@ -4415,7 +4415,7 @@ _gpgrt_vfprintf (estream_t _GPGRT__RESTRICT stream,
   int ret;
 
   lock_stream (stream);
-  ret = es_print (stream, format, ap);
+  ret = do_print_stream (stream, format, ap);
   unlock_stream (stream);
 
   return ret;
@@ -4430,7 +4430,7 @@ _gpgrt_fprintf_unlocked (estream_t _GPGRT__RESTRICT stream,
 
   va_list ap;
   va_start (ap, format);
-  ret = es_print (stream, format, ap);
+  ret = do_print_stream (stream, format, ap);
   va_end (ap);
 
   return ret;
@@ -4446,7 +4446,7 @@ _gpgrt_fprintf (estream_t _GPGRT__RESTRICT stream,
   va_list ap;
   va_start (ap, format);
   lock_stream (stream);
-  ret = es_print (stream, format, ap);
+  ret = do_print_stream (stream, format, ap);
   unlock_stream (stream);
   va_end (ap);
 
@@ -4559,17 +4559,14 @@ estream_t
 _gpgrt_tmpfile (void)
 {
   unsigned int modeflags;
-  int create_called;
-  estream_t stream;
-  void *cookie;
+  int create_called = 0;
+  estream_t stream = NULL;
+  void *cookie = NULL;
   int err;
   int fd;
   es_syshd_t syshd;
 
-  create_called = 0;
-  stream = NULL;
   modeflags = O_RDWR | O_TRUNC | O_CREAT;
-  cookie = NULL;
 
   fd = tmpfd ();
   if (fd == -1)
@@ -4585,8 +4582,9 @@ _gpgrt_tmpfile (void)
   syshd.type = ES_SYSHD_FD;
   syshd.u.fd = fd;
   create_called = 1;
-  err = es_create (&stream, cookie, &syshd, BACKEND_FD, estream_functions_fd,
-                   modeflags, 0, 0);
+  err = create_stream (&stream, cookie, &syshd,
+                       BACKEND_FD, estream_functions_fd,
+                       modeflags, 0, 0);
 
  out:
   if (err)
@@ -4790,7 +4788,8 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
     return count;  /* Early return without waiting.  */
 
   /* Now do the real select.  */
-#ifdef _WIN32
+#ifdef HAVE_W32_SYSTEM
+
   if (pre_syscall_func)
     pre_syscall_func ();
 
@@ -4798,7 +4797,9 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
 
   if (post_syscall_func)
     post_syscall_func ();
-#else
+
+#else /*!HAVE_W32_SYSTEM*/
+
   any_readfd = any_writefd = any_exceptfd = 0;
   max_fd = 0;
   for (item = fds, idx = 0; idx < nfds; item++, idx++)
@@ -4905,7 +4906,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout)
       if (any)
         count++;
     }
-#endif
+#endif /*!HAVE_W32_SYSTEM*/
 
   return count;
 }
diff --git a/src/estream.h b/src/estream.h
index 91f2bc0..2f2b11e 100644
--- a/src/estream.h
+++ b/src/estream.h
@@ -23,7 +23,7 @@
 #include "gpg-error.h"
 
 /* Local prototypes for estream.  */
-int _gpgrt_es_init (void);
+int _gpgrt_estream_init (void);
 
 
 
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index d624e84..8a2dae7 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -147,7 +147,7 @@ typedef struct _gpgrt_stream_internal *estream_internal_t;
 
 
 /* Local prototypes for estream.  */
-int _gpgrt_es_init (void);
+int _gpgrt_estream_init (void);
 void _gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void));
 void _gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void));
 
diff --git a/src/init.c b/src/init.c
index 8de54b6..f7207fe 100644
--- a/src/init.c
+++ b/src/init.c
@@ -80,7 +80,7 @@ real_init (void)
       drop_locale_dir (locale_dir);
     }
 #endif
-  _gpgrt_es_init ();
+  _gpgrt_estream_init ();
 }
 
 /* Initialize the library.  This function should be run early.  */

commit 915e1bf2ad1b23239b17843755376344e59a3110
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Feb 24 12:17:15 2017 +0100

    w32: Do not use the syscall clamps in pollable mode.
    
    * src/estream.c (estream_cookie_w32): Add flag no_syscall_clamp.
    (func_w32_create): Add arg no_syscall_clamp.
    (func_w32_read): Do not call pre/post_syscall_clamp when flag is set.
    (func_w32_write): Ditto.
    (func_w32_seek): Ditto.
    (do_w32open): Set NO_SYSCALL_CLAMP in pollable mode.
    (es_create) [W32]: Make sure that pollable-mode is unly used with the
    W32 backend.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/estream.c b/src/estream.c
index 045182b..db9de01 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -1127,6 +1127,7 @@ typedef struct estream_cookie_w32
 {
   HANDLE hd;     /* The handle we are using for actual output.  */
   int no_close;  /* If set we won't close the handle.  */
+  int no_syscall_clamp; /* Do not use the syscall clamp. */
 } *estream_cookie_w32_t;
 
 
@@ -1135,7 +1136,7 @@ typedef struct estream_cookie_w32
  */
 static int
 func_w32_create (void **cookie, HANDLE hd,
-                    unsigned int modeflags, int no_close)
+                 unsigned int modeflags, int no_close, int no_syscall_clamp)
 {
   estream_cookie_w32_t w32_cookie;
   int err;
@@ -1152,6 +1153,7 @@ func_w32_create (void **cookie, HANDLE hd,
 
       w32_cookie->hd = hd;
       w32_cookie->no_close = no_close;
+      w32_cookie->no_syscall_clamp = no_syscall_clamp;
       *cookie = w32_cookie;
       err = 0;
     }
@@ -1161,6 +1163,9 @@ func_w32_create (void **cookie, HANDLE hd,
 
 /*
  * Read function for W32 handle objects.
+ *
+ * Note that this function may also be used by the reader thread of
+ * w32-stream.  In that case the NO_SYSCALL_CLAMP is set.
  */
 static gpgrt_ssize_t
 func_w32_read (void *cookie, void *buffer, size_t size)
@@ -1177,7 +1182,7 @@ func_w32_read (void *cookie, void *buffer, size_t size)
     }
   else
     {
-      if (pre_syscall_func)
+      if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
         pre_syscall_func ();
       do
         {
@@ -1198,7 +1203,7 @@ func_w32_read (void *cookie, void *buffer, size_t size)
             bytes_read = (int)nread;
         }
       while (bytes_read == -1 && errno == EINTR);
-      if (post_syscall_func)
+      if (post_syscall_func && !w32_cookie->no_syscall_clamp)
         post_syscall_func ();
     }
 
@@ -1208,6 +1213,9 @@ func_w32_read (void *cookie, void *buffer, size_t size)
 
 /*
  * Write function for W32 handle objects.
+ *
+ * Note that this function may also be used by the writer thread of
+ * w32-stream.  In that case the NO_SYSCALL_CLAMP is set.
  */
 static gpgrt_ssize_t
 func_w32_write (void *cookie, const void *buffer, size_t size)
@@ -1222,7 +1230,7 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
     }
   else if (buffer)
     {
-      if (pre_syscall_func)
+      if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
         pre_syscall_func ();
       do
         {
@@ -1237,7 +1245,7 @@ func_w32_write (void *cookie, const void *buffer, size_t size)
 	    bytes_written = (int)nwritten;
         }
       while (bytes_written == -1 && errno == EINTR);
-      if (post_syscall_func)
+      if (post_syscall_func && !w32_cookie->no_syscall_clamp)
         post_syscall_func ();
     }
   else
@@ -1286,7 +1294,7 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence)
 #ifdef HAVE_W32CE_SYSTEM
 # warning need to use SetFilePointer
 #else
-  if (pre_syscall_func)
+  if (pre_syscall_func && !w32_cookie->no_syscall_clamp)
     pre_syscall_func ();
   if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method))
     {
@@ -1295,7 +1303,7 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence)
         post_syscall_func ();
       return -1;
     }
-  if (post_syscall_func)
+  if (post_syscall_func && !w32_cookie->no_syscall_clamp)
     post_syscall_func ();
 #endif
   /* Note that gpgrt_off_t is always 64 bit.  */
@@ -1661,6 +1669,7 @@ func_file_create (void **cookie, int *filedes,
  *    The object is opened in sysmode.  On POSIX this is a NOP but
  *    under Windows the direct W32 API functions (HANDLE) are used
  *    instead of their libc counterparts (fd).
+ *    FIXME: The functionality is not yet implemented.
  *
  * pollable
  *
@@ -2067,6 +2076,19 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
   stream_new = NULL;
   stream_internal_new = NULL;
 
+#if HAVE_W32_SYSTEM
+  if ((xmode & X_POLLABLE) && kind != BACKEND_W32)
+    {
+      /* We require the W32 backend, because only that allows us to
+       * write directly using the native W32 API and to disable the
+       * system clamp.  Note that func_w32_create has already been
+       * called with the flag to disable the system call clamp.  */
+      _set_errno (EINVAL);
+      err = -1;
+      goto out;
+    }
+#endif /*HAVE_W32_SYSTEM*/
+
   stream_new = mem_alloc (sizeof (*stream_new));
   if (! stream_new)
     {
@@ -2087,7 +2109,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
   stream_new->unread_buffer_size = sizeof (stream_internal_new->unread_buffer);
   stream_new->intern = stream_internal_new;
 
-#if _WIN32
+#if HAVE_W32_SYSTEM
   if ((xmode & X_POLLABLE))
     {
       void *new_cookie;
@@ -2102,7 +2124,7 @@ es_create (estream_t *stream, void *cookie, es_syshd_t *syshd,
       kind = BACKEND_W32_POLLABLE;
       functions = _gpgrt_functions_w32_pollable;
     }
-#endif
+#endif /*HAVE_W32_SYSTEM*/
 
   init_stream_obj (stream_new, cookie, syshd, kind, functions, modeflags,
                    xmode);
@@ -3379,7 +3401,11 @@ do_w32open (HANDLE hd, const char *mode,
   if (err)
     goto leave;
 
-  err = func_w32_create (&cookie, hd, modeflags, no_close);
+  /* If we are pollable we create the function cookie with syscall
+   * clamp disabled.  This is because functions are called from
+   * separatre reader and writer threads in w32-stream.  */
+  err = func_w32_create (&cookie, hd, modeflags,
+                         no_close, !!(xmode & X_POLLABLE));
   if (err)
     goto leave;
 

-----------------------------------------------------------------------

Summary of changes:
 src/estream.c     | 312 +++++++++++++++++++++++++++++++++++-------------------
 src/estream.h     |   2 +-
 src/gpgrt-int.h   |  46 +++++++-
 src/init.c        |  79 +++++++++++++-
 src/w32-estream.c | 177 +++++++++++++++----------------
 5 files changed, 410 insertions(+), 206 deletions(-)


hooks/post-receive
-- 
Error codes used by GnuPG et al.
http://git.gnupg.org




More information about the Gnupg-commits mailing list