From dbcce0df8f265a5e158c8e489be3dec6e704fd73 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 25 Jan 2010 16:04:27 +0000 Subject: [PATCH] Allow the native W32 version to properly work with sockets. --- ChangeLog | 4 ++ autogen.sh | 2 + doc/gpgme.texi | 2 +- src/ChangeLog | 14 ++++++- src/version.c | 17 +++------ src/w32-io.c | 101 ++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 104 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78880e0f..1d7523be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-22 Werner Koch + + * autogen.sh (--build-w32): Add --with-libassuan-prefix. + 2010-01-11 Marcus Brinkmann Release 1.3.0. diff --git a/autogen.sh b/autogen.sh index 60e52d74..e328f8e2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -81,6 +81,7 @@ if test "$1" = "--build-w32"; then ./configure --enable-maintainer-mode --prefix=${w32root} \ --host=i586-mingw32msvc --build=${build} \ --with-gpg-error-prefix=${w32root} \ + --with-libassuan-prefix=${w32root} \ --enable-shared --enable-static --enable-w32-glib \ PKG_CONFIG_LIBDIR="$w32root/lib/pkgconfig" @@ -162,3 +163,4 @@ $AUTOCONF${FORCE} echo "You may now run: ./configure --enable-maintainer-mode && make " + diff --git a/doc/gpgme.texi b/doc/gpgme.texi index e530e168..cbbe4938 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3746,7 +3746,7 @@ useful in a server application (where passphrases are not required anyway). Note that old @code{gpg} engines (before version 2.0.15) do not support -this comamnd and will silently ignore it. +this command and will silently ignore it. @end deftypefun @deftypefun gpgme_error_t gpgme_op_passwd_start @ diff --git a/src/ChangeLog b/src/ChangeLog index 3292f4ca..a90259c9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2010-01-25 Werner Koch + + * w32-io.c (_gpgme_io_connect): Fix return code check to make it work. + + * version.c (do_subsystem_inits): Remove superfluous second + WSAStartup. + +2010-01-22 Werner Koch + + * w32-io.c (writer): Try to use send first. + (reader): Try to use recv first. + 2010-01-08 Werner Koch * engine-gpg.c (gpg_passwd): New. @@ -727,7 +739,7 @@ * opassuan.c, dirinfo.c, engine-assuan.c: New. * Makefile.am: Add them. - * engine-backend.h: Add _gpgme_engine_ops_assuan. + * engine-backend.h: Add _gpgme_engine_ops_assuan. (struct engine_ops): Add field OPASSUAN_TRANSACT. Update all engine intializers. * Makefile.am (gpgsm_components): Add engine-assuan.c. diff --git a/src/version.c b/src/version.c index 8ba71ac3..e02037e9 100644 --- a/src/version.c +++ b/src/version.c @@ -65,24 +65,17 @@ do_subsystem_inits (void) return; #ifdef HAVE_W32_SYSTEM - { - WSADATA wsadat; - - WSAStartup (0x202, &wsadat); - } -#endif - - _gpgme_sema_subsystem_init (); - _gpgme_debug_subsystem_init (); - _gpgme_io_subsystem_init (); -#if defined(HAVE_W32_SYSTEM) && defined(HAVE_ASSUAN_H) /* We need to make sure that the sockets are initialized. */ { WSADATA wsadat; WSAStartup (0x202, &wsadat); } -#endif /*HAVE_W32_SYSTEM && HAVE_ASSUAN_H*/ +#endif + + _gpgme_sema_subsystem_init (); + _gpgme_debug_subsystem_init (); + _gpgme_io_subsystem_init (); done = 1; } diff --git a/src/w32-io.c b/src/w32-io.c index d1c48084..762d617f 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -49,6 +49,7 @@ #define handle_to_fd(a) ((int)(a)) #define pid_to_handle(a) ((HANDLE)(a)) #define handle_to_pid(a) ((int)(a)) +#define handle_to_socket(a) ((unsigned int)(a)) #define READBUF_SIZE 4096 #define WRITEBUF_SIZE 4096 @@ -180,6 +181,7 @@ reader (void *arg) struct reader_context_s *ctx = arg; int nbytes; DWORD nread; + int try_recv = 1; TRACE_BEG1 (DEBUG_SYSIO, "gpgme:reader", ctx->file_hd, "thread=%p", ctx->thread_hd); @@ -211,21 +213,52 @@ reader (void *arg) UNLOCK (ctx->mutex); TRACE_LOG1 ("reading %d bytes", nbytes); - if (!ReadFile (ctx->file_hd, - ctx->buffer + ctx->writepos, nbytes, &nread, NULL)) - { - ctx->error_code = (int) GetLastError (); - if (ctx->error_code == ERROR_BROKEN_PIPE) - { - ctx->eof = 1; - TRACE_LOG ("got EOF (broken pipe)"); + + if (try_recv) + { + int n; + + n = recv (handle_to_socket (ctx->file_hd), + ctx->buffer + ctx->writepos, nbytes, 0); + if (n < 0 && WSAGetLastError () == WSAENOTSOCK) + try_recv = 0; + else if (n < 0) + { + ctx->error_code = (int) WSAGetLastError (); + if (ctx->error_code == ERROR_BROKEN_PIPE) + { + ctx->eof = 1; + TRACE_LOG ("got EOF (broken connection)"); + } + else + { + ctx->error = 1; + TRACE_LOG1 ("recv error: ec=%d", ctx->error_code); + } + break; } - else - { - ctx->error = 1; - TRACE_LOG1 ("read error: ec=%d", ctx->error_code); + else + nread = n; + + } + if (!try_recv) + { + if (!ReadFile (ctx->file_hd, + ctx->buffer + ctx->writepos, nbytes, &nread, NULL)) + { + ctx->error_code = (int) GetLastError (); + if (ctx->error_code == ERROR_BROKEN_PIPE) + { + ctx->eof = 1; + TRACE_LOG ("got EOF (broken pipe)"); + } + else + { + ctx->error = 1; + TRACE_LOG1 ("read error: ec=%d", ctx->error_code); + } + break; } - break; } if (!nread) { @@ -507,6 +540,7 @@ writer (void *arg) { struct writer_context_s *ctx = arg; DWORD nwritten; + int try_send = 1; TRACE_BEG1 (DEBUG_SYSIO, "gpgme:writer", ctx->file_hd, "thread=%p", ctx->thread_hd); @@ -541,14 +575,37 @@ writer (void *arg) /* Note that CTX->nbytes is not zero at this point, because _gpgme_io_write always writes at least 1 byte before waking us up, unless CTX->stop_me is true, which we catch above. */ - if (!WriteFile (ctx->file_hd, ctx->buffer, - ctx->nbytes, &nwritten, NULL)) - { - ctx->error_code = (int) GetLastError (); - ctx->error = 1; - TRACE_LOG1 ("write error: ec=%d", ctx->error_code); - break; - } + if (try_send) + { + /* We need to try send first because a socket handle can't + be used with WriteFile. */ + int n; + + n = send (handle_to_socket (ctx->file_hd), + ctx->buffer, ctx->nbytes, 0); + if (n < 0 && WSAGetLastError () == WSAENOTSOCK) + try_send = 0; + else if (n < 0) + { + ctx->error_code = (int) WSAGetLastError (); + ctx->error = 1; + TRACE_LOG1 ("send error: ec=%d", ctx->error_code); + break; + } + else + nwritten = n; + } + if (!try_send) + { + if (!WriteFile (ctx->file_hd, ctx->buffer, + ctx->nbytes, &nwritten, NULL)) + { + ctx->error_code = (int) GetLastError (); + ctx->error = 1; + TRACE_LOG1 ("write error: ec=%d", ctx->error_code); + break; + } + } TRACE_LOG1 ("wrote %d bytes", (int) nwritten); LOCK (ctx->mutex); @@ -1563,7 +1620,7 @@ _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) "addr=%p, addrlen=%i", addr, addrlen); res = connect (fd, addr, addrlen); - if (!res) + if (res) { errno = wsa2errno (WSAGetLastError ()); return TRACE_SYSRES (-1);