[svn] assuan - r362 - in trunk: . doc src tests

svn author wk cvs at cvs.gnupg.org
Mon Mar 22 13:16:18 CET 2010


Author: wk
Date: 2010-03-22 13:16:18 +0100 (Mon, 22 Mar 2010)
New Revision: 362

Added:
   trunk/src/assuan.h.in
   trunk/src/mkheader.c
   trunk/tests/ChangeLog
   trunk/tests/pipeconnect.c
Removed:
   trunk/src/assuan.h
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/doc/assuan.texi
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/assuan-defs.h
   trunk/src/assuan-pipe-connect.c
   trunk/src/gpgcedev.c
   trunk/src/libassuan.def
   trunk/src/system-w32.c
   trunk/src/system-w32ce.c
   trunk/src/system.c
   trunk/src/sysutils.c
   trunk/tests/Makefile.am
   trunk/tests/ce-createpipe.c
   trunk/tests/ce-server.c
Log:
Changed the implementation of CreatePipe under W32CE.
Reorganized the source.


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/ChangeLog	2010-03-22 12:16:18 UTC (rev 362)
@@ -1,14 +1,16 @@
-2010-02-25  Werner Koch  <wk at g10code.com>
+2010-03-22  Werner Koch  <wk at g10code.com>
 
-	* m4/libtool.m4 (_LT_CHECK_MAGIC_METHOD): Fix for non x86 mingw
-	targets.
+	* configure.ac (CC_FOR_BUILD): Add test.
 
-2010-02-24  Werner Koch  <wk at g10code.com>
+2010-03-17  Werner Koch  <wk at g10code.com>
 
-	* tests/ce-server.c: New.
+	* tests/ChangeLog: New.  Move all relevant entries to there.
 
-	* tests/ce-createpipe.c [W32CE]: New.
+2010-02-25  Werner Koch  <wk at g10code.com>
 
+	* m4/libtool.m4 (_LT_CHECK_MAGIC_METHOD): Fix for non x86 mingw
+	targets.
+
 2010-02-11  Werner Koch  <wk at g10code.com>
 
 	* configure.ac (inet_pton): Check for it.
@@ -17,10 +19,6 @@
 
 	* configure.ac (AC_TYPE_UINT16_T): New.
 
-2010-01-27  Werner Koch  <wk at g10code.com>
-
-	* tests/common.h (SOCKET2HANDLE, HANDLE2SOCKET): New.
-
 2010-01-26  Werner Koch  <wk at g10code.com>
 
 	* configure.ac (NETLIBS) [W32CE]: Use -lws2.
@@ -49,16 +47,6 @@
 
 	* configure.ac: Bump version to 2.0.0.
 
-2009-11-05  Marcus Brinkmann  <marcus at g10code.de>
-
-	* tests/fdpassing.c (main): Call assuan_pipe_connect instead
-	of assuan_pipe_connect_ext.
-
-2009-11-04  Werner Koch  <wk at g10code.com>
-
-	* tests/fdpassing.c (register_commands): Add NULL arg to
-	assuan_register_command.
-
 2009-10-16  Marcus Brinkmann  <marcus at g10code.de>
 
 	* autogen.sh: Remove --with-pth-prefix from configure invocation.
@@ -74,7 +62,6 @@
 
 2009-09-19  Marcus Brinkmann  <marcus at g10code.de>
 
-	* tests/fdpassing.c: Update to new API.
 	* configure.ac: Check for stdint.h and inttypes.h.  Invoke
 	AC_TYPE_UINTPTR_T.
 
@@ -101,18 +88,11 @@
 	(AC_CONFIG_FILES): Add src/versioninfo.rc.
 	* ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltsugar.m4,
 	m4/ltversion.m4, m4/lt~obsolete.m4: New files from libtool 2.2.6.
-	* tests/Makefile.am (AM_CFLAGS, LDADD): Add gpg-error.
-	* tests/fdpassing.c: Change error values to gpg-error ones.
 
 2009-01-22  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Check for nanoleep only in libc.
 
-2008-11-03  Marcus Brinkmann  <marcus at g10code.de>
-
-	* tests/fdpassing.c (register_commands): Add missing initializer
-	to silence gcc -W warning.
-
 2008-05-25  Werner Koch  <wk at g10code.com>
 
 	Released 1.0.5.
@@ -130,7 +110,7 @@
 2007-08-24  Werner Koch  <wk at g10code.com>
 
 	Released 1.0.3.
-	
+
 	Switched license of the library code back to LGPLv2.1.  See NEWS.
 
 	* COPYING.LIB: Replaced by LPGLv2.1
@@ -138,7 +118,7 @@
 2007-07-05  Werner Koch  <wk at g10code.com>
 
 	Released 1.0.2.
-	
+
 	Relicensed to LGPLv3.
 
 	* COPYING: Replaced by GPLv3.
@@ -162,13 +142,13 @@
 
 2007-05-30  Werner Koch  <wk at g10code.com>
 
-	* autogen.sh <--build-w32>: Modernize. 
+	* autogen.sh <--build-w32>: Modernize.
 
 2007-05-29  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Require automake 1.10 and autoconf 2.61.
 	(AM_PROG_CC_C_O): New.  Error out if no C-89 cc is installed.
-	(gl_HEADER_SYS_SOCKET): Explicitly add this for documentation. 
+	(gl_HEADER_SYS_SOCKET): Explicitly add this for documentation.
 
 2007-05-24  Werner Koch  <wk at g10code.com>
 
@@ -202,8 +182,6 @@
 
 	Released 0.9.3.
 
-	* tests/Makefile.am (LDADD): Add NETLIBS.
-
 	* configure.ac: Check for cmsghdr.
 	(USE_DESCRIPTOR_PASSING): Define it then.
 
@@ -214,29 +192,15 @@
 2006-10-04  Werner Koch  <wk at g10code.com>
 
 	Released 0.9.2.
-	
+
 2006-10-04  Werner Koch  <wk at g10code.com>
 
 	Released 0.9.1.
-	
+
 	* configure.ac (AB_INIT): New.
 
 	* m4/autobuild.m4: New.
 
-2006-09-19  Werner Koch  <wk at g10code.com>
-
-	* tests/fdpassing.c: Reverted Marcus changes.
-	(client): New arg FNAME to replace hardwired file name.
-	(main): Pass motd to client.
-	* tests/Makefile.am (AM_CPPFLAGS): Removed.
-	(EXTRA_DIST): Add motd.
-
-2006-09-19  Marcus Brinkmann  <marcus at g10code.de>
-
-	* tests/fdpassing.c (MOTD): New macro.
-	* tests/Makefile.am (AM_CPPFLAGS): New variable.
-	* tests/motd: New file.
-
 2006-09-14  Werner Koch  <wk at g10code.com>
 
 	Released 0.9.0.
@@ -292,7 +256,7 @@
 
 2004-09-27  Werner Koch  <wk at g10code.com>
 
-	* config.sub, config.guess: Updated. 
+	* config.sub, config.guess: Updated.
 
 2004-06-23  Marcus Brinkmann  <marcus at g10code.de>
 
@@ -398,7 +362,7 @@
 	* tests: New directory.
 
 
- Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
@@ -407,5 +371,3 @@
  This file is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/ChangeLog	2010-03-22 12:16:18 UTC (rev 362)
