[svn] w32pth - r15 - trunk

svn author marcus cvs at cvs.gnupg.org
Tue Feb 12 01:53:40 CET 2008


Author: marcus
Date: 2008-02-12 01:53:38 +0100 (Tue, 12 Feb 2008)
New Revision: 15

Added:
   trunk/debug.h
   trunk/w32-io.c
   trunk/w32-io.h
Modified:
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/NEWS
   trunk/libw32pth.def
   trunk/pth.h
   trunk/w32-pth.c
Log:
2008-02-12  Marcus Brinkmann  <marcus at g10code.de>

	* Makefile.am (libw32pth_la_SOURCES): Add debug.h, w32-io.h and
	w32-io.c.
	* libw32pth.def: Add pth_pipe, pth_close.
	* pth.h (pth_pipe, pth_close): New prototypes.
	* debug.h, w32-io.h, w32-io.c: New files.
	* w32-pth.c: Include "debug.h" and "w32-io.h".
	(debug_level, dbgfp): Make non-static.
	(DBG_ERROR, DBG_INFO, DBG_CALLS): Moved to debug.h.
	(fd_is_socket): New function.
	(pth_init): Call _pth_sema_subsystem_init.
	(do_pth_read): New function, supports pipes.
	(pth_read_ev): Implement it.
	(pth_read): Use do_pth_read.
	(do_pth_write): New function, supports pipes.
	(pth_write_ev): Implement it.
	(pth_write): Use do_pth_write.
	(do_pth_wait): Support pipes.  Use actual events waited upon when
	gathering the results.  Use R instead of EV in build_fdarray
	invocation.  Do not reset the event for pipes.  Add lengthy note
	about remaining issues.
	(do_pth_event_body): Fix type in va_arg invocation.


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/ChangeLog	2008-02-12 00:53:38 UTC (rev 15)
@@ -1,3 +1,27 @@
+2008-02-12  Marcus Brinkmann  <marcus at g10code.de>
+
+	* Makefile.am (libw32pth_la_SOURCES): Add debug.h, w32-io.h and
+	w32-io.c.
+	* libw32pth.def: Add pth_pipe, pth_close.
+	* pth.h (pth_pipe, pth_close): New prototypes.
+	* debug.h, w32-io.h, w32-io.c: New files.
+	* w32-pth.c: Include "debug.h" and "w32-io.h".
+	(debug_level, dbgfp): Make non-static.
+	(DBG_ERROR, DBG_INFO, DBG_CALLS): Moved to debug.h.
+	(fd_is_socket): New function.
+	(pth_init): Call _pth_sema_subsystem_init.
+	(do_pth_read): New function, supports pipes.
+	(pth_read_ev): Implement it.
+	(pth_read): Use do_pth_read.
+	(do_pth_write): New function, supports pipes.
+	(pth_write_ev): Implement it.
+	(pth_write): Use do_pth_write.
+	(do_pth_wait): Support pipes.  Use actual events waited upon when
+	gathering the results.  Use R instead of EV in build_fdarray
+	invocation.  Do not reset the event for pipes.  Add lengthy note
+	about remaining issues.
+	(do_pth_event_body): Fix type in va_arg invocation.
+
 2007-08-16  Werner Koch  <wk at g10code.com>
 
 	Released 2.0.1.

Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/Makefile.am	2008-02-12 00:53:38 UTC (rev 15)
@@ -1,5 +1,5 @@
 # Makefile.am -  Makefile for W32PTH
-#     	Copyright (C) 2007 g10 Code GmbH
+# Copyright (C) 2007, 2008 g10 Code GmbH
 # 
 # This file is part of W32PTH.
 # 
@@ -54,7 +54,7 @@
       @W32PTH_LT_CURRENT@:@W32PTH_LT_REVISION@:@W32PTH_LT_AGE@
 libw32pth_la_DEPENDENCIES = $(w32pth_deps)
 libw32pth_la_LIBADD = @LTLIBOBJS@ -lws2_32
