[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