@@ -1,5 +1,39 @@
+2010-03-22  Werner Koch  <wk at g10code.com>
+
+	* Makefile.am (mkheader, assuan.h): Build header file.
+	* mkheader.c: New.
+	* assuan.h: Rename to assuan.h.in.
+
+2010-03-18  Werner Koch  <wk at g10code.com>
+
+	* libassuan.def (_assuan_w32ce_prepare_pipe)
+	(_assuan_w32ce_finish_pipe): New
+	* gpgcedev.c (struct opnctx_s): Replace HD by RVID.
+	(GPGCEDEV_IOCTL_SET_HANDLE): Remove.
+	(GPGCEDEV_IOCTL_GET_RVID): New.
+	(create_rendezvous_id): New.
+	(get_new_opnctx): Init the RVID.
+	(set_handle): Remove.
+	(find_and_lock_opnctx, make_pipe, GPG_IOControl): Change to new
+	method.
+	* system-w32ce.c (_assuan_w32ce_prepare_pipe)
+	(_assuan_w32ce_finish_pipe): New.
+	(_assuan_w32ce_create_pipe): Re-implement using the new functions.
+	(__assuan_pipe): Create an inheritable pipe.
+	(build_w32_commandline): New arg FD2_ISNULL.
+	* system.c (_assuan_close_inheritable): New.
+	* assuan-pipe-connect.c (pipe_connect): Use the new function.
+
+	* sysutils.c (_assuan_w32ce_create_pipe): Move to system-w32ce.c.
+
 2010-03-16  Werner Koch  <wk at g10code.com>
 
+	* system-w32ce.c (build_w32_commandline): Add args to pass the
+	special options for the standard descriptors.
+	(utf8_to_wchar, free_wchar): New.
+	(__assuan_spawn): Adjust for changes.  Convert strings for
+	CreateProcess to wchar_t.
+
 	* system.c: For better readability move platform dependend code to ..
 	* system-posix.c, system-w32.c, system-w32ce.c: .. New.
 	* Makefile.am (common_sources): Account for this change.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/configure.ac	2010-03-22 12:16:18 UTC (rev 362)
@@ -58,7 +58,7 @@
 
 AM_INIT_AUTOMAKE
 AM_MAINTAINER_MODE
-AC_CONFIG_SRCDIR(src/assuan.h)
+AC_CONFIG_SRCDIR(src/assuan.h.in)
 AC_CONFIG_MACRO_DIR(m4)
 AM_CONFIG_HEADER(config.h)
 AC_CANONICAL_HOST
@@ -118,6 +118,22 @@
 AC_PROG_MAKE_SET
 #AC_ARG_PROGRAM
 
+# We need to compile and run a program on the build machine.  A
+# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in
+# the AC archive is broken for autoconf 2.57.  Given that there is no
+# newer version of that macro, we assume that it is also broken for
+# autoconf 2.61 and thus we use a simple but usually sufficient
+# approach.
+AC_MSG_CHECKING(for cc for build)
+if test "$cross_compiling" = "yes"; then
+  CC_FOR_BUILD="${CC_FOR_BUILD-cc}"
+else
+  CC_FOR_BUILD="${CC_FOR_BUILD-$CC}"
+fi
+AC_MSG_RESULT($CC_FOR_BUILD)
+AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
+
+
 if test "$GCC" = yes; then
     CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
 
@@ -325,8 +341,6 @@
 fi
 
 
-
-
 # Create the config files.
 AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([m4/Makefile])

Modified: trunk/doc/assuan.texi
===================================================================
--- trunk/doc/assuan.texi	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/doc/assuan.texi	2010-03-22 12:16:18 UTC (rev 362)
@@ -1064,12 +1064,13 @@
 list @var{argv}.  A list of file descriptors not to be closed may be
 given using the @code{ASSUAN_INVLID_FD} terminated array @var{fd_child_list}.
 
-If @var{name} is a null pointer, only a fork but no exec is done.
-Thus the child continues to run.  However all file descriptors are
-closed and some special environment variables are set.  To let the
-caller detect whether the child or the parent continues, the parent
-returns with @code{"client"} returned in @var{argv} and the child
-returns with @code{"server"} in @var{argv}.
+If @var{name} is a null pointer, only a fork but no exec is done.  Thus
+the child continues to run.  However all file descriptors are closed and
+some special environment variables are set.  To let the caller detect
+whether the child or the parent continues, the parent returns with
+ at code{"client"} returned in @var{argv} and the child returns with
+ at code{"server"} in @var{argv}.  This feature is only available on POSIX
+platforms.
 
 If @var{atfork} is not NULL, this function is called in the child right
 after the fork and the value @var{atforkvalue} is passed as the first

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/Makefile.am	2010-03-22 12:16:18 UTC (rev 362)
@@ -1,5 +1,5 @@
 # Assuan Makefile
-# Copyright (C) 2001, 2002, 2003, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of Assuan.
 #
@@ -18,7 +18,7 @@
 ## Process this file with automake to produce Makefile.in
 
 EXTRA_DIST = libassuan-config.in libassuan.m4 libassuan.vers \
-             versioninfo.rc.in libassuan.def
+             versioninfo.rc.in libassuan.def mkheader.c
 INCLUDES = -I.. -I$(top_srcdir)/include
 
 bin_SCRIPTS = libassuan-config
@@ -37,8 +37,12 @@
 libassuan_version_script_cmd =
 endif
 
+CLEANFILES = mkheader assuan.h
 
+BUILT_SOURCES = assuan.h
+
 common_sources = \
+	assuan.h.in assuan.h w32ce-add.h \
 	assuan-defs.h \
 	assuan.c context.c system.c \
 	debug.c debug.h conversion.c sysutils.c \
@@ -121,3 +125,10 @@
 gpgcemgr_SOURCES = gpgcemgr.c
 gpgcemgr_CPPFLAGS = $(AM_CPPFLAGS)
 endif
+
+mkheader: mkheader.c Makefile
+	$(CC_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
+
+assuan.h: assuan.h.in mkheader w32ce-add.h
+	./mkheader $(host_os) $(srcdir)/assuan.h.in >$@
+

Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/assuan-defs.h	2010-03-22 12:16:18 UTC (rev 362)
@@ -230,6 +230,7 @@
 void _assuan_usleep (assuan_context_t ctx, unsigned int usec);
 int _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx);
 int _assuan_close (assuan_context_t ctx, assuan_fd_t fd);
+int _assuan_close_inheritable (assuan_context_t ctx, assuan_fd_t fd);
 ssize_t _assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer,
 		      size_t size);
 ssize_t _assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,

Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/assuan-pipe-connect.c	2010-03-22 12:16:18 UTC (rev 362)
@@ -175,7 +175,7 @@
   if (_assuan_pipe (ctx, wp, 0) < 0)
     {
       _assuan_close (ctx, rp[0]);
-      _assuan_close (ctx, rp[1]);
+      _assuan_close_inheritable (ctx, rp[1]);
       return _assuan_error (ctx, gpg_err_code_from_syserror ());
     }
   
@@ -197,8 +197,8 @@
     }
 
   /* Close the stdin/stdout child fds in the parent.  */
-  _assuan_close (ctx, rp[1]);
-  _assuan_close (ctx, wp[0]);
+  _assuan_close_inheritable (ctx, rp[1]);
+  _assuan_close_inheritable (ctx, wp[0]);
 
   ctx->engine.release = _assuan_client_release;
   ctx->engine.readfnc = _assuan_simple_read;
