[svn] gpgme - r1136 - in trunk: . gpgme m4

svn author marcus cvs at cvs.gnupg.org
Thu Nov 17 19:45:16 CET 2005


Author: marcus
Date: 2005-11-17 19:45:14 +0100 (Thu, 17 Nov 2005)
New Revision: 1136

Added:
   trunk/gpgme/w32-glib-io.c
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/gpgme/ChangeLog
   trunk/gpgme/Makefile.am
   trunk/gpgme/gpgme-config.in
   trunk/gpgme/gpgme.def
   trunk/gpgme/gpgme.m4
   trunk/gpgme/w32-io.c
   trunk/m4/ChangeLog
Log:
2005-11-17  Marcus Brinkmann  <marcus at g10code.de>

	* configure.ac: Add support for --enable-w32-glib (disabled by
	default).  Invoke AM_PATH_GLIB_2_0.

gpgme/
2005-11-17  Marcus Brinkmann  <marcus at g10code.de>

	* w32-glib-io.c: New file.
	* gpgme.def (gpgme_get_giochannel): Add symbol.
	* Makefile.am (system_components) [HAVE_DOSISH_SYSTEM]: Remove
	w32-io.c.
	(ltlib_gpgme_extra): New variable.
	(lib_LTLIBRARIES): Add $(ltlib_gpgme_extra).
	(system_components_not_extra): New variable.
	(libgpgme_la_SOURCES, libgpgme_pthread_la_SOURCES,
	(libgpgme_pth_la_SOURCES): Add $(system_components_not_extra).
	(libgpgme_glib_la_LDFLAGS, libgpgme_glib_la_DEPENDENCIES,
	(libgpgme_glib_la_LIBADD, libgpgme_glib_la_CFLAGS)
	[BUILD_W32_GLIB]: New variables. 
	* gpgme-config.in (glib): New option.
	* gpgme.m4 (AM_PATH_GPGME_GLIB): New macro.

m4/
2005-11-17  Marcus Brinkmann  <marcus at g10code.de>

	* glib-2.0.m4: New file.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/ChangeLog	2005-11-17 18:45:14 UTC (rev 1136)
@@ -1,3 +1,8 @@
+2005-11-17  Marcus Brinkmann  <marcus at g10code.de>
+
+	* configure.ac: Add support for --enable-w32-glib (disabled by
+	default).  Invoke AM_PATH_GLIB_2_0.
+
 2005-11-15  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Create BUILD_FILEVERSION from SVN Revision.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/configure.ac	2005-11-17 18:45:14 UTC (rev 1136)
@@ -147,6 +147,12 @@
 fi
 AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
 
+build_w32_glib=no
+AM_PATH_GLIB_2_0
+AC_ARG_ENABLE(w32-glib,
+	    AC_HELP_STRING([--enable-w32-glib], [build GPGME Glib for W32]),
+	    build_w32_glib=$withval)
+AM_CONDITIONAL(BUILD_W32_GLIB, test "$build_w32_glib" = yes)
 
 AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
 AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes")

Modified: trunk/gpgme/ChangeLog
===================================================================
--- trunk/gpgme/ChangeLog	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/ChangeLog	2005-11-17 18:45:14 UTC (rev 1136)
@@ -1,5 +1,22 @@
 2005-11-17  Marcus Brinkmann  <marcus at g10code.de>
 
+	* w32-glib-io.c: New file.
+	* gpgme.def (gpgme_get_giochannel): Add symbol.
+	* Makefile.am (system_components) [HAVE_DOSISH_SYSTEM]: Remove
+	w32-io.c.
+	(ltlib_gpgme_extra): New variable.
+	(lib_LTLIBRARIES): Add $(ltlib_gpgme_extra).
+	(system_components_not_extra): New variable.
+	(libgpgme_la_SOURCES, libgpgme_pthread_la_SOURCES,
+	(libgpgme_pth_la_SOURCES): Add $(system_components_not_extra).
+	(libgpgme_glib_la_LDFLAGS, libgpgme_glib_la_DEPENDENCIES,
+	(libgpgme_glib_la_LIBADD, libgpgme_glib_la_CFLAGS)
+	[BUILD_W32_GLIB]: New variables. 
+	* gpgme-config.in (glib): New option.
+	* gpgme.m4 (AM_PATH_GPGME_GLIB): New macro.
+
+2005-11-17  Marcus Brinkmann  <marcus at g10code.de>
+
 	* priv-io.h (_gpgme_io_waitpid, _gpgme_io_kill): Removed.
 	* w32-io.c (_gpgme_io_waitpid, _gpgme_io_kill): Removed.
 	* posix-io.c (_gpgme_io_kill): Removed.

Modified: trunk/gpgme/Makefile.am
===================================================================
--- trunk/gpgme/Makefile.am	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/Makefile.am	2005-11-17 18:45:14 UTC (rev 1136)
@@ -1,4 +1,4 @@
-# Copyright (C) 2000 Werner Koch (dd9jn)
+ # Copyright (C) 2000 Werner Koch (dd9jn)
 # Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
 # 
 # This file is part of GPGME.
@@ -39,8 +39,15 @@
 ltlib_gpgme_pth =
 endif
 
+if BUILD_W32_GLIB
+ltlib_gpgme_extra = libgpgme-glib.la
+else
+ltlib_gpgme_extra =
+endif
+
 noinst_LTLIBRARIES = libgpgme-real.la
-lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_pthread) $(ltlib_gpgme_pth)
+lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_extra) \
+	$(ltlib_gpgme_pthread) $(ltlib_gpgme_pth)
 
 if HAVE_LD_VERSION_SCRIPT
 libgpgme_version_script_cmd = -Wl,--version-script=$(srcdir)/libgpgme.vers
@@ -57,9 +64,11 @@
 endif
 
 if HAVE_DOSISH_SYSTEM
-system_components = w32-util.c w32-sema.c w32-io.c
+system_components = w32-util.c w32-sema.c
+system_components_not_extra = w32-io.c
 else
 system_components = ath.h posix-util.c posix-sema.c posix-io.c
+system_components_not_extra =
 endif
 
 if HAVE_GPGSM
@@ -83,10 +92,15 @@
 	$(gpgsm_components) sema.h priv-io.h $(system_components)	\
 	debug.c debug.h gpgme.c version.c error.c
 
-libgpgme_la_SOURCES = ath.h ath.c
-libgpgme_pthread_la_SOURCES = ath.h ath-pthread.c
-libgpgme_pth_la_SOURCES = ath.h ath-pth.c
+libgpgme_la_SOURCES = ath.h ath.c $(system_components_not_extra)
+libgpgme_pthread_la_SOURCES = \
+	ath.h ath-pthread.c $(system_components_not_extra)
+libgpgme_pth_la_SOURCES = ath.h ath-pth.c $(system_components_not_extra)
 
+if BUILD_W32_GLIB
+libgpgme_glib_la_SOURCES = ath.h ath.c w32-glib-io.c
+endif
+
 AM_CPPFLAGS = $(assuan_cppflags) @GPG_ERROR_CFLAGS@
 
 
@@ -149,6 +163,17 @@
 libgpgme_pth_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \
 	@PTH_LIBS@ @GPG_ERROR_LIBS@
 
+if BUILD_W32_GLIB
+libgpgme_glib_la_LDFLAGS = $(gpgme_res_ldflag) $(no_undefined) \
+	$(export_symbols) $(libgpgme_version_script_cmd) -version-info \
+	@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
+libgpgme_glib_la_CFLAGS = $(AM_CFLAGS) @GLIB_CFLAGS@
+libgpgme_glib_la_DEPENDENCIES = libgpgme-real.la $(assuan_libobjs) \
+	@LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps)
+libgpgme_glib_la_LIBADD = libgpgme-real.la $(assuan_libobjs) @LTLIBOBJS@ \
+	@GPG_ERROR_LIBS@ @GLIB_LIBS@
+endif
+
 status-table.h : gpgme.h
 	$(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h
 

Modified: trunk/gpgme/gpgme-config.in
===================================================================
--- trunk/gpgme/gpgme-config.in	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/gpgme-config.in	2005-11-17 18:45:14 UTC (rev 1136)
@@ -25,9 +25,10 @@
 libs_pth="@PTH_LDFLAGS@ @PTH_LIBS@"
 cflags_pth="@PTH_CFLAGS@"
 
- at HAVE_PTHREAD_TRUE@thread_modules="$thread_modules pthread"
-libs_pthread="-lpthread"
-cflags_pthread=""
+# Configure glib.
+libs_glib="@GLIB_LIBS@"
+cflags_glib="@GLIB_CFLAGS@"
+with_glib=
 
 output=""
 
@@ -74,6 +75,9 @@
         --exec-prefix)
 	    output="$output $exec_prefix"
 	    ;;
+	--glib)
+	    with_glib=yes
+	    ;;
         --version)
             echo "@VERSION@"
 	    exit 0