-libw32pth_la_SOURCES = w32-pth.c pth.h
+libw32pth_la_SOURCES = pth.h debug.h w32-pth.c w32-io.h w32-io.c
 
 
 install-data-local: install-def-file

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/NEWS	2008-02-12 00:53:38 UTC (rev 15)
@@ -1,7 +1,10 @@
 Noteworthy changes in version 2.0.2
 ------------------------------------------------
 
+ * Support pipes created with pth_pipe and closed with pth_close.
 
+ * Bug fixes.
+
 Noteworthy changes in version 2.0.1 (2007-08-16)
 ------------------------------------------------
 

Added: trunk/debug.h
===================================================================
--- trunk/debug.h	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/debug.h	2008-02-12 00:53:38 UTC (rev 15)
@@ -0,0 +1,194 @@
+/* debug.h - interface to debugging functions
+   Copyright (C) 2002, 2004, 2005, 2007, 2008 g10 Code GmbH
+ 
+   This file is part of PTH.
+
+   PTH is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   PTH is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <string.h>
+
+
+/* Keeps the current debug level. Define marcos to test them. */
+extern int debug_level;
+extern FILE *dbgfp;
+#define DBG_ERROR  (debug_level >= 1)
+#define DBG_INFO   (debug_level >= 2)
+#define DBG_CALLS  (debug_level >= 3)
+
+
+/* Indirect stringification, requires __STDC__ to work.  */
+#define STRINGIFY(v) #v
+#define XSTRINGIFY(v) STRINGIFY(v)
+
+/* Log the formatted string FORMAT at debug level LEVEL or higher.  */
+void _pth_debug (int level, const char *format, ...);
+
+
+/* Trace support.  */
+
+/* FIXME: For now.  */
+#define _pth_debug_trace() 1
+
+#define _TRACE(lvl, name, tag)					\
+  int _pth_trace_level = lvl;					\
+  const char *const _pth_trace_func = name;			\
+  const char *const _pth_trace_tagname = STRINGIFY (tag);	\
+  void *_pth_trace_tag = (void *) tag
+
+#define TRACE_BEG(lvl, name, tag)			   \
+  _TRACE (lvl, name, tag);				   \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter\n", \
+		_pth_trace_func, _pth_trace_tagname,   \
+		_pth_trace_tag), 0
+#define TRACE_BEG0(lvl, name, tag, fmt)					\
+  _TRACE (lvl, name, tag);						\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag), 0
+#define TRACE_BEG1(lvl, name, tag, fmt, arg1)				\
+  _TRACE (lvl, name, tag);						\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag, arg1), 0
+#define TRACE_BEG2(lvl, name, tag, fmt, arg1, arg2)		    \
+  _TRACE (lvl, name, tag);					    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2), 0
+#define TRACE_BEG3(lvl, name, tag, fmt, arg1, arg2, arg3)	    \
+  _TRACE (lvl, name, tag);					    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2, arg3), 0
+#define TRACE_BEG4(lvl, name, tag, fmt, arg1, arg2, arg3, arg4)	    \
+  _TRACE (lvl, name, tag);					    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): enter: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2, arg3, arg4), 0
+
+#define TRACE(lvl, name, tag)						\
+  _pth_debug (lvl, "%s (%s=0x%x): call\n",				\
+		name, STRINGIFY (tag), (void *) tag), 0
+#define TRACE0(lvl, name, tag, fmt)					\
+  _pth_debug (lvl, "%s (%s=0x%x): call: " fmt "\n",			\
+		name, STRINGIFY (tag), (void *) tag), 0
+#define TRACE1(lvl, name, tag, fmt, arg1)			       \
+  _pth_debug (lvl, "%s (%s=0x%x): call: " fmt "\n",		       \
+		name, STRINGIFY (tag), (void *) tag, arg1), 0
+#define TRACE2(lvl, name, tag, fmt, arg1, arg2)			       \
+  _pth_debug (lvl, "%s (%s=0x%x): call: " fmt "\n",		       \
+		name, STRINGIFY (tag), (void *) tag, arg1, arg2), 0
+#define TRACE3(lvl, name, tag, fmt, arg1, arg2, arg3)		       \
+  _pth_debug (lvl, "%s (%s=0x%x): call: " fmt "\n",		       \
+		name, STRINGIFY (tag), (void *) tag, arg1, arg2,       \
+		arg3), 0
+#define TRACE6(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5, arg6)	\
+  _pth_debug (lvl, "%s (%s=0x%x): call: " fmt "\n",			\
+		name, STRINGIFY (tag), (void *) tag, arg1, arg2, arg3,	\
+		arg4, arg5, arg6), 0
+
+#define TRACE_ERR(err)							\
+  err == 0 ? (TRACE_SUC ()) :						\
+    (_pth_debug (_pth_trace_level, "%s (%s=0x%x): error: %s <%s>\n",	\
+		   _pth_trace_func, _pth_trace_tagname,		\
+		   _pth_trace_tag, pth_strerror (err),		\
+		   pth_strsource (err)), (err))
+/* The cast to void suppresses GCC warnings.  */
+#define TRACE_SYSRES(res)						\
+  res >= 0 ? ((void) (TRACE_SUC1 ("result=%i", res)), (res)) :		\
+    (_pth_debug (_pth_trace_level, "%s (%s=0x%x): error: %s\n",	\
+		   _pth_trace_func, _pth_trace_tagname,		\
+		   _pth_trace_tag, strerror (errno)), (res))
+#define TRACE_SYSERR(res)						\
+  res == 0 ? ((void) (TRACE_SUC1 ("result=%i", res)), (res)) :		\
+    (_pth_debug (_pth_trace_level, "%s (%s=0x%x): error: %s\n",	\
+		   _pth_trace_func, _pth_trace_tagname,		\
+		   _pth_trace_tag, strerror (res)), (res))
+
+#define TRACE_SUC()						 \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): leave\n",       \
+		_pth_trace_func, _pth_trace_tagname,	 \
+		_pth_trace_tag), 0
+#define TRACE_SUC0(fmt)							\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): leave: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag), 0
+#define TRACE_SUC1(fmt, arg1)						\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): leave: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag, arg1), 0
+#define TRACE_SUC2(fmt, arg1, arg2)					\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): leave: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag, arg1, arg2), 0
+#define TRACE_SUC5(fmt, arg1, arg2, arg3, arg4, arg5)			\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): leave: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag, arg1, arg2, arg3, arg4, arg5), 0
+
+#define TRACE_LOG(fmt)							\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n",	\
+		_pth_trace_func, _pth_trace_tagname,		\
+		_pth_trace_tag), 0
+#define TRACE_LOG1(fmt, arg1)						\
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1), 0
+#define TRACE_LOG2(fmt, arg1, arg2)				    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2), 0
+#define TRACE_LOG3(fmt, arg1, arg2, arg3)			    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2, arg3), 0
+#define TRACE_LOG4(fmt, arg1, arg2, arg3, arg4)			    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2, arg3, arg4), 0
+#define TRACE_LOG6(fmt, arg1, arg2, arg3, arg4, arg5, arg6)	    \
+  _pth_debug (_pth_trace_level, "%s (%s=0x%x): check: " fmt "\n", \
+		_pth_trace_func, _pth_trace_tagname,	    \
+		_pth_trace_tag, arg1, arg2, arg3, arg4, arg5,	    \
+		arg6), 0
+
+#define TRACE_LOGBUF(buf, len)						\
+  _pth_debug_buffer (_pth_trace_level, "%s (%s=0x%x): check: %s",	\
+		       _pth_trace_func, _pth_trace_tagname,		\
+		       _pth_trace_tag, buf, len)
+
+#define TRACE_SEQ(hlp,fmt)						\
+  _pth_debug_begin (&(hlp), _pth_trace_level,			\
+		      "%s (%s=0x%x): check: " fmt,			\
+		      _pth_trace_func, _pth_trace_tagname,		\
+		      _pth_trace_tag)
+#define TRACE_ADD0(hlp,fmt) \
+  _pth_debug_add (&(hlp), fmt)
+#define TRACE_ADD1(hlp,fmt,a) \
+  _pth_debug_add (&(hlp), fmt, (a))
+#define TRACE_ADD2(hlp,fmt,a,b) \
+  _pth_debug_add (&(hlp), fmt, (a), (b))
+#define TRACE_ADD3(hlp,fmt,a,b,c) \
+  _pth_debug_add (&(hlp), fmt, (a), (b), (c))
+#define TRACE_END(hlp,fmt) \
+  _pth_debug_add (&(hlp), fmt); \
+  _pth_debug_end (&(hlp))
+#define TRACE_ENABLED(hlp) (!!(hlp))
+
+#endif	/* DEBUG_H */