@@ -393,7 +393,7 @@
    environment variables are set. To let the caller detect whether the
    child or the parent continues, the child returns "client" or
    "server" in *ARGV (but it is sufficient to check only the first
-   character).  */
+   character).  This feature is only available on POSIX platforms.  */
 gpg_error_t
 assuan_pipe_connect (assuan_context_t ctx,
 		     const char *name, const char *argv[],

Deleted: trunk/src/assuan.h

Copied: trunk/src/assuan.h.in (from rev 361, trunk/src/assuan.h)
===================================================================
--- trunk/src/assuan.h.in	                        (rev 0)
+++ trunk/src/assuan.h.in	2010-03-22 12:16:18 UTC (rev 362)
@@ -0,0 +1,649 @@
+/* assuan.h - Definitions for the Assuan IPC library             -*- c -*-
+   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009,
+                 2010  Free Software Foundation, Inc.
+
+   This file is part of Assuan.
+
+   Assuan 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.
+
+   Assuan 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, see <http://www.gnu.org/licenses/>.
+
+   @configure_input@
+ */
+
+#ifndef ASSUAN_H
+#define ASSUAN_H
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#ifndef _ASSUAN_NO_SOCKET_WRAPPER
+#ifdef _WIN32
+#include <ws2tcpip.h> 
+#else
+#include <sys/socket.h>
+#endif
+#endif /*!_ASSUAN_NO_SOCKET_WRAPPER*/
+
+#ifdef _WIN32
+typedef void *assuan_msghdr_t;
+#else
+typedef struct msghdr *assuan_msghdr_t;
+#endif
+
+#include <gpg-error.h>
+
+/* Compile time configuration:
+
+   #define _ASSUAN_NO_SOCKET_WRAPPER
+
+   Do not include the definitions for the socket wrapper feature.  */
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0
+}
+#endif
+#endif
+
+
+/* Check for compiler features.  */
+#if __GNUC__
+#define _ASSUAN_GCC_VERSION (__GNUC__ * 10000 \
+                            + __GNUC_MINOR__ * 100 \
+                            + __GNUC_PATCHLEVEL__)
+
+#if _ASSUAN_GCC_VERSION > 30100
+#define _ASSUAN_DEPRECATED  __attribute__ ((__deprecated__))
+#endif
+#endif
+#ifndef _ASSUAN_DEPRECATED
+#define _ASSUAN_DEPRECATED
+#endif
+
+
+#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */
+
+struct assuan_context_s;
+typedef struct assuan_context_s *assuan_context_t;
+
+/* Because we use system handles and not libc low level file
+   descriptors on W32, we need to declare them as HANDLE (which
+   actually is a plain pointer).  This is required to eventually
+   support 64 bit Windows systems.  */
+#ifdef _WIN32
+typedef void *assuan_fd_t;
+#define ASSUAN_INVALID_FD ((void*)(-1))
+#define ASSUAN_INVALID_PID ((pid_t) -1)
+static inline assuan_fd_t
+assuan_fd_from_posix_fd (int fd)
+{
+#ifdef __MINGW32CE__
+    return (assuan_fd_t)(fd);
+#else
+  if (fd < 0)
+    return ASSUAN_INVALID_FD;
+  else
+    return (assuan_fd_t) _get_osfhandle (fd);
+#endif
+}
+#else
+typedef int assuan_fd_t;
+#define ASSUAN_INVALID_FD (-1)
+#define ASSUAN_INVALID_PID ((pid_t) -1)
+static inline assuan_fd_t
+assuan_fd_from_posix_fd (int fd)
+{
+  return fd;
+}
+#endif
+
+assuan_fd_t assuan_fdopen (int fd);
+
+
+/* Assuan features an emulation of Unix domain sockets based on a
+   local TCP connections.  To implement access permissions based on
+   file permissions a nonce is used which is expected by the server as
+   the first bytes received.  This structure is used by the server to
+   save the nonce created initially by bind.  On POSIX systems this is
+   a dummy operation. */  
+struct assuan_sock_nonce_s
+{
+  size_t length;
+#ifdef _WIN32
+  char nonce[16];
+#endif
+};
+typedef struct assuan_sock_nonce_s assuan_sock_nonce_t;
+
+/* Define the Unix domain socket structure for Windows.  */
+#if defined(_WIN32) && !defined(_ASSUAN_NO_SOCKET_WRAPPER)
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+#define EADDRINUSE WSAEADDRINUSE
+struct sockaddr_un
+{
+  short          sun_family;
+  unsigned short sun_port;
+  struct         in_addr sun_addr;
+  char           sun_path[108-2-4]; 
+};
+#endif
+
+
+/* Global interface.  */
+
+struct assuan_malloc_hooks
+{
+  void *(*malloc) (size_t cnt);
+  void *(*realloc) (void *ptr, size_t cnt);
+  void (*free) (void *ptr);
+};
+typedef struct assuan_malloc_hooks *assuan_malloc_hooks_t;
+
+/* Categories for log messages.  */
+#define ASSUAN_LOG_INIT 1
+#define ASSUAN_LOG_CTX 2
+#define ASSUAN_LOG_ENGINE 3
+#define ASSUAN_LOG_DATA 4
+#define ASSUAN_LOG_SYSIO 5
+#define ASSUAN_LOG_CONTROL 8
+
+/* If MSG is NULL, return true/false depending on if this category is
+   logged.  This is used to probe before expensive log message
+   generation (buffer dumps).  */
+typedef int (*assuan_log_cb_t) (assuan_context_t ctx, void *hook,
+				unsigned int cat, const char *msg);
+
+/* Set the default gpg error source.  */
+void assuan_set_gpg_err_source (gpg_err_source_t errsource);
+
+/* Get the default gpg error source.  */
+gpg_err_source_t assuan_get_gpg_err_source (void);
+
+
+/* Set the default malloc hooks.  */
+void assuan_set_malloc_hooks (assuan_malloc_hooks_t malloc_hooks);
+
+/* Get the default malloc hooks.  */
+assuan_malloc_hooks_t assuan_get_malloc_hooks (void);
+
+
+/* Set the default log callback handler.  */
+void assuan_set_log_cb (assuan_log_cb_t log_cb, void *log_cb_data);
+
+/* Get the default log callback handler.  */
+void assuan_get_log_cb (assuan_log_cb_t *log_cb, void **log_cb_data);
+
+
+/* Create a new Assuan context.  The initial parameters are all needed
+   in the creation of the context.  */
+gpg_error_t assuan_new_ext (assuan_context_t *ctx, gpg_err_source_t errsource,
+			    assuan_malloc_hooks_t malloc_hooks,
+			    assuan_log_cb_t log_cb, void *log_cb_data);
+
+/* Create a new context with default arguments.  */
+gpg_error_t assuan_new (assuan_context_t *ctx);
+
+/* Release all resources associated with the given context.  */
+void assuan_release (assuan_context_t ctx);
+
+/* Release the memory at PTR using the allocation handler of the
+   context CTX.  This is a convenience function.  */
+void assuan_free (assuan_context_t ctx, void *ptr);
+
+
+/* Set user-data in a context.  */
+void assuan_set_pointer (assuan_context_t ctx, void *pointer);
+
+/* Get user-data in a context.  */
+void *assuan_get_pointer (assuan_context_t ctx);
+
+
+/* Definitions of flags for assuan_set_flag().  */
+typedef unsigned int assuan_flag_t;
+
+/* When using a pipe server, by default Assuan will wait for the
+   forked process to die in assuan_release.  In certain cases this
+   is not desirable.  By setting this flag, the waitpid will be
+   skipped and the caller is responsible to cleanup a forked
+   process. */
+#define ASSUAN_NO_WAITPID 1
+/* This flag indicates whether Assuan logging is in confidential mode.
+   You can use assuan_{begin,end}_condidential to change the mode.  */
+#define ASSUAN_CONFIDENTIAL 2
+/* This flag suppresses fix up of signal handlers for pipes.  */
+#define ASSUAN_NO_FIXSIGNALS 3
+
+/* For context CTX, set the flag FLAG to VALUE.  Values for flags
+   are usually 1 or 0 but certain flags might allow for other values;
+   see the description of the type assuan_flag_t for details.  */
+void assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value);
+
+/* Return the VALUE of FLAG in context CTX.  */
+int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag);
+
+
+/* Same as assuan_set_flag (ctx, ASSUAN_CONFIDENTIAL, 1).  */
+void assuan_begin_confidential (assuan_context_t ctx);
+
+/* Same as assuan_set_flag (ctx, ASSUAN_CONFIDENTIAL, 0).  */
+void assuan_end_confidential (assuan_context_t ctx);
+
+
+/* Direction values for assuan_set_io_monitor.  */
+#define ASSUAN_IO_FROM_PEER 0
+#define ASSUAN_IO_TO_PEER 1
+
+/* Return flags of I/O monitor.  */
+#define ASSUAN_IO_MONITOR_NOLOG 1
+#define ASSUAN_IO_MONITOR_IGNORE 2
+
+/* The IO monitor gets to see all I/O on the context, and can return
+   ASSUAN_IO_MONITOR_* bits to control actions on it.  */
+typedef unsigned int (*assuan_io_monitor_t) (assuan_context_t ctx, void *hook,
+					     int inout, const char *line,
+					     size_t linelen);
+
+/* Set the IO monitor function.  */
+void assuan_set_io_monitor (assuan_context_t ctx,
+			    assuan_io_monitor_t io_monitor, void *hook_data);
+
+
+#define ASSUAN_SYSTEM_HOOKS_VERSION 1
+#define ASSUAN_SPAWN_DETACHED 128
+struct assuan_system_hooks
+{
+  /* Always set to ASSUAN_SYTEM_HOOKS_VERSION.  */
+  int version;
+
+  /* Sleep for the given number of microseconds.  */
+  void (*usleep) (assuan_context_t ctx, unsigned int usec);
+
+  /* Create a pipe with an inheritable end.  */
+  int (*pipe) (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx);
+
+ /* Close the given file descriptor, created with _assuan_pipe or one
+   of the socket functions.  */
+  int (*close) (assuan_context_t ctx, assuan_fd_t fd);
+
+
+  ssize_t (*read) (assuan_context_t ctx, assuan_fd_t fd, void *buffer,
+		   size_t size);
+  ssize_t (*write) (assuan_context_t ctx, assuan_fd_t fd,
+		    const void *buffer, size_t size);
+
+  int (*recvmsg) (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
+		  int flags);
+  int (*sendmsg) (assuan_context_t ctx, assuan_fd_t fd,
+		  const assuan_msghdr_t msg, int flags);
+
+  /* If NAME is NULL, don't exec, just fork.  FD_CHILD_LIST is
+     modified to reflect the value of the FD in the peer process (on
+     Windows).  */
+  int (*spawn) (assuan_context_t ctx, pid_t *r_pid, const char *name,
+		const char **argv,
+		assuan_fd_t fd_in, assuan_fd_t fd_out,
+		assuan_fd_t *fd_child_list,
+		void (*atfork) (void *opaque, int reserved),
+		void *atforkvalue, unsigned int flags);
+
+  /* If action is 0, like waitpid.  If action is 1, just release the PID?  */
+  pid_t (*waitpid) (assuan_context_t ctx, pid_t pid,
+		    int action, int *status, int options);
+  int (*socketpair) (assuan_context_t ctx, int _namespace, int style,
+		     int protocol, assuan_fd_t filedes[2]);
+};
+typedef struct assuan_system_hooks *assuan_system_hooks_t;
+
+
+/* Configuration of the default log handler.  */
+
+/* Set the prefix to be used at the start of a line emitted by assuan
+   on the log stream.  The default is the empty string.  Note, that
+   this function is not thread-safe and should in general be used
+   right at startup. */
+void assuan_set_assuan_log_prefix (const char *text);
+
+/* Return a prefix to be used at the start of a line emitted by assuan
+   on the log stream.  The default implementation returns the empty
+   string, i.e. ""  */
+const char *assuan_get_assuan_log_prefix (void);
+
+/* Global default log stream.  */
+void assuan_set_assuan_log_stream (FILE *fp);
+
+/* Set the per context log stream for the default log handler.  */
+void assuan_set_log_stream (assuan_context_t ctx, FILE *fp);
+
+
+typedef gpg_error_t (*assuan_handler_t) (assuan_context_t, char *);
+
+/*-- assuan-handler.c --*/
+gpg_error_t assuan_register_command (assuan_context_t ctx,
+				     const char *cmd_string,
+				     assuan_handler_t handler,
+                                     const char *help_string);
+gpg_error_t assuan_register_post_cmd_notify (assuan_context_t ctx,
+					     void (*fnc)(assuan_context_t,
+                                                         gpg_error_t));
+gpg_error_t assuan_register_bye_notify (assuan_context_t ctx,
+					assuan_handler_t handler);
+gpg_error_t assuan_register_reset_notify (assuan_context_t ctx,
+					  assuan_handler_t handler);
+gpg_error_t assuan_register_cancel_notify (assuan_context_t ctx,
+					   assuan_handler_t handler);
+gpg_error_t assuan_register_input_notify (assuan_context_t ctx,
+					  assuan_handler_t handler);
+gpg_error_t assuan_register_output_notify (assuan_context_t ctx,
+					   assuan_handler_t handler);
+
+gpg_error_t assuan_register_option_handler (assuan_context_t ctx,
+					    gpg_error_t (*fnc)(assuan_context_t,
+							       const char*,
+                                                               const char*));
+
+gpg_error_t assuan_process (assuan_context_t ctx);
+gpg_error_t assuan_process_next (assuan_context_t ctx, int *done);
+gpg_error_t assuan_process_done (assuan_context_t ctx, gpg_error_t rc);
+int assuan_get_active_fds (assuan_context_t ctx, int what,
+                           assuan_fd_t *fdarray, int fdarraysize);
+
+const char *assuan_get_command_name (assuan_context_t ctx);
+
+FILE *assuan_get_data_fp (assuan_context_t ctx);
+gpg_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line);
+gpg_error_t assuan_write_status (assuan_context_t ctx,
+				 const char *keyword, const char *text);
+
+/* Negotiate a file descriptor.  If LINE contains "FD=N", returns N
+   assuming a local file descriptor.  If LINE contains "FD" reads a
+   file descriptor via CTX and stores it in *RDF (the CTX must be
+   capable of passing file descriptors).  Under W32 the returned FD is
+   a libc-type one.  */
+gpg_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line,
+                                        assuan_fd_t *rfd);
+
+
+/*-- assuan-listen.c --*/
+gpg_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line);
+gpg_error_t assuan_accept (assuan_context_t ctx);
+assuan_fd_t assuan_get_input_fd (assuan_context_t ctx);
+assuan_fd_t assuan_get_output_fd (assuan_context_t ctx);
+gpg_error_t assuan_close_input_fd (assuan_context_t ctx);
+gpg_error_t assuan_close_output_fd (assuan_context_t ctx);
+
+
+/*-- assuan-pipe-server.c --*/
+gpg_error_t assuan_init_pipe_server (assuan_context_t ctx,
+				     assuan_fd_t filedes[2]);
+
+/*-- assuan-socket-server.c --*/
+#define ASSUAN_SOCKET_SERVER_FDPASSING 1
+#define ASSUAN_SOCKET_SERVER_ACCEPTED 2
+gpg_error_t assuan_init_socket_server (assuan_context_t ctx,
+				       assuan_fd_t listen_fd,
+				       unsigned int flags);
+void assuan_set_sock_nonce (assuan_context_t ctx, assuan_sock_nonce_t *nonce);
+
+/*-- assuan-pipe-connect.c --*/
+#define ASSUAN_PIPE_CONNECT_FDPASSING 1
+#define ASSUAN_PIPE_CONNECT_DETACHED 128
+gpg_error_t assuan_pipe_connect (assuan_context_t ctx,
+				 const char *name,
+				 const char *argv[],
+				 assuan_fd_t *fd_child_list,
+				 void (*atfork) (void *, int),
+				 void *atforkvalue,
+				 unsigned int flags);
+
+/*-- assuan-socket-connect.c --*/
+#define ASSUAN_SOCKET_CONNECT_FDPASSING 1
+gpg_error_t assuan_socket_connect (assuan_context_t ctx, const char *name,
+				   pid_t server_pid, unsigned int flags);
+
+/*-- assuan-connect.c --*/
+pid_t assuan_get_pid (assuan_context_t ctx);
+struct _assuan_peercred
+{
+#ifdef _WIN32
+  /* Empty struct not allowed on some compilers.  */
+  unsigned int _dummy;
+#else
+  pid_t pid;
+  uid_t uid;
+  gid_t gid;
+#endif
+};
+typedef struct _assuan_peercred *assuan_peercred_t;
+
+gpg_error_t assuan_get_peercred (assuan_context_t ctx,
+				 assuan_peercred_t *peercred);
+
+
+
+/* Client interface.  */
+#define ASSUAN_RESPONSE_ERROR 0
+#define ASSUAN_RESPONSE_OK 1
+#define ASSUAN_RESPONSE_DATA 2
+#define ASSUAN_RESPONSE_INQUIRE 3
+#define ASSUAN_RESPONSE_STATUS 4
+#define ASSUAN_RESPONSE_END 5
+#define ASSUAN_RESPONSE_COMMENT 6
+typedef int assuan_response_t;
+
+/* This already de-escapes data lines.  */
+gpg_error_t assuan_client_read_response (assuan_context_t ctx,
+					 char **line, int *linelen);
+
+gpg_error_t assuan_client_parse_response (assuan_context_t ctx,
+					  char *line, int linelen,
+					  assuan_response_t *response,
+					  int *off);
+
+/*-- assuan-client.c --*/
+gpg_error_t 
+assuan_transact (assuan_context_t ctx,
+                 const char *command,
+                 gpg_error_t (*data_cb)(void *, const void *, size_t),
+                 void *data_cb_arg,
+                 gpg_error_t (*inquire_cb)(void*, const char *),
+                 void *inquire_cb_arg,
+                 gpg_error_t (*status_cb)(void*, const char *),
+                 void *status_cb_arg);
+
+
+/*-- assuan-inquire.c --*/
+gpg_error_t assuan_inquire (assuan_context_t ctx, const char *keyword,
+                               unsigned char **r_buffer, size_t *r_length,
+                               size_t maxlen);
+gpg_error_t assuan_inquire_ext (assuan_context_t ctx, const char *keyword,
+				size_t maxlen,
+				gpg_error_t (*cb) (void *cb_data,
+						   gpg_error_t rc,
+						   unsigned char *buf,
+						   size_t buf_len),
+				void *cb_data);
+/*-- assuan-buffer.c --*/
+gpg_error_t assuan_read_line (assuan_context_t ctx,
+                              char **line, size_t *linelen);
+int assuan_pending_line (assuan_context_t ctx);
+gpg_error_t assuan_write_line (assuan_context_t ctx, const char *line);
+gpg_error_t assuan_send_data (assuan_context_t ctx,
+                              const void *buffer, size_t length);
+
+/* The file descriptor must be pending before assuan_receivefd is
+   called.  This means that assuan_sendfd should be called *before* the
+   trigger is sent (normally via assuan_write_line ("INPUT FD")).  */
+gpg_error_t assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd);
+gpg_error_t assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd);
+
+
+/*-- assuan-util.c --*/
+gpg_error_t assuan_set_error (assuan_context_t ctx, gpg_error_t err,
+			      const char *text);
+
+
+
+/*-- assuan-socket.c --*/
+
+/* These are socket wrapper functions to support an emulation of Unix
+   domain sockets on Windows W32.  */
+gpg_error_t assuan_sock_init (void);
+void assuan_sock_deinit (void);
+int assuan_sock_close (assuan_fd_t fd);
+assuan_fd_t assuan_sock_new (int domain, int type, int proto);
+int assuan_sock_connect (assuan_fd_t sockfd, 
+                         struct sockaddr *addr, int addrlen);
+int assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
+int assuan_sock_get_nonce (struct sockaddr *addr, int addrlen, 
+                           assuan_sock_nonce_t *nonce);
+int assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
+
+
+/* Set the default or per context system callbacks.  This is
+   irreversible.  */
+void assuan_set_system_hooks (assuan_system_hooks_t system_hooks);
+
+void assuan_ctx_set_system_hooks (assuan_context_t ctx,
+				  assuan_system_hooks_t system_hooks);
+
+void __assuan_usleep (assuan_context_t ctx, unsigned int usec);
+int __assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx);
+int __assuan_close (assuan_context_t ctx, assuan_fd_t fd);
+int __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
+		    const char **argv, assuan_fd_t fd_in, assuan_fd_t fd_out,
+		    assuan_fd_t *fd_child_list,
+		    void (*atfork) (void *opaque, int reserved),
+		    void *atforkvalue, unsigned int flags);
+int __assuan_socketpair (assuan_context_t ctx, int _namespace, int style,
+			 int protocol, assuan_fd_t filedes[2]);
+
+#ifdef _WIN32
+#define _ASSUAN_SYSTEM_PTH_IMPL						\
+  static int _assuan_pth_recvmsg (assuan_context_t ctx, assuan_fd_t fd, \
+				  assuan_msghdr_t msg, int flags)	\
+  {									\
+    (void) ctx;								\
+    errno = ENOSYS;							\
+    return -1;								\
+  }									\
+  static int _assuan_pth_sendmsg (assuan_context_t ctx, assuan_fd_t fd, \
+				  const assuan_msghdr_t msg, int flags) \
+  {									\
+    (void) ctx;								\
+    errno = ENOSYS;							\
+    return -1;								\
+  }
+#else
+#define _ASSUAN_SYSTEM_PTH_IMPL						\
+  static int _assuan_pth_recvmsg (assuan_context_t ctx, assuan_fd_t fd, \
+				  assuan_msghdr_t msg, int flags)	\
+  {									\
+    /* Pth does not provide a recvmsg function.  We implement it.  */	\
+    int ret;								\
+    int fdmode;								\
+									\
+    (void) ctx;								\
+    fdmode = pth_fdmode (fd, PTH_FDMODE_POLL);				\
+    if (fdmode == PTH_FDMODE_ERROR)					\
+      {									\
+        errno = EBADF;							\
+        return -1;							\
+      }									\
+    if (fdmode == PTH_FDMODE_BLOCK)					\
+      {									\
+        fd_set fds;							\
+									\
+	FD_ZERO (&fds);							\
+	FD_SET (fd, &fds);						\
+	while ((ret = pth_select (fd + 1, &fds, NULL, NULL, NULL)) < 0	\
+	       && errno == EINTR)					\
+	  ;								\
+	if (ret < 0)							\
+	  return -1;							\
+      }									\
+    									\
+    while ((ret = recvmsg (fd, msg, flags)) == -1 && errno == EINTR)	\
+      ;									\
+    return ret;								\
+  }									\
+  static int _assuan_pth_sendmsg (assuan_context_t ctx, assuan_fd_t fd, \
+				  const assuan_msghdr_t msg, int flags) \
+  {									\
+    /* Pth does not provide a sendmsg function.  We implement it.  */	\
+    int ret;								\
+    int fdmode;								\
+									\
+    (void) ctx;								\
+    fdmode = pth_fdmode (fd, PTH_FDMODE_POLL);				\
+    if (fdmode == PTH_FDMODE_ERROR)					\
+      {									\
+        errno = EBADF;							\
+	return -1;							\
+      }									\
+    if (fdmode == PTH_FDMODE_BLOCK)					\
+      {									\
+        fd_set fds;							\
+									\
+	FD_ZERO (&fds);							\
+	FD_SET (fd, &fds);						\
+	while ((ret = pth_select (fd + 1, NULL, &fds, NULL, NULL)) < 0	\
+	       && errno == EINTR)					\
+	  ;								\
+	if (ret < 0)							\
+	  return -1;							\
+	}								\
+									\
+    while ((ret = sendmsg (fd, msg, flags)) == -1 && errno == EINTR)	\
+      ;									\
+    return ret;								\
+  }
+#endif
+
+
+#define ASSUAN_SYSTEM_PTH_IMPL						\
+  static void _assuan_pth_usleep (assuan_context_t ctx, unsigned int usec) \
+  { (void) ctx; pth_usleep (usec); }					\
+  static ssize_t _assuan_pth_read (assuan_context_t ctx, assuan_fd_t fd, \
+				void *buffer, size_t size)		\
+  { (void) ctx; return pth_read (fd, buffer, size); }			\
+  static ssize_t _assuan_pth_write (assuan_context_t ctx, assuan_fd_t fd, \
+				 const void *buffer, size_t size)	\
+  { (void) ctx; return pth_write (fd, buffer, size); }			\
+  _ASSUAN_SYSTEM_PTH_IMPL						\
+  static pid_t _assuan_pth_waitpid (assuan_context_t ctx, pid_t pid,     \
+				   int nowait, int *status, int options) \
+  { (void) ctx;                                                         \
+     if (!nowait) return pth_waitpid (pid, status, options);            \
+      else return 0; }							\
+									\
+  struct assuan_system_hooks _assuan_system_pth =			\
+    { ASSUAN_SYSTEM_HOOKS_VERSION, _assuan_pth_usleep, __assuan_pipe,	\
+      __assuan_close, _assuan_pth_read, _assuan_pth_write,		\
+      _assuan_pth_recvmsg, _assuan_pth_sendmsg,				\
+      __assuan_spawn, _assuan_pth_waitpid, __assuan_socketpair }
+
+extern struct assuan_system_hooks _assuan_system_pth;
+#define ASSUAN_SYSTEM_PTH &_assuan_system_pth
+
+ at include:w32ce-add@
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ASSUAN_H */