@@ -95,6 +99,9 @@
 		    ;;
 	    esac
 	    output="$output $gpg_error_cflags"
+	    if test "x$with_glib" = "xyes"; then
+		output="$output $glib_cflags"
+	    fi
 	    ;;
 	--libs)
 	    if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then
@@ -105,12 +112,20 @@
 	            output="$output -lgpgme-pthread $libs_pthread"
 		    ;;
 	        pth)
-	            output="$output -lgpgme-pth $libs_pth"
+		    output="$output -lgpgme-pth $libs_pth"
 		    ;;
 		*)
-		    output="$output -lgpgme"
+		    if test "x$with_glib" = "xyes"; then
+			output="$output -lgpgme-glib"
+		    else
+			output="$output -lgpgme"
+		    fi
+		    ;;
 	    esac
 	    output="$output $gpg_error_libs"
+	    if test "x$with_glib" = "xyes"; then
+		output="$output $glib_cflags"
+	    fi
 	    ;;
 	--thread=*)
             for thread_mod in $thread_modules; do

Modified: trunk/gpgme/gpgme.def
===================================================================
--- trunk/gpgme/gpgme.def	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/gpgme.def	2005-11-17 18:45:14 UTC (rev 1136)
@@ -152,5 +152,7 @@
     gpgme_sig_notation_get		  @119
 
     gpgme_free				  @120