Modified: trunk/libw32pth.def
===================================================================
--- trunk/libw32pth.def	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/libw32pth.def	2008-02-12 00:53:38 UTC (rev 15)
@@ -67,3 +67,5 @@
 
       pth_yield @38
 
+      pth_pipe @39
+      pth_close @40

Modified: trunk/pth.h
===================================================================
--- trunk/pth.h	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/pth.h	2008-02-12 00:53:38 UTC (rev 15)
@@ -1,6 +1,6 @@
 /* pth.h - GNU Pth emulation for W32 (MS Windows).
  * Copyright (c) 1999-2003 Ralf S. Engelschall <rse at engelschall.com>
- * Copyright (C) 2004, 2006, 2007 g10 Code GmbH
+ * Copyright (C) 2004, 2006, 2007, 2008 g10 Code GmbH
  *
  * This file is part of W32PTH.
  *
@@ -44,6 +44,11 @@
 #define W32_PTH_HANDLE_INTERNAL  int
 #endif
 
+/* These are needed for pipe support.  Sigh.  */
+int pth_pipe (int filedes[2], int inherit_idx);
+int pth_close (int fd);
+
+
 /* We need to define value for the how argument of pth_sigmask.  This
    is required because Mingw does not yet define sigprocmask.  We use
    an enum to error out if Mingw eventually defines them.  Also define
@@ -100,7 +105,6 @@
 #define PTH_EVENT_FUNC         (1<<9)
 
 
-
 /* Event occurrence restrictions. */
 #define PTH_UNTIL_OCCURRED     (1<<11)
 #define PTH_UNTIL_FD_READABLE  (1<<12)

