From 2259df1be22e700346620e5160e2e70396cf1ced Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 17 Nov 2005 18:45:14 +0000 Subject: [PATCH] 2005-11-17 Marcus Brinkmann * configure.ac: Add support for --enable-w32-glib (disabled by default). Invoke AM_PATH_GLIB_2_0. gpgme/ 2005-11-17 Marcus Brinkmann * 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 * glib-2.0.m4: New file. --- trunk/ChangeLog | 5 + trunk/configure.ac | 6 + trunk/gpgme/ChangeLog | 17 ++ trunk/gpgme/Makefile.am | 37 ++- trunk/gpgme/gpgme-config.in | 25 +- trunk/gpgme/gpgme.def | 2 + trunk/gpgme/gpgme.m4 | 69 +++++ trunk/gpgme/w32-glib-io.c | 502 ++++++++++++++++++++++++++++++++++++ trunk/gpgme/w32-io.c | 9 + trunk/m4/ChangeLog | 4 + 10 files changed, 665 insertions(+), 11 deletions(-) create mode 100644 trunk/gpgme/w32-glib-io.c diff --git a/trunk/ChangeLog b/trunk/ChangeLog index 661117a..459dfbb 100644 --- a/trunk/ChangeLog +++ b/trunk/ChangeLog @@ -1,3 +1,8 @@ +2005-11-17 Marcus Brinkmann + + * configure.ac: Add support for --enable-w32-glib (disabled by + default). Invoke AM_PATH_GLIB_2_0. + 2005-11-15 Werner Koch * configure.ac: Create BUILD_FILEVERSION from SVN Revision. diff --git a/trunk/configure.ac b/trunk/configure.ac index cd16596..b62ad50 100644 --- a/trunk/configure.ac +++ b/trunk/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/trunk/gpgme/ChangeLog b/trunk/gpgme/ChangeLog index 0f2c67b..4414c82 100644 --- a/trunk/gpgme/ChangeLog +++ b/trunk/gpgme/ChangeLog @@ -1,3 +1,20 @@ +2005-11-17 Marcus Brinkmann + + * 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 * priv-io.h (_gpgme_io_waitpid, _gpgme_io_kill): Removed. diff --git a/trunk/gpgme/Makefile.am b/trunk/gpgme/Makefile.am index 7ecae10..404ebd9 100644 --- a/trunk/gpgme/Makefile.am +++ b/trunk/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/trunk/gpgme/gpgme-config.in b/trunk/gpgme/gpgme-config.in index 81e599d..5310b53 100644 --- a/trunk/gpgme/gpgme-config.in +++ b/trunk/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/trunk/gpgme/gpgme.def b/trunk/gpgme/gpgme.def index 43ead9f..f4aa1b5 100644 --- a/trunk/gpgme/gpgme.def +++ b/trunk/gpgme/gpgme.def @@ -152,5 +152,7 @@ EXPORTS gpgme_sig_notation_get @119 gpgme_free @120 + + gpgme_get_giochannel @121 ; END diff --git a/trunk/gpgme/gpgme.m4 b/trunk/gpgme/gpgme.m4 index 10ee13f..44bf43c 100644 --- a/trunk/gpgme/gpgme.m4 +++ b/trunk/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/trunk/gpgme/w32-glib-io.c b/trunk/gpgme/w32-glib-io.c new file mode 100644 index 0000000..0867b04 --- /dev/null +++ b/trunk/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 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "priv-io.h" +#include "sema.h" +#include "debug.h" + +#include + + +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/trunk/gpgme/w32-io.c b/trunk/gpgme/w32-io.c index 7ad10ec..42c3132 100644 --- a/trunk/gpgme/w32-io.c +++ b/trunk/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/trunk/m4/ChangeLog b/trunk/m4/ChangeLog index aa94780..a12bf68 100644 --- a/trunk/m4/ChangeLog +++ b/trunk/m4/ChangeLog @@ -1,3 +1,7 @@ +2005-11-17 Marcus Brinkmann + + * glib-2.0.m4: New file. + 2004-12-28 Werner Koch * pth.m4: Changed quoting for use with automake 1.9. -- 2.26.2