diff options
| author | Marcus Brinkmann <[email protected]> | 2005-11-17 18:45:14 +0000 | 
|---|---|---|
| committer | Marcus Brinkmann <[email protected]> | 2005-11-17 18:45:14 +0000 | 
| commit | d11318a3198e88f7cbb7e4b4bada4b96984be374 (patch) | |
| tree | 2007bbb64d3be4d1f18435579adb0f40181de5a8 | |
| parent | 2005-11-17 Marcus Brinkmann <[email protected]> (diff) | |
| download | gpgme-d11318a3198e88f7cbb7e4b4bada4b96984be374.tar.gz gpgme-d11318a3198e88f7cbb7e4b4bada4b96984be374.zip  | |
2005-11-17  Marcus Brinkmann  <[email protected]>
	* configure.ac: Add support for --enable-w32-glib (disabled by
	default).  Invoke AM_PATH_GLIB_2_0.
gpgme/
2005-11-17  Marcus Brinkmann  <[email protected]>
	* 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  <[email protected]>
	* glib-2.0.m4: New file.
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | gpgme/ChangeLog | 17 | ||||
| -rw-r--r-- | gpgme/Makefile.am | 37 | ||||
| -rw-r--r-- | gpgme/gpgme-config.in | 25 | ||||
| -rw-r--r-- | gpgme/gpgme.def | 2 | ||||
| -rw-r--r-- | gpgme/gpgme.m4 | 69 | ||||
| -rw-r--r-- | gpgme/w32-glib-io.c | 502 | ||||
| -rw-r--r-- | gpgme/w32-io.c | 9 | ||||
| -rw-r--r-- | m4/ChangeLog | 4 | 
10 files changed, 665 insertions, 11 deletions
@@ -1,3 +1,8 @@ +2005-11-17  Marcus Brinkmann  <[email protected]> + +	* configure.ac: Add support for --enable-w32-glib (disabled by +	default).  Invoke AM_PATH_GLIB_2_0. +  2005-11-15  Werner Koch  <[email protected]>  	* configure.ac: Create BUILD_FILEVERSION from SVN Revision. diff --git a/configure.ac b/configure.ac index cd165961..b62ad50f 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,12 @@ if test "$have_w32_system" = yes; then  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") diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 0f2c67ba..4414c82a 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,22 @@  2005-11-17  Marcus Brinkmann  <[email protected]> +	* 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  <[email protected]> +  	* 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. diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 7ecae108..404ebd91 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -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 @@ else  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 @@ assuan_libobjs =  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,9 +92,14 @@ libgpgme_real_la_SOURCES =						\  	$(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_DEPENDENCIES = libgpgme-real.la $(assuan_libobjs) \  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 diff --git a/gpgme/gpgme-config.in b/gpgme/gpgme-config.in index 81e599d9..5310b53b 100644 --- a/gpgme/gpgme-config.in +++ b/gpgme/gpgme-config.in @@ -25,9 +25,10 @@ thread_modules=""  libs_pth="@PTH_LDFLAGS@ @PTH_LIBS@"  cflags_pth="@PTH_CFLAGS@" -@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 @@ while test $# -gt 0; do          --exec-prefix)  	    output="$output $exec_prefix"  	    ;; +	--glib) +	    with_glib=yes +	    ;;          --version)              echo "@VERSION@"  	    exit 0 @@ -95,6 +99,9 @@ while test $# -gt 0; do  		    ;;  	    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 @@ while test $# -gt 0; do  	            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 diff --git a/gpgme/gpgme.def b/gpgme/gpgme.def index 43ead9f5..f4aa1b5a 100644 --- a/gpgme/gpgme.def +++ b/gpgme/gpgme.def @@ -152,5 +152,7 @@ EXPORTS      gpgme_sig_notation_get		  @119      gpgme_free				  @120 + +    gpgme_get_giochannel		  @121  ; END diff --git a/gpgme/gpgme.m4 b/gpgme/gpgme.m4 index 10ee13f9..44bf43cb 100644 --- a/gpgme/gpgme.m4 +++ b/gpgme/gpgme.m4 @@ -236,3 +236,72 @@ AC_DEFUN([AM_PATH_GPGME_PTHREAD],    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) +]) + diff --git a/gpgme/w32-glib-io.c b/gpgme/w32-glib-io.c new file mode 100644 index 00000000..0867b040 --- /dev/null +++ b/gpgme/w32-glib-io.c @@ -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; +} diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 7ad10ecb..42c3132d 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -1091,4 +1091,13 @@ _gpgme_io_subsystem_init (void)  } + +/* 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; +} diff --git a/m4/ChangeLog b/m4/ChangeLog index aa94780c..a12bf68b 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2005-11-17  Marcus Brinkmann  <[email protected]> + +	* glib-2.0.m4: New file. +  2004-12-28  Werner Koch  <[email protected]>  	* pth.m4: Changed quoting for use with automake 1.9.  | 