Added: trunk/w32-io.c
===================================================================
--- trunk/w32-io.c	2007-08-16 10:39:42 UTC (rev 14)
+++ trunk/w32-io.c	2008-02-12 00:53:38 UTC (rev 15)
@@ -0,0 +1,1034 @@
+/* w32-io.c - W32 API I/O functions.
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2003, 2004, 2007 g10 Code GmbH
+
+   This file is part of PTH.
+ 
+   PTH is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   PTH is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <windows.h>
+
+#include <assert.h>
+
+#include "debug.h"
+#include "w32-io.h"
+
+
+struct critsect_s
+{
+  const char *name;
+  void *priv;
+};
+
+#define DEFINE_GLOBAL_LOCK(name) \
+  struct critsect_s name = { #name, NULL }
+#define DEFINE_STATIC_LOCK(name) \
+  static struct critsect_s name  = { #name, NULL }
+
+#define DECLARE_LOCK(name) \
+  struct critsect_s name
+#define INIT_LOCK(a)			\
+  do					\
+    {					\
+      (a).name = #a;			\
+      (a).priv = NULL;			\
+    }					\
+  while (0)
+#define DESTROY_LOCK(name) _pth_sema_cs_destroy (&(name))
+                       
+
+#define LOCK(name)			\
+  do					\
+    {					\
+      _pth_sema_cs_enter (&(name));	\
+    }					\
+  while (0)
+
+#define UNLOCK(name)			\
+  do					\
+    {					\
+      _pth_sema_cs_leave (&(name));	\
+    }					\
+  while (0)
+
+
+static void
+sema_fatal (const char *text)
+{
+    fprintf (stderr, "sema.c: %s\n", text);
+    abort ();
+}
+
+
+static void
+critsect_init (struct critsect_s *s)
+{
+    CRITICAL_SECTION *mp;
+    static CRITICAL_SECTION init_lock;
+    static int initialized;
+    
+    if (!initialized) {
+        /* The very first time we call this function, we assume that
+	   only one thread is running, so that we can bootstrap the
+	   semaphore code.  */
+        InitializeCriticalSection (&init_lock);
+        initialized = 1;
+    }
+    if (!s)
+        return; /* we just want to initialize ourself */
+
+    /* first test whether it is really not initialized */
+    EnterCriticalSection (&init_lock);
+    if ( s->priv ) {
+        LeaveCriticalSection (&init_lock);
+        return;
+    }
+    /* now init it */
+    mp = malloc ( sizeof *mp );
+    if (!mp) {
+        LeaveCriticalSection (&init_lock);
+        sema_fatal ("out of core while creating critical section lock");
+    }
+    InitializeCriticalSection (mp);
+    s->priv = mp;
+    LeaveCriticalSection (&init_lock);
+}
+
+
+void
+_pth_sema_subsystem_init (void)
+{
+    /* fixme: we should check that there is only one thread running */
+    critsect_init (NULL);
+}
+
+
+void
+_pth_sema_cs_enter ( struct critsect_s *s )
+{
+    if (!s->priv)
+        critsect_init (s);
+    EnterCriticalSection ( (CRITICAL_SECTION*)s->priv );
+}
+
+void
+_pth_sema_cs_leave (struct critsect_s *s)
+{
+    if (!s->priv)
+        critsect_init (s);
+    LeaveCriticalSection ((CRITICAL_SECTION*)s->priv);
+}
+
+void
+_pth_sema_cs_destroy ( struct critsect_s *s )
+{
+    if (s && s->priv) {
+        DeleteCriticalSection ((CRITICAL_SECTION*)s->priv);
+        free (s->priv);
+        s->priv = NULL;
+    }
+}
+
+
+DEFINE_STATIC_LOCK (debug_lock);
+
+#define DEBUG_SYSIO 2
+
+/* Log the formatted string FORMAT at debug level LEVEL or higher.  */
+void
+_pth_debug (int level, const char *format, ...)
+{
+  va_list arg_ptr;
+  int saved_errno;
+
+  saved_errno = errno;
+
+  if (debug_level < level)
+    return;
+    
+  va_start (arg_ptr, format);
+  LOCK (debug_lock);
+  vfprintf (dbgfp, format, arg_ptr);
+  va_end (arg_ptr);
+  if(format && *format && format[strlen (format) - 1] != '\n')
+    putc ('\n', dbgfp);
+  UNLOCK (debug_lock);
+  fflush (dbgfp);
+
+  errno = saved_errno;
+}
+
+
+#define fd_to_handle(a)  ((HANDLE)(a))
+#define handle_to_fd(a)  ((int)(a))
+#define pid_to_handle(a) ((HANDLE)(a))
+#define handle_to_pid(a) ((int)(a))
+
+#define READBUF_SIZE 4096
+#define WRITEBUF_SIZE 4096
+#define PIPEBUF_SIZE  4096
+#define MAX_READERS 40
+#define MAX_WRITERS 40
+
+
+
+struct reader_context_s
+{
+  HANDLE file_hd;
+  HANDLE thread_hd;	
+  int refcount;
+
+  DECLARE_LOCK (mutex);
+
+  int stop_me;
+  int eof;
+  int eof_shortcut;
+  int error;
+  int error_code;
+  
+  /* This is manually reset.  */
+  HANDLE have_data_ev;
+  /* This is automatically reset.  */
+  HANDLE have_space_ev;
+  HANDLE stopped;
+  size_t readpos, writepos;
+  char buffer[READBUF_SIZE];




More information about the Gnupg-commits mailing list