+
+    gpgme_get_giochannel		  @121
 ; END
 

Modified: trunk/gpgme/gpgme.m4
===================================================================
--- trunk/gpgme/gpgme.m4	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/gpgme.m4	2005-11-17 18:45:14 UTC (rev 1136)
@@ -236,3 +236,72 @@
   AC_SUBST(GPGME_PTHREAD_CFLAGS)
   AC_SUBST(GPGME_PTHREAD_LIBS)
 ])
+
+
+dnl AM_PATH_GPGME_GLIB([MINIMUM-VERSION,
+dnl               [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgpgme-glib and define GPGME_GLIB_CFLAGS and GPGME_GLIB_LIBS.
+dnl
+AC_DEFUN([AM_PATH_GPGME_GLIB],
+[ AC_REQUIRE([_AM_PATH_GPGME_CONFIG])dnl
+  tmp=ifelse([$1], ,1:0.4.2,$1)
+  if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+     req_gpgme_api=`echo "$tmp"     | sed 's/\(.*\):\(.*\)/\1/'`
+     min_gpgme_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+  else
+     req_gpgme_api=0
+     min_gpgme_version="$tmp"
+  fi
+
+  AC_MSG_CHECKING(for GPGME - version >= $min_gpgme_version)
+  ok=no
+  if test "$GPGME_CONFIG" != "no" ; then
+    req_major=`echo $min_gpgme_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+    req_minor=`echo $min_gpgme_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+    req_micro=`echo $min_gpgme_version | \
+               sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+    if test "$gpgme_version_major" -gt "$req_major"; then
+        ok=yes
+    else 
+        if test "$gpgme_version_major" -eq "$req_major"; then
+            if test "$gpgme_version_minor" -gt "$req_minor"; then
+               ok=yes
+            else
+               if test "$gpgme_version_minor" -eq "$req_minor"; then
+                   if test "$gpgme_version_micro" -ge "$req_micro"; then
+                     ok=yes
+                   fi
+               fi
+            fi
+        fi
+    fi
+  fi
+  if test $ok = yes; then
+     # If we have a recent GPGME, we should also check that the
+     # API is compatible.
+     if test "$req_gpgme_api" -gt 0 ; then
+        tmp=`$GPGME_CONFIG --api-version 2>/dev/null || echo 0`
+        if test "$tmp" -gt 0 ; then
+           if test "$req_gpgme_api" -ne "$tmp" ; then
+             ok=no
+           fi
+        fi
+     fi
+  fi
+  if test $ok = yes; then
+    GPGME_GLIB_CFLAGS=`$GPGME_CONFIG --glib --cflags`
+    GPGME_GLIB_LIBS=`$GPGME_CONFIG --glib --libs`
+    AC_MSG_RESULT(yes)
+    ifelse([$2], , :, [$2])
+  else
+    GPGME_GLIB_CFLAGS=""
+    GPGME_GLIB_LIBS=""
+    AC_MSG_RESULT(no)
+    ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GPGME_GLIB_CFLAGS)
+  AC_SUBST(GPGME_GLIB_LIBS)
+])
+

Added: trunk/gpgme/w32-glib-io.c
===================================================================
--- trunk/gpgme/w32-glib-io.c	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/w32-glib-io.c	2005-11-17 18:45:14 UTC (rev 1136)
@@ -0,0 +1,502 @@
+/* w32-glib-io.c - W32 Glib I/O functions
+   Copyright (C) 2000 Werner Koch (dd9jn)
+   Copyright (C) 2001, 2002, 2004, 2005 g10 Code GmbH
+
+   This file is part of GPGME.
+ 
+   GPGME 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.
+   
+   GPGME 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 <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <windows.h>
+#include <io.h>
+
+#include "util.h"
+#include "priv-io.h"
+#include "sema.h"
+#include "debug.h"
+
+#include <glib.h>
+
+
+static GIOChannel *giochannel_table[256];
+
+static HANDLE handle_table[256];
+#define fd_to_handle(x) handle_table[x]
+
+static GIOChannel *
+find_channel (int fd, int create)
+{
+  if (fd < 0 || fd > (int) DIM (giochannel_table))
+    return NULL;
+
+  if (giochannel_table[fd] == NULL && create)
+    giochannel_table[fd] = g_io_channel_unix_new (fd);
+
+  return giochannel_table[fd];
+}
+
+
+/* Look up the giochannel for file descriptor FD.  */
+GIOChannel *
+gpgme_get_giochannel (int fd)
+{
+  return find_channel (fd, 0);
+}
+
+
+void
+_gpgme_io_subsystem_init (void)
+{
+}
+
+
+static struct
+{
+  void (*handler) (int,void*);
+  void *value;
+} notify_table[256];
+
+int
+_gpgme_io_read (int fd, void *buffer, size_t count)
+{
+  int saved_errno = 0;
+  gsize nread;
+  GIOChannel *chan;
+  GIOStatus status;
+
+  DEBUG2 ("fd %d: about to read %d bytes\n", fd, (int) count);
+
+  chan = find_channel (fd, 0);
+  if (!chan)
+    {
+      DEBUG1 ("fd %d: no channel registered\n", fd);
+      errno = EINVAL;
+      return -1;
+    }
+
+  status = g_io_channel_read_chars (chan, (gchar *) buffer,
+				    count, &nread, NULL);
+  if (status == G_IO_STATUS_EOF)
+    nread = 0;
+  else if (status != G_IO_STATUS_NORMAL)
+    {
+      nread = -1;
+      saved_errno = EIO;
+    }
+
+  DEBUG2 ("fd %d: got %d bytes\n", fd, nread);
+  if (nread > 0)
+    _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, nread, buffer);
+
+  errno = saved_errno;
+  return nread;
+}
+
+
+int
+_gpgme_io_write (int fd, const void *buffer, size_t count)
+{
+  int saved_errno = 0;
+  gsize nwritten;
+  GIOChannel *chan;
+  GIOStatus status;
+
+  DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int) count);
+  _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer);
+
+  chan = find_channel (fd, 0);
+  if (!chan)
+    {
+      DEBUG1 ("fd %d: no channel registered\n", fd);
+      errno = EINVAL;
+      return -1;
+    }
+
+  status = g_io_channel_write_chars (chan, (gchar *) buffer, count,
+				     &nwritten, NULL);
+  if (status != G_IO_STATUS_NORMAL)
+    {
+      nwritten = -1;
+      saved_errno = EIO;
+    }
+  DEBUG2 ("fd %d:          wrote %d bytes\n", fd, (int) nwritten);
+  errno = saved_errno;
+  return nwritten;
+}
+
+
+int
+_gpgme_io_pipe ( int filedes[2], int inherit_idx )
+{
+    HANDLE r, w;
+    SECURITY_ATTRIBUTES sec_attr;
+
+    memset (&sec_attr, 0, sizeof sec_attr );
+    sec_attr.nLength = sizeof sec_attr;
+    sec_attr.bInheritHandle = FALSE;
+    
+#define PIPEBUF_SIZE  4096
+    if (!CreatePipe ( &r, &w, &sec_attr, PIPEBUF_SIZE))
+        return -1;
+    /* Make one end inheritable. */
+    if ( inherit_idx == 0 ) {
+        HANDLE h;
+        if (!DuplicateHandle( GetCurrentProcess(), r,
+                              GetCurrentProcess(), &h, 0,
+                              TRUE, DUPLICATE_SAME_ACCESS ) ) {
+            DEBUG1 ("DuplicateHandle failed: ec=%d\n", (int)GetLastError());
+            CloseHandle (r);
+            CloseHandle (w);
+            return -1;
+        }
+        CloseHandle (r);
+        r = h;
+    }
+    else if ( inherit_idx == 1 ) {
+        HANDLE h;
+        if (!DuplicateHandle( GetCurrentProcess(), w,
+                              GetCurrentProcess(), &h, 0,
+                              TRUE, DUPLICATE_SAME_ACCESS ) ) {
+            DEBUG1 ("DuplicateHandle failed: ec=%d\n", (int)GetLastError());
+            CloseHandle (r);
+            CloseHandle (w);
+            return -1;
+        }
+        CloseHandle (w);
+        w = h;
+    }
+    filedes[0] = _open_osfhandle ((long) r, 0 );
+    if (filedes[0] == -1)
+      {
+	DEBUG1 ("_open_osfhandle failed: ec=%d\n", errno);
+	CloseHandle (r);
+	CloseHandle (w);
+	return -1;
+      }
+    filedes[1] = _open_osfhandle ((long) w, 0 );
+      {
+	DEBUG1 ("_open_osfhandle failed: ec=%d\n", errno);
+	_gpgme_io_close (filedes[0]);
+	CloseHandle (r);
+	CloseHandle (w);
+	return -1;
+      }
+
+    /* The fd that is not inherited will be used locally.  Create a
+       channel for it.  */
+    if (inherit_idx == 0)
+      {
+	if (!find_channel (filedes[1], 1))
+	  {
+	    DEBUG1 ("channel creation failed for %d\n", filedes[1]);
+	    _gpgme_io_close (filedes[0]);
+	    _gpgme_io_close (filedes[1]);
+	    CloseHandle (r);
+	    CloseHandle (w);
+	    return -1;
+	  }
+      }
+    else
+      {
+	if (!find_channel (filedes[0], 1))
+	  {
+	    DEBUG1 ("channel creation failed for %d\n", filedes[1]);
+	    _gpgme_io_close (filedes[0]);
+	    _gpgme_io_close (filedes[1]);
+	    CloseHandle (r);
+	    CloseHandle (w);
+	    return -1;
+	  }
+      }
+
+    /* Remember the handles for later.  */
+    handle_table[filedes[0]] = r;
+    handle_table[filedes[1]] = w;
+
+    DEBUG5 ("CreatePipe %p %p %d %d inherit=%d\n", r, w,
+                   filedes[0], filedes[1], inherit_idx );
+    return 0;
+}
+
+
+int
+_gpgme_io_close (int fd)
+{
+  GIOChannel *chan;
+
+  if (fd == -1)
+    return -1;
+
+  /* First call the notify handler.  */
+  DEBUG1 ("closing fd %d", fd);
+  if (fd >= 0 && fd < (int) DIM (notify_table))
+    {
+      if (notify_table[fd].handler)
+	{
+	  notify_table[fd].handler (fd, notify_table[fd].value);
+	  notify_table[fd].handler = NULL;
+	  notify_table[fd].value = NULL;
+        }
+    }
+  /* Then do the close.  */    
+  chan = find_channel (fd, 0);
+  if (chan)
+    {
+      g_io_channel_shutdown (chan, 1, NULL);
+      g_io_channel_unref (chan);
+      giochannel_table[fd] = NULL;
+      return 0;
+    }
+  else
+    return close (fd);
+}
+
+
+int
+_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+{
+  assert (fd != -1);
+
+  if (fd < 0 || fd >= (int) DIM (notify_table))
+    return -1;
+  DEBUG1 ("set notification for fd %d", fd);
+  notify_table[fd].handler = handler;
+  notify_table[fd].value = value;
+  return 0;
+}
+
+
+int
+_gpgme_io_set_nonblocking (int fd)
+{
+  GIOChannel *chan;
+  GIOStatus status;
+
+  chan = find_channel (fd, 0);
+  if (!chan)
+    {
+      errno = EIO;
+      return -1;
+    }
+
+  status = g_io_channel_set_flags (chan,
+				   g_io_channel_get_flags (chan) |
+				   G_IO_FLAG_NONBLOCK, NULL);
+  if (status != G_IO_STATUS_NORMAL)
+    {
+      errno = EIO;
+      return -1;
+    }
+
+  return 0;
+}
+
+
+static char *
+build_commandline ( char **argv )
+{
+  int i, n = 0;
+  char *buf, *p;
+  
+  /* FIXME: we have to quote some things because under Windows the
+   * program parses the commandline and does some unquoting.  For now
+   * we only do very basic quoting to the first argument because this
+   * one often contains a space (e.g. C:\\Program Files\GNU\GnuPG\gpg.exe) 
+   * and we would produce an invalid line in that case.  */
+  for (i=0; argv[i]; i++)
+    n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */
+  buf = p = malloc (n);
+  if ( !buf )
+    return NULL;
+  *buf = 0;
+  if ( argv[0] )
+    {
+      if (strpbrk (argv[0], " \t"))
+        p = stpcpy (stpcpy (stpcpy (p, "\""), argv[0]), "\"");
+      else
+        p = stpcpy (p, argv[0]);
+      for (i = 1; argv[i]; i++)
+        {
+          if (!*argv[i])
+            p = stpcpy (p, " \"\"");
+          else
+            p = stpcpy (stpcpy (p, " "), argv[i]);
+        }
+    }
+  
+  return buf;
+}
+
+
+int
+_gpgme_io_spawn ( const char *path, char **argv,
+                  struct spawn_fd_item_s *fd_child_list,
+                  struct spawn_fd_item_s *fd_parent_list )
+{
+    SECURITY_ATTRIBUTES sec_attr;
+    PROCESS_INFORMATION pi = {
+        NULL,      /* returns process handle */
+        0,         /* returns primary thread handle */
+        0,         /* returns pid */
+        0         /* returns tid */
+    };
+    STARTUPINFO si;
+    char *envblock = NULL;
+    int cr_flags = CREATE_DEFAULT_ERROR_MODE
+                 | GetPriorityClass (GetCurrentProcess ());
+    int i;
+    char *arg_string;
+    int duped_stdin = 0;
+    int duped_stderr = 0;
+    HANDLE hnul = INVALID_HANDLE_VALUE;
+    /* FIXME.  */
+    int debug_me = 0;
+
+    memset (&sec_attr, 0, sizeof sec_attr );
+    sec_attr.nLength = sizeof sec_attr;
+    sec_attr.bInheritHandle = FALSE;
+
+    arg_string = build_commandline ( argv );
+    if (!arg_string )
+        return -1; 
+
+    memset (&si, 0, sizeof si);
+    si.cb = sizeof (si);
+    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+    si.wShowWindow = debug_me? SW_SHOW : SW_HIDE;
+    si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+    si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+    si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
+
+    for (i=0; fd_child_list[i].fd != -1; i++ ) {
+        if (fd_child_list[i].dup_to == 0 ) {
+            si.hStdInput = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stdin", fd_child_list[i].fd );
+            duped_stdin=1;
+        }
+        else if (fd_child_list[i].dup_to == 1 ) {
+            si.hStdOutput = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stdout", fd_child_list[i].fd );
+        }
+        else if (fd_child_list[i].dup_to == 2 ) {
+            si.hStdError = fd_to_handle (fd_child_list[i].fd);
+            DEBUG1 ("using %d for stderr", fd_child_list[i].fd );
+            duped_stderr = 1;
+        }
+    }
+
+    if( !duped_stdin || !duped_stderr ) {
+        SECURITY_ATTRIBUTES sa;
+
+        memset (&sa, 0, sizeof sa );
+        sa.nLength = sizeof sa;
+        sa.bInheritHandle = TRUE;
+        hnul = CreateFile ( "nul",
+                            GENERIC_READ|GENERIC_WRITE,
+                            FILE_SHARE_READ|FILE_SHARE_WRITE,
+                            &sa,
+                            OPEN_EXISTING,
+                            FILE_ATTRIBUTE_NORMAL,
+                            NULL );
+        if ( hnul == INVALID_HANDLE_VALUE ) {
+            DEBUG1 ("can't open `nul': ec=%d\n", (int)GetLastError ());
+            free (arg_string);
+            return -1;
+        }
+        /* Make sure that the process has a connected stdin */
+        if ( !duped_stdin ) {
+            si.hStdInput = hnul;
+            DEBUG1 ("using %d for dummy stdin", (int)hnul );
+        }
+        /* We normally don't want all the normal output */
+        if ( !duped_stderr ) {
+            si.hStdError = hnul;
+            DEBUG1 ("using %d for dummy stderr", (int)hnul );
+        }
+    }
+
+    DEBUG2 ("CreateProcess, path=`%s' args=`%s'", path, arg_string);
+    cr_flags |= CREATE_SUSPENDED; 
+    if ( !CreateProcessA (path,
+                          arg_string,
+                          &sec_attr,     /* process security attributes */
+                          &sec_attr,     /* thread security attributes */
+                          TRUE,          /* inherit handles */
+                          cr_flags,      /* creation flags */
+                          envblock,      /* environment */
+                          NULL,          /* use current drive/directory */
+                          &si,           /* startup information */
+                          &pi            /* returns process information */
+        ) ) {
+        DEBUG1 ("CreateProcess failed: ec=%d\n", (int) GetLastError ());
+        free (arg_string);
+        return -1;
+    }
+
+    /* Close the /dev/nul handle if used. */
+    if (hnul != INVALID_HANDLE_VALUE ) {
+        if ( !CloseHandle ( hnul ) )
+            DEBUG1 ("CloseHandle(hnul) failed: ec=%d\n", (int)GetLastError());
+    }
+
+    /* Close the other ends of the pipes. */
+    for (i = 0; fd_parent_list[i].fd != -1; i++)
+      _gpgme_io_close (fd_parent_list[i].fd);
+
+    DEBUG4 ("CreateProcess ready\n"
+            "-   hProcess=%p  hThread=%p\n"
+            "-   dwProcessID=%d dwThreadId=%d\n",
+            pi.hProcess, pi.hThread, 
+            (int) pi.dwProcessId, (int) pi.dwThreadId);
+
+    if ( ResumeThread ( pi.hThread ) < 0 ) {
+        DEBUG1 ("ResumeThread failed: ec=%d\n", (int)GetLastError ());
+    }
+
+    if ( !CloseHandle (pi.hThread) ) { 
+        DEBUG1 ("CloseHandle of thread failed: ec=%d\n",
+                 (int)GetLastError ());
+    }
+
+    return 0;
+}
+
+
+/*
+ * Select on the list of fds.
+ * Returns: -1 = error
+ *           0 = timeout or nothing to select
+ *          >0 = number of signaled fds
+ */
+int
+_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
+{
+  assert (!"ARGH!  The user of this library MUST define io callbacks!");
+  errno = EINVAL;
+  return -1;
+}

Modified: trunk/gpgme/w32-io.c
===================================================================
--- trunk/gpgme/w32-io.c	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/gpgme/w32-io.c	2005-11-17 18:45:14 UTC (rev 1136)
@@ -1091,4 +1091,13 @@
   
 }
 
+
+/* The following interface is only useful for GPGME Glib.  */
 
+/* Look up the giochannel for file descriptor FD.  */
+void *
+gpgme_get_giochannel (int fd)
+{
+  return NULL;
+}
+

Modified: trunk/m4/ChangeLog
===================================================================
--- trunk/m4/ChangeLog	2005-11-17 16:12:27 UTC (rev 1135)
+++ trunk/m4/ChangeLog	2005-11-17 18:45:14 UTC (rev 1136)
@@ -1,3 +1,7 @@
+2005-11-17  Marcus Brinkmann  <marcus at g10code.de>
+
+	* glib-2.0.m4: New file.
+
 2004-12-28  Werner Koch  <wk at g10code.com>
 
 	* pth.m4: Changed quoting for use with automake 1.9.




More information about the Gnupg-commits mailing list