Property changes on: trunk/src/assuan.h.in
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Modified: trunk/src/gpgcedev.c
===================================================================
--- trunk/src/gpgcedev.c	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/gpgcedev.c	2010-03-22 12:16:18 UTC (rev 362)
@@ -17,6 +17,7 @@
    License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+
 #include <stdio.h>
 #include <stdarg.h>
 #include <windows.h>
@@ -35,19 +36,21 @@
 #endif /*IOCTL_PSL_NOTIFY*/
 
 
-/* The IOCTL used to tell the device about the handle.
+/* The IOCTL to return the rendezvous id of the handle.
 
-   The required inbuf parameter is the address of a variable holding
-   the handle.  */
-#define GPGCEDEV_IOCTL_SET_HANDLE \
+   The required outbuf parameter is the address of a variable to store
+   the rendezvous ID, which is a LONG value.  */
+#define GPGCEDEV_IOCTL_GET_RVID \
   CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 /* The IOCTL used to create the pipe. 
 
-   The caller sends this IOCTL to the read handle.  The required inbuf
-   parameter is the address of variable holding the write handle.
-   Note that the SET_HANDLE IOCTLs must have been used prior to this
-   one.  */
+   The caller sends this IOCTL to the read or the write handle.  The
+   required inbuf parameter is address of a variable holding the
+   rendezvous id of the pipe's other end.  There is one possible
+   problem with eocdde: If a pipe is kept in non-rendezvous state
+   until after the rendezvous ids overflow, it is possible that the
+   wrong end will be used.  However this is not a realistic scenario.  */
 #define GPGCEDEV_IOCTL_MAKE_PIPE \
   CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
@@ -62,7 +65,7 @@
                        other context; i.e. a pipe has been
                        established.  */
   int is_write;     /* True if this is the write end of the pipe.  */
-  HANDLE hd;        /* The system's handle object or INVALID_HANDLE_VALUE.  */
+  LONG rvid;        /* The unique rendezvous identifier.  */
   DWORD access_code;/* Value from OpenFile.  */
   DWORD share_mode; /* Value from OpenFile.  */
   CRITICAL_SECTION critsect;  /* Lock for all operations.  */
@@ -118,7 +121,20 @@
 }
 
 
+/* Return a new rendezvous next command id.  Command Ids are used to group
+   resources of one command.  We will never return an RVID of 0. */
+static LONG
+create_rendezvous_id (void)
+{
+  static LONG rendezvous_id;
+  LONG rvid;
 
+  while (!(rvid = InterlockedIncrement (&rendezvous_id)))
+    ;
+  return rvid;
+}
+
+
 
 /* Return a new opnctx handle and mark it as used.  Returns NULL and
    sets LastError on memory failure etc.  On success the context is
@@ -152,8 +168,7 @@
     }
   opnctx = opnctx_table + idx;
   opnctx->assoc = NULL;
-  opnctx->hd = INVALID_HANDLE_VALUE;
-  opnctx->assoc = 0;
+  opnctx->rvid = create_rendezvous_id ();
   opnctx->buffer_size = 512;
   opnctx->buffer = malloc (opnctx->buffer_size);
   if (!opnctx->buffer)
@@ -173,36 +188,45 @@
   
  leave:
   LeaveCriticalSection (&opnctx_table_cs);
-  log_debug ("get_new_opnctx -> %p\n", opnctx);
+  if (opnctx)
+    log_debug ("get_new_opnctx -> %p (rvid=%ld)\n", opnctx, opnctx->rvid);
+  else
+    log_debug ("get_new_opnctx -> failed\n");
   return opnctx;
 }
 
 
-/* Find the OPNCTX for handle HD.  */
+/* Find the OPNCTX object with the rendezvous id RVID.  */
 static opnctx_t
-find_and_lock_opnctx (HANDLE hd)
+find_and_lock_opnctx (LONG rvid)
 {
   opnctx_t result = NULL;
   int idx;
 
   EnterCriticalSection (&opnctx_table_cs);
   for (idx=0; idx < opnctx_table_size; idx++)
-    if (opnctx_table[idx].inuse && opnctx_table[idx].hd == hd)
+    if (opnctx_table[idx].inuse && opnctx_table[idx].rvid == rvid)
       {
         result = opnctx_table + idx;
         break;
       }
   LeaveCriticalSection (&opnctx_table_cs);
   if (!result)
-    SetLastError (ERROR_INVALID_HANDLE);
+    {
+      SetLastError (ERROR_INVALID_HANDLE);
+      log_debug ("find_opnctx -> invalid rendezvous id\n");
+    }
   else if (TryEnterCriticalSection (&result->critsect))
-    result->locked++;
+    {
+      result->locked++;
+      log_debug ("find_opnctx -> %p (rvid=%ld)\n", result, result->rvid);
+    }
   else
     {
       SetLastError (ERROR_BUSY);
       result = NULL;
+      log_debug ("find_opnctx -> busy\n");
     }
-  log_debug ("find_opnctx -> %p\n", result);
   return result;
 }
 
@@ -353,14 +377,10 @@
   for (idx=0; idx < opnctx_table_size; idx++)
     if (opnctx_table[idx].inuse && (opnctx_table + idx) == opnctx)
       {
-        if (opnctx->hd != INVALID_HANDLE_VALUE)
+        if (opnctx->assoc)
           {
-            if (opnctx->assoc)
-              {
-                opnctx->assoc->assoc = NULL;
-                opnctx->assoc = NULL;
-              }
-            opnctx->hd = INVALID_HANDLE_VALUE;
+            opnctx->assoc->assoc = NULL;
+            opnctx->assoc = NULL;
           }
         if (opnctx->locked)
           {
@@ -419,7 +439,7 @@
       SetLastError (ERROR_INVALID_ACCESS);
       goto leave;
     }
-  if (rctx->hd == INVALID_HANDLE_VALUE || !rctx->assoc)
+  if (!rctx->assoc)
     {
       SetLastError (ERROR_BROKEN_PIPE);
       goto leave;
@@ -490,7 +510,7 @@
       SetLastError (ERROR_INVALID_ACCESS);
       goto leave;
     }
-  if (wctx->hd == INVALID_HANDLE_VALUE || !wctx->assoc)
+  if (!wctx->assoc)
     {
       SetLastError (ERROR_BROKEN_PIPE);
       goto leave;
@@ -546,79 +566,78 @@
 
 
 static BOOL
-set_handle (opnctx_t opnctx, HANDLE hd)
+make_pipe (opnctx_t ctx, LONG rvid)
 {
-  log_debug ("  set_handle(%p, hd=%p)\n", opnctx, hd);
-  if (opnctx->hd != INVALID_HANDLE_VALUE)
-    {
-      SetLastError (ERROR_ALREADY_ASSIGNED);
-      return FALSE;
-    }
-  opnctx->hd = hd;
-  return TRUE;
-}
-
-static BOOL
-make_pipe (opnctx_t rctx, HANDLE hd)
-{
   BOOL result = FALSE;
-  opnctx_t wctx = NULL;
+  opnctx_t peerctx = NULL;
 
-  log_debug ("  make_pipe(%p, hd=%p)\n", rctx, hd);
-  if (rctx->hd == INVALID_HANDLE_VALUE)
+  log_debug ("  make_pipe(%p, rvid=%ld)\n", ctx, rvid);
+  if (ctx->assoc)
     {
-      SetLastError (ERROR_NOT_READY);
-      goto leave;
-    }
-  if (rctx->assoc)
-    {
       SetLastError (ERROR_ALREADY_ASSIGNED);
       goto leave;
     }
-  if (!(rctx->access_code & GENERIC_READ))
-    {
-      SetLastError (ERROR_INVALID_ACCESS);
-      goto leave;
-    }
 
-  wctx = find_and_lock_opnctx (hd);
-  if (!wctx)
+  peerctx = find_and_lock_opnctx (rvid);
+  if (!peerctx)
     {
       SetLastError (ERROR_NOT_FOUND);
       goto leave;
     }
-  if (wctx == rctx)
+  if (peerctx == ctx)
     {
       SetLastError (ERROR_INVALID_TARGET_HANDLE);
       goto leave;
     }
-  if (wctx->hd == INVALID_HANDLE_VALUE)
+  if (peerctx->assoc)
     {
-      SetLastError (ERROR_NOT_READY);
+      SetLastError (ERROR_ALREADY_ASSIGNED);
       goto leave;
     }
-  if (wctx->assoc)
+
+  if ((ctx->access_code & GENERIC_READ))
     {
-      SetLastError (ERROR_ALREADY_ASSIGNED);
-      goto leave;
+      /* Check that the peer is a write end.  */
+      if (!(peerctx->access_code & GENERIC_WRITE))
+        {
+          SetLastError (ERROR_INVALID_ACCESS);
+          goto leave;
+        }
+      peerctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+      peerctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+      
+      ctx->assoc = peerctx;
+      peerctx->assoc = ctx;
+      ctx->is_write = 0;
+      peerctx->is_write = 1;
+      result = TRUE;
     }
-  if (!(wctx->access_code & GENERIC_WRITE))
+  else if ((ctx->access_code & GENERIC_WRITE))
     {
+      /* Check that the peer is a read end.  */
+      if (!(peerctx->access_code & GENERIC_READ))
+        {
+          SetLastError (ERROR_INVALID_ACCESS);
+          goto leave;
+        }
+      ctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+      ctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
+      
+      ctx->assoc = peerctx;
+      peerctx->assoc = ctx;
+      ctx->is_write = 1;
+      peerctx->is_write = 0;
+      result = TRUE;
+    }
+  else
+    {
       SetLastError (ERROR_INVALID_ACCESS);
       goto leave;
     }
-  wctx->space_available = CreateEvent (NULL, FALSE, FALSE, NULL);
-  wctx->data_available = CreateEvent (NULL, FALSE, FALSE, NULL);
-  
-  rctx->assoc = wctx;
-  wctx->assoc = rctx;
-  rctx->is_write = 0;
-  wctx->is_write = 1;
-  result = TRUE;
 
  leave:
-  if (wctx)
-    unlock_opnctx (wctx);
+  if (peerctx)
+    unlock_opnctx (peerctx);
   return result;
 }
 
@@ -629,6 +648,7 @@
 {
   opnctx_t opnctx = (opnctx_t)opnctx_arg;
   BOOL result = FALSE;
+  LONG rvid;
 
   log_debug ("GPG_IOControl(%p, %d)\n", (void*)opnctx, code);
   if (!validate_and_lock_opnctx (opnctx, LOCK_TRY))
@@ -636,25 +656,28 @@
 
   switch (code)
     {
-    case GPGCEDEV_IOCTL_SET_HANDLE:
-      if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE) 
-          || outbuf || outbuflen || actualoutlen )
+    case GPGCEDEV_IOCTL_GET_RVID:
+      if (!opnctx || inbuf || inbuflen
+          || !outbuf || outbuflen  < sizeof (LONG))
         {
           SetLastError (ERROR_INVALID_PARAMETER);
           goto leave;
         }
-      if (set_handle (opnctx, *(HANDLE*)inbuf))
-        result = TRUE;
+      memcpy (outbuf, &opnctx->rvid, sizeof (LONG));
+      if (actualoutlen)
+        *actualoutlen = sizeof (LONG);
+      result = TRUE;
       break;
 
     case GPGCEDEV_IOCTL_MAKE_PIPE:
-      if (!opnctx || !inbuf || inbuflen < sizeof (HANDLE) 
+      if (!opnctx || !inbuf || inbuflen < sizeof (LONG) 
           || outbuf || outbuflen || actualoutlen )
         {
           SetLastError (ERROR_INVALID_PARAMETER);
           goto leave;
         }
-      if (make_pipe (opnctx, *(HANDLE*)inbuf))
+      memcpy (&rvid, inbuf, sizeof (LONG));
+      if (make_pipe (opnctx, rvid))
         result = TRUE;
       break;
 

Modified: trunk/src/libassuan.def
===================================================================
--- trunk/src/libassuan.def	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/libassuan.def	2010-03-22 12:16:18 UTC (rev 362)
@@ -99,6 +99,8 @@
     assuan_set_sock_nonce               @78
     _assuan_w32ce_create_pipe           @79
     assuan_free                         @80
+    _assuan_w32ce_prepare_pipe          @81
+    _assuan_w32ce_finish_pipe           @82
 
 ; END
 

Added: trunk/src/mkheader.c
===================================================================
--- trunk/src/mkheader.c	                        (rev 0)
+++ trunk/src/mkheader.c	2010-03-22 12:16:18 UTC (rev 362)
@@ -0,0 +1,192 @@
+/* mkheader.c - Create a header file for libassuan.
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ * 
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGM "mkheader"
+
+#define LINESIZE 1024
+
+static const char *host_os;
+static char *srcdir;
+
+
+/* Include the file NAME form the source directory.  The included file
+   is not further expanded.  It may have comments indicated by a
+   double hash masrk at the begin of a line.  */
+static void
+include_file (const char *fname, int lnr, const char *name)
+{
+  FILE *fp;
+  char *incfname;
+  char line[LINESIZE];
+
+  incfname = malloc (strlen (srcdir) + strlen (name) + 1);
+  if (!incfname)
+    {
+      fputs (PGM ": out of core\n", stderr);
+      exit (1);
+    }
+  strcpy (incfname, srcdir);
+  strcat (incfname, name);
+
+  fp = fopen (incfname, "r");
+  if (!fp)
+    {
+      fprintf (stderr, "%s:%d: error including `%s': %s\n", 
+               fname, lnr, incfname, strerror (errno));
+      exit (1);
+    }
+
+  while (fgets (line, LINESIZE, fp))
+    {
+      if (line[0] != '#' && line[1] != '#')
+        fputs (line, stdout);
+    }
+  if (ferror (fp))
+    {
+      fprintf (stderr, "%s:%d: error reading `%s': %s\n", 
+               fname, lnr, incfname, strerror (errno));
+      exit (1);
+    }
+  fclose (fp);
+  free (incfname);
+}
+
+
+static int
+write_special (const char *fname, int lnr, const char *tag)
+{
+  if (!strcmp (tag, "include:w32ce-add"))
+    {
+      if (!strcmp (host_os, "mingw32ce"))
+        include_file (fname, lnr, "w32ce-add.h");
+    }
+  else
+    return 0; /* Unknown tag.  */
+
+  return 1; /* Tag processed.  */
+}
+
+
+int 
+main (int argc, char **argv)
+{
+  FILE *fp;
+  char line[LINESIZE];
+  int lnr = 0;
+  const char *fname, *s;
+  char *p1, *p2;
+
+  if (argc)
+    {
+      argc--; argv++;
+    }
+ 
+  if (argc != 2)
+    {
+      fputs ("usage: " PGM " host_os template.h\n", stderr);
+      return 1;
+    }
+  host_os = argv[0];
+  fname = argv[1];
+
+  srcdir = malloc (strlen (fname) + 2 + 1);
+  if (!srcdir)
+    {
+      fputs (PGM ": out of core\n", stderr);
+      return 1;
+    }
+  strcpy (srcdir, fname);
+  p1 = strrchr (srcdir, '/');
+  if (p1)
+    p1[1] = 0;
+  else
+    strcpy (srcdir, "./");
+
+  fp = fopen (fname, "r");
+  if (!fp)
+    {
+      fprintf (stderr, "%s:%d: can't open file: %s",
+               fname, lnr, strerror (errno));
+      return 1;
+    }
+  
+  while (fgets (line, LINESIZE, fp))
+    {
+      size_t n = strlen (line);
+
+      lnr++;
+      if (!n || line[n-1] != '\n')
+        {
+          fprintf (stderr,
+                   "%s:%d: trailing linefeed missing, line too long or "
+                   "embedded Nul character", fname, lnr);
+          break;
+        }
+      line[--n] = 0;
+      
+      p1 = strchr (line, '@');
+      p2 = p1? strchr (p1+1, '@') : NULL;
+      if (!p1 || !p2 || p2-p1 == 1)
+        {
+          puts (line);
+          continue;
+        }
+      *p1++ = 0;
+      *p2++ = 0;
+      fputs (line, stdout);
+
+      if (!strcmp (p1, "configure_input"))
+        {
+          s = strrchr (fname, '/');
+          printf ("Do not edit.  Generated from %s by %s for %s.", 
+                  s? s+1 : fname, PGM, host_os);
+        }
+      else if (!write_special (fname, lnr, p1))
+        {
+          putchar ('@');
+          fputs (p1, stdout);
+          putchar ('@');
+        }
+      
+      fputs (p2, stdout);
+      putchar ('\n');
+    }
+
+  if (ferror (fp))
+    {
+      fprintf (stderr, "%s:%d: error reading file: %s\n", 
+               fname, lnr, strerror (errno));
+      return 1;
+    }
+
+  fputs ("/*\n"
+         "Local Variables:\n"
+         "buffer-read-only: t\n"
+         "End:\n"
+         "*/\n", stdout);
+
+  if (ferror (stdout))
+    {
+      fprintf (stderr, PGM ": error writing stdout: %s\n", strerror (errno));
+      return 1;
+    }
+  
+  fclose (fp);
+
+  return 0;
+}

Modified: trunk/src/system-w32.c
===================================================================
--- trunk/src/system-w32.c	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/system-w32.c	2010-03-22 12:16:18 UTC (rev 362)
@@ -64,6 +64,33 @@
 
 
 
+/* Three simple wrappers, only used because thes function are named in
+   the def file.  */
+HANDLE
+_assuan_w32ce_prepare_pipe (int *r_rvid, int write_end)
+{
+  (void)r_rvid;
+  (void)write_end;
+  return INVALID_HANDLE_VALUE;
+}
+
+HANDLE
+_assuan_w32ce_finish_pipe (int rvid, int write_end)
+{
+  (void)rvid;
+  (void)write_end;
+  return INVALID_HANDLE_VALUE;
+}
+
+DWORD
+_assuan_w32ce_create_pipe (HANDLE *read_hd, HANDLE *write_hd,
+                           LPSECURITY_ATTRIBUTES sec_attr, DWORD size)
+{
+  return CreatePipe (read_hd, write_hd, sec_attr, size);
+}
+
+
+
 /* Create a pipe with one inheritable end.  Default implementation.  */
 int
 __assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx)

Modified: trunk/src/system-w32ce.c
===================================================================
--- trunk/src/system-w32ce.c	2010-03-16 13:04:42 UTC (rev 361)
+++ trunk/src/system-w32ce.c	2010-03-22 12:16:18 UTC (rev 362)
@@ -27,57 +27,207 @@
 #include <time.h>
 #include <fcntl.h>
 #include <windows.h>
+#include <winioctl.h>
+#include <devload.h>
 
 #include "assuan-defs.h"
 #include "debug.h"
 
 
+#define GPGCEDEV_IOCTL_GET_RVID                                         \
+  CTL_CODE (FILE_DEVICE_STREAMS, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define GPGCEDEV_IOCTL_MAKE_PIPE                                        \
+  CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+
 
-assuan_fd_t
-assuan_fdopen (int fd)
+static wchar_t *
+utf8_to_wchar (const char *string)
 {
-  assuan_fd_t ifd = (assuan_fd_t)fd;
-  assuan_fd_t ofd;
+  int n;
+  size_t nbytes;
+  wchar_t *result;
 
-  if (! DuplicateHandle(GetCurrentProcess(), ifd, 
-			GetCurrentProcess(), &ofd, 0,
-			TRUE, DUPLICATE_SAME_ACCESS))
+  if (!string)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+  if (n < 0)
     {
-      gpg_err_set_errno (EIO);
-      return ASSUAN_INVALID_FD;
+      gpg_err_set_errno (EINVAL);
+      return NULL;
     }
-  return ofd;
+
+  nbytes = (size_t)(n+1) * sizeof(*result);
+  if (nbytes / sizeof(*result) != (n+1)) 
+    {
+      gpg_err_set_errno (ENOMEM);
+      return NULL;
+    }
+  result = malloc (nbytes);
+  if (!result)
+    return NULL;
+
+  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+  if (n < 0)
+    {
+      free (result);
+      gpg_err_set_errno (EINVAL);
+      result = NULL;
+    }
+  return result;
 }
 
+/* Convenience function.  */
+static void
+free_wchar (wchar_t *string)
+{
+  if (string)
+    free (string);
+}
 




More information about the Gnupg-commits mailing list