[svn] gpgme - r1478 - trunk/src
svn author marcus
cvs at cvs.gnupg.org
Thu Jun 10 15:49:20 CEST 2010
Author: marcus
Date: 2010-06-10 15:49:19 +0200 (Thu, 10 Jun 2010)
New Revision: 1478
Modified:
trunk/src/ChangeLog
trunk/src/debug.h
trunk/src/w32-io.c
Log:
2010-06-10 Marcus Brinkmann <marcus at g10code.de>
* debug.h (TRACE_SUC6): New macro.
* w32-io.c (MAX_SLAFD): New macro.
(fd_table): New static variable.
(new_fd, release_fd): New functions.
(fd_to_handle, handle_to_fd, handle_to_socket): Remove macros.
(MAX_READERS, MAX_WRITERS): Increase to 64.
(notify_table): Increase to MAX_SLAFD.
(struct reader_context_s, struct writer_context_s): Add member
file_sock.
(reader, writer): Use file_hd vs file_sock to decide if socket
operations to use. Remove auto-detect mode.
(create_reader, create_writer): Set file_sock. Unblock pending
thread only if this is a pipe fd.
(_gpgme_io_pipe): Allocate fds from table and return slot indices
instead of windows handles. This allows to properly handle RVIDs.
(_gpgme_io_close): Handle dup'ed file descriptors.
(build_commandline) [HAVE_W32_SYSTEM]: Use RVID from fd table now.
(_gpgme_io_spawn): Use fd table now.
(_gpgme_io_fd2str): Use RVID from fd table now.
(_gpgme_io_dup): Implement using fd table.
(_gpgme_io_socket): Allocate fds from table.
(_gpgme_io_connect): Use fd from table.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2010-06-10 13:41:12 UTC (rev 1477)
+++ trunk/src/ChangeLog 2010-06-10 13:49:19 UTC (rev 1478)
@@ -1,3 +1,30 @@
+2010-06-10 Marcus Brinkmann <marcus at g10code.de>
+
+ * debug.h (TRACE_SUC6): New macro.
+ * w32-io.c (MAX_SLAFD): New macro.
+ (fd_table): New static variable.
+ (new_fd, release_fd): New functions.
+ (fd_to_handle, handle_to_fd, handle_to_socket): Remove macros.
+ (MAX_READERS, MAX_WRITERS): Increase to 64.
+ (notify_table): Increase to MAX_SLAFD.
+ (struct reader_context_s, struct writer_context_s): Add member
+ file_sock.
+ (reader, writer): Use file_hd vs file_sock to decide if socket
+ operations to use. Remove auto-detect mode.
+ (create_reader, create_writer): Set file_sock. Unblock pending
+ thread only if this is a pipe fd.
+ (_gpgme_io_pipe): Allocate fds from table and return slot indices
+ instead of windows handles. This allows to properly handle RVIDs.
+ (_gpgme_io_close): Handle dup'ed file descriptors.
+ (build_commandline) [HAVE_W32_SYSTEM]: Use RVID from fd table now.
+ (_gpgme_io_spawn): Use fd table now.
+ (_gpgme_io_fd2str): Use RVID from fd table now.
+ (_gpgme_io_dup): Implement using fd table.
+ (_gpgme_io_socket): Allocate fds from table.
+ (_gpgme_io_connect): Use fd from table.
+
+ * w32-glib-io.c (find_channel): Check that the slot is used.
+
2010-06-09 Marcus Brinkmann <marcus at g10code.de>
* w32-io.c [HAVE_W32CE_SYSTEM]: Include assuan.h and winioctl.h.
Modified: trunk/src/debug.h
===================================================================
--- trunk/src/debug.h 2010-06-10 13:41:12 UTC (rev 1477)
+++ trunk/src/debug.h 2010-06-10 13:49:19 UTC (rev 1478)
@@ -204,6 +204,10 @@
_gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
_gpgme_trace_func, arg1, arg2, arg3, arg4, arg5), \
_gpgme_debug_frame_end (), 0
+#define TRACE_SUC6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
+ _gpgme_debug (_gpgme_trace_level, "%s: leave: " fmt "\n", \
+ _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5, arg6), \
+ _gpgme_debug_frame_end (), 0
#define TRACE_LOG(fmt) \
_gpgme_debug (_gpgme_trace_level, "%s: check: %s=%p, " fmt "\n", \
Modified: trunk/src/w32-io.c
===================================================================
--- trunk/src/w32-io.c 2010-06-10 13:41:12 UTC (rev 1477)
+++ trunk/src/w32-io.c 2010-06-10 13:49:19 UTC (rev 1478)
@@ -46,22 +46,87 @@
#include "debug.h"
-/* We assume that a HANDLE can be represented by an int which should
- be true for all i386 systems (HANDLE is defined as void *) and
- these are the only systems for which Windows is available. Further
- we assume that -1 denotes an invalid handle. */
+/* FIXME: Optimize. */
+#define MAX_SLAFD 512
-#define fd_to_handle(a) ((HANDLE)(a))
-#define handle_to_fd(a) ((int)(a))
+static struct
+{
+ int used;
+
+ /* If this is not INVALID_HANDLE_VALUE, then it's a handle. */
+ HANDLE handle;
+
+ /* If this is not INVALID_SOCKET, then it's a Windows socket. */
+ int socket;
+
+ /* If this is not 0, then it's a rendezvous ID for the pipe server. */
+ int rvid;
+
+ /* DUP_FROM is -1 if this file descriptor was allocated by pipe or
+ socket functions. Only then should the handle or socket be
+ destroyed when this FD is closed. This, together with the fact
+ that dup'ed file descriptors are closed before the file
+ descriptors from which they are dup'ed are closed, ensures that
+ the handle or socket is always valid, and shared among all file
+ descriptors refering to the same underlying object.
+
+ The logic behind this is that there is only one reason for us to
+ dup file descriptors anyway: to allow simpler book-keeping of
+ file descriptors shared between GPGME and libassuan, which both
+ want to close something. Using the same handle for these
+ duplicates works just fine. */
+ int dup_from;
+} fd_table[MAX_SLAFD];
+
+
+/* Returns the FD or -1 on resource limit. */
+int
+new_fd (void)
+{
+ int idx;
+
+ for (idx = 0; idx < MAX_SLAFD; idx++)
+ if (! fd_table[idx].used)
+ break;
+
+ if (idx == MAX_SLAFD)
+ {
+ gpg_err_set_errno (EIO);
+ return -1;
+ }
+
+ fd_table[idx].used = 1;
+ fd_table[idx].handle = INVALID_HANDLE_VALUE;
+ fd_table[idx].socket = INVALID_SOCKET;
+ fd_table[idx].rvid = 0;
+ fd_table[idx].dup_from = -1;
+
+ return idx;
+}
+
+
+void
+release_fd (int fd)
+{
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ return;
+
+ fd_table[fd].used = 0;
+ fd_table[fd].handle = INVALID_HANDLE_VALUE;
+ fd_table[fd].socket = INVALID_SOCKET;
+ fd_table[fd].rvid = 0;
+ fd_table[fd].dup_from = -1;
+}
+
+
#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
#define PIPEBUF_SIZE 4096
-#define MAX_READERS 40
-#define MAX_WRITERS 40
+#define MAX_READERS 64
+#define MAX_WRITERS 64
static struct
{
@@ -69,13 +134,14 @@
int fd;
_gpgme_close_notify_handler_t handler;
void *value;
-} notify_table[256];
+} notify_table[MAX_SLAFD];
DEFINE_STATIC_LOCK (notify_table_lock);
struct reader_context_s
{
HANDLE file_hd;
+ int file_sock;
HANDLE thread_hd;
int refcount;
@@ -110,6 +176,7 @@
struct writer_context_s
{
HANDLE file_hd;
+ int file_sock;
HANDLE thread_hd;
int refcount;
@@ -229,7 +296,10 @@
TRACE_BEG1 (DEBUG_SYSIO, "gpgme:reader", ctx->file_hd,
"thread=%p", ctx->thread_hd);
- sock = is_socket (ctx->file_hd);
+ if (ctx->file_hd != INVALID_HANDLE_VALUE)
+ sock = 0;
+ else
+ sock = 1;
for (;;)
{
@@ -260,25 +330,13 @@
TRACE_LOG2 ("%s %d bytes", sock? "receiving":"reading", nbytes);
- if (sock == -1 || sock == 1)
+ if (sock)
{
int n;
- n = recv (handle_to_socket (ctx->file_hd),
- ctx->buffer + ctx->writepos, nbytes, 0);
+ n = recv (ctx->file_sock, ctx->buffer + ctx->writepos, nbytes, 0);
if (n < 0)
{
- if (sock == -1)
- {
- if (WSAGetLastError () == WSAENOTSOCK)
- {
- sock = 0;
- goto try_readfile;
- }
- else
- sock = 1;
- }
-
ctx->error_code = (int) WSAGetLastError ();
if (ctx->error_code == ERROR_BROKEN_PIPE)
{
@@ -296,7 +354,6 @@
}
else
{
- try_readfile:
if (!ReadFile (ctx->file_hd,
ctx->buffer + ctx->writepos, nbytes, &nread, NULL))
{
@@ -348,7 +405,7 @@
static struct reader_context_s *
-create_reader (HANDLE fd)
+create_reader (int fd)
{
struct reader_context_s *ctx;
SECURITY_ATTRIBUTES sec_attr;
@@ -367,7 +424,14 @@
return NULL;
}
- ctx->file_hd = fd;
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ {
+ TRACE_SYSERR (EIO);
+ return NULL;
+ }
+ ctx->file_hd = fd_table[fd].handle;
+ ctx->file_sock = fd_table[fd].socket;
+
ctx->refcount = 1;
ctx->have_data_ev = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
if (ctx->have_data_ev)
@@ -440,11 +504,14 @@
reading. Then we need to unblock the reader in the pipe driver
to make our reader thread notice that we want it to go away. */
- if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK,
+ if (ctx->file_hd != INVALID_HANDLE_VALUE)
+ {
+ if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK,
NULL, 0, NULL, 0, NULL, NULL))
- {
- TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
- "unblock control call failed for thread %p", ctx->thread_hd);
+ {
+ TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
+ "unblock control call failed for thread %p", ctx->thread_hd);
+ }
}
#endif
@@ -491,7 +558,7 @@
if (i != reader_table_size)
{
- rd = create_reader (fd_to_handle (fd));
+ rd = create_reader (fd);
if (rd)
{
reader_table[i].fd = fd;
@@ -614,7 +681,10 @@
TRACE_BEG1 (DEBUG_SYSIO, "gpgme:writer", ctx->file_hd,
"thread=%p", ctx->thread_hd);
- sock = is_socket (ctx->file_hd);
+ if (ctx->file_hd != INVALID_HANDLE_VALUE)
+ sock = 0;
+ else
+ sock = 1;
for (;;)
{
@@ -648,27 +718,15 @@
/* 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 (sock == -1 || sock == 1)
+ if (sock)
{
/* 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);
+ n = send (ctx->file_sock, ctx->buffer, ctx->nbytes, 0);
if (n < 0)
{
- if (sock == -1)
- {
- if (WSAGetLastError () == WSAENOTSOCK)
- {
- sock = 0;
- goto try_writefile;
- }
- else
- sock = 1;
- }
-
ctx->error_code = (int) WSAGetLastError ();
ctx->error = 1;
TRACE_LOG1 ("send error: ec=%d", ctx->error_code);
@@ -678,7 +736,6 @@
}
else
{
- try_writefile:
if (!WriteFile (ctx->file_hd, ctx->buffer,
ctx->nbytes, &nwritten, NULL))
{
@@ -711,7 +768,7 @@
static struct writer_context_s *
-create_writer (HANDLE fd)
+create_writer (int fd)
{
struct writer_context_s *ctx;
SECURITY_ATTRIBUTES sec_attr;
@@ -730,7 +787,14 @@
return NULL;
}
- ctx->file_hd = fd;
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ {
+ TRACE_SYSERR (EIO);
+ return NULL;
+ }
+ ctx->file_hd = fd_table[fd].handle;
+ ctx->file_sock = fd_table[fd].socket;
+
ctx->refcount = 1;
ctx->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
if (ctx->have_data)
@@ -853,7 +917,7 @@
if (i != writer_table_size)
{
- wt = create_writer (fd_to_handle (fd));
+ wt = create_writer (fd);
if (wt)
{
writer_table[i].fd = fd;
@@ -969,22 +1033,39 @@
int
_gpgme_io_pipe (int filedes[2], int inherit_idx)
{
- HANDLE rh;
- HANDLE wh;
-
+ int rfd;
+ int wfd;
#ifdef HAVE_W32CE_SYSTEM
HANDLE hd;
int rvid;
+#else
+ HANDLE rh;
+ HANDLE wh;
+ SECURITY_ATTRIBUTES sec_attr;
+#endif
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes,
"inherit_idx=%i (GPGME uses it for %s)",
inherit_idx, inherit_idx ? "reading" : "writing");
+ rfd = new_fd ();
+ if (rfd == -1)
+ return TRACE_SYSRES (-1);
+ wfd = new_fd ();
+ if (wfd == -1)
+ {
+ release_fd (rfd);
+ return TRACE_SYSRES (-1);
+ }
+
+#ifdef HAVE_W32CE_SYSTEM
hd = _assuan_w32ce_prepare_pipe (&rvid, !inherit_idx);
if (hd == INVALID_HANDLE_VALUE)
{
TRACE_LOG1 ("_assuan_w32ce_prepare_pipe failed: ec=%d",
(int) GetLastError ());
+ release_fd (rfd);
+ release_fd (wfd);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
@@ -992,18 +1073,16 @@
if (inherit_idx == 0)
{
- /* FIXME: For now. We need to detect them at close. */
- rh = (void*) ((rvid << 1) | 1);
- wh = hd;
+ fd_table[rfd].rvid = rvid;
+ fd_table[wfd].handle = hd;
}
else
{
- rh = hd;
- /* FIXME: For now. We need to detect them at close. */
- wh = (void*) ((rvid << 1) | 1);
+ fd_table[rfd].handle = hd;
+ fd_table[wfd].rvid = rvid;
}
+
#else
- SECURITY_ATTRIBUTES sec_attr;
memset (&sec_attr, 0, sizeof (sec_attr));
sec_attr.nLength = sizeof (sec_attr);
@@ -1012,6 +1091,8 @@
if (!CreatePipe (&rh, &wh, &sec_attr, PIPEBUF_SIZE))
{
TRACE_LOG1 ("CreatePipe failed: ec=%d", (int) GetLastError ());
+ release_fd (rfd);
+ release_fd (wfd);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
@@ -1027,6 +1108,8 @@
{
TRACE_LOG1 ("DuplicateHandle failed: ec=%d",
(int) GetLastError ());
+ release_fd (rfd);
+ release_fd (wfd);
CloseHandle (rh);
CloseHandle (wh);
/* FIXME: Should translate the error code. */
@@ -1045,6 +1128,8 @@
{
TRACE_LOG1 ("DuplicateHandle failed: ec=%d",
(int) GetLastError ());
+ release_fd (rfd);
+ release_fd (wfd);
CloseHandle (rh);
CloseHandle (wh);
/* FIXME: Should translate the error code. */
@@ -1054,20 +1139,25 @@
CloseHandle (wh);
wh = hd;
}
+ fd_table[rfd].handle = rh;
+ fd_table[wfd].handle = wh;
#endif
if (inherit_idx == 0)
{
struct writer_context_s *ctx;
- ctx = find_writer (handle_to_fd (wh), 0);
+ ctx = find_writer (wfd, 0);
assert (ctx == NULL);
- ctx = find_writer (handle_to_fd (wh), 1);
+ ctx = find_writer (wfd, 1);
if (!ctx)
{
-#ifndef HAVE_W32CE_SYSTEM
- CloseHandle (rh);
-#endif
- CloseHandle (wh);
+ /* No way/need to close RVIDs on Windows CE. */
+ if (fd_table[rfd].handle)
+ CloseHandle (fd_table[rfd].handle);
+ if (fd_table[wfd].handle)
+ CloseHandle (fd_table[wfd].handle);
+ release_fd (rfd);
+ release_fd (wfd);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
@@ -1076,24 +1166,29 @@
else if (inherit_idx == 1)
{
struct reader_context_s *ctx;
- ctx = find_reader (handle_to_fd (rh), 0);
+ ctx = find_reader (rfd, 0);
assert (ctx == NULL);
- ctx = find_reader (handle_to_fd (rh), 1);
+ ctx = find_reader (rfd, 1);
if (!ctx)
{
- CloseHandle (rh);
-#ifndef HAVE_W32CE_SYSTEM
- CloseHandle (wh);
-#endif
+ if (fd_table[rfd].handle)
+ CloseHandle (fd_table[rfd].handle);
+ /* No way/need to close RVIDs on Windows CE. */
+ if (fd_table[wfd].handle)
+ CloseHandle (fd_table[wfd].handle);
+ release_fd (rfd);
+ release_fd (wfd);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
}
- filedes[0] = handle_to_fd (rh);
- filedes[1] = handle_to_fd (wh);
- return TRACE_SUC2 ("read=%p, write=%p", rh, wh);
+ filedes[0] = rfd;
+ filedes[1] = wfd;
+ return TRACE_SUC6 ("read=0x%x (%p/0x%x), write=0x%x (%p/0x%x)",
+ rfd, fd_table[rfd].handle, fd_table[rfd].rvid,
+ wfd, fd_table[wfd].handle, fd_table[wfd].rvid);
}
@@ -1103,6 +1198,7 @@
int i;
_gpgme_close_notify_handler_t handler = NULL;
void *value = NULL;
+
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);
if (fd == -1)
@@ -1110,13 +1206,12 @@
gpg_err_set_errno (EBADF);
return TRACE_SYSRES (-1);
}
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ {
+ gpg_err_set_errno (EBADF);
+ return TRACE_SYSRES (-1);
+ }
-#ifdef HAVE_W32CE_SYSTEM
- /* FIXME: For now: This is a rendezvous id. */
- if (fd & 1)
- return TRACE_SYSRES (0);
-#endif
-
kill_reader (fd);
kill_writer (fd);
LOCK (notify_table_lock);
@@ -1136,14 +1231,33 @@
if (handler)
handler (fd, value);
- if (!CloseHandle (fd_to_handle (fd)))
- {
- TRACE_LOG1 ("CloseHandle failed: ec=%d", (int) GetLastError ());
- /* FIXME: Should translate the error code. */
- gpg_err_set_errno (EIO);
- return TRACE_SYSRES (-1);
+ if (fd_table[fd].dup_from == -1)
+ {
+ if (fd_table[fd].handle != INVALID_HANDLE_VALUE)
+ {
+ if (!CloseHandle (fd_table[fd].handle))
+ {
+ TRACE_LOG1 ("CloseHandle failed: ec=%d", (int) GetLastError ());
+ /* FIXME: Should translate the error code. */
+ gpg_err_set_errno (EIO);
+ return TRACE_SYSRES (-1);
+ }
+ }
+ else if (fd_table[fd].socket != INVALID_SOCKET)
+ {
+ if (closesocket (fd_table[fd].socket))
+ {
+ TRACE_LOG1 ("closesocket failed: ec=%d", (int) WSAGetLastError ());
+ /* FIXME: Should translate the error code. */
+ gpg_err_set_errno (EIO);
+ return TRACE_SYSRES (-1);
+ }
+ }
+ /* Nothing to do for RVIDs. */
}
+ release_fd (fd);
+
return TRACE_SYSRES (0);
}
@@ -1188,6 +1302,7 @@
return 0;
}
+
#ifdef HAVE_W32CE_SYSTEM
static char *
build_commandline (char **argv, int fd0, int fd0_isnull,
@@ -1202,42 +1317,28 @@
p = fdbuf;
*p = 0;
- strcpy (p, "-&S0=null ");
- p += strlen (p);
if (fd0 != -1)
{
- /* FIXME */
- if (fd0 & 1)
- fd0 = fd0 >> 1;
-
if (fd0_isnull)
strcpy (p, "-&S0=null ");
else
- snprintf (p, 25, "-&S0=%d ", (int)fd0);
+ snprintf (p, 25, "-&S0=%d ", fd_table[fd0].rvid);
p += strlen (p);
}
if (fd1 != -1)
{
- /* FIXME */
- if (fd1 & 1)
- fd1 = fd1 >> 1;
-
if (fd1_isnull)
strcpy (p, "-&S1=null ");
else
- snprintf (p, 25, "-&S1=%d ", (int)fd1);
+ snprintf (p, 25, "-&S1=%d ", fd_table[fd1].rvid);
p += strlen (p);
}
if (fd2 != -1)
{
- /* FIXME */
- if (fd2 & 1)
- fd2 = fd2 >> 1;
-
if (fd2_isnull)
strcpy (p, "-&S2=null ");
else
- snprintf (p, 25, "-&S2=%d ", (int)fd2);
+ snprintf (p, 25, "-&S2=%d ", fd_table[fd2].rvid);
p += strlen (p);
}
strcpy (p, "-&S2=null ");
@@ -1378,7 +1479,22 @@
for (i = 0; fd_list[i].fd != -1; i++)
{
- TRACE_LOG3 ("fd_list[%2i] = fd %i, dup_to %i", i, fd_list[i].fd, fd_list[i].dup_to);
+ int fd = fd_list[i].fd;
+
+ TRACE_LOG3 ("fd_list[%2i] = fd %i, dup_to %i", i, fd, fd_list[i].dup_to);
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ {
+ TRACE_LOG1 ("invalid fd 0x%x", fd);
+ gpg_err_set_errno (EBADF);
+ return TRACE_SYSRES (-1);
+ }
+ if (fd_table[fd].rvid == 0)
+ {
+ TRACE_LOG1 ("fd 0x%x not inheritable (not an RVID)", fd);
+ gpg_err_set_errno (EBADF);
+ return TRACE_SYSRES (-1);
+ }
+
if (fd_list[i].dup_to == 0)
{
fd_in = fd_list[i].fd;
@@ -1428,7 +1544,7 @@
for (i = 0; fd_list[i].fd != -1; i++)
{
/* Return the child name of this handle. */
- fd_list[i].peer_name = fd_list[i].fd;
+ fd_list[i].peer_name = fd_table[fd_list[i].fd].rvid;
}
#else
@@ -1749,6 +1865,7 @@
else if (code == WAIT_FAILED)
{
int le = (int) GetLastError ();
+#if 0
if (le == ERROR_INVALID_HANDLE)
{
int k;
@@ -1765,6 +1882,7 @@
}
TRACE_LOG (" oops, or not???");
}
+#endif
TRACE_LOG1 ("WFMO failed: %d", le);
count = -1;
}
@@ -1813,9 +1931,11 @@
{
#ifdef HAVE_W32CE_SYSTEM
/* FIXME: For now. See above. */
- if (fd & 1)
- fd = fd >> 1;
- /* FIXME: The real problems start if fd is not of this type! */
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used
+ || fd_table[fd].rvid == 0)
+ fd = -1;
+ else
+ fd = fd_table[fd].rvid;
#endif
return snprintf (buf, buflen, "%d", fd);
@@ -1825,28 +1945,28 @@
int
_gpgme_io_dup (int fd)
{
-#ifdef HAVE_W32CE_SYSTEM
- gpg_err_set_errno (EIO);
- return -1;
-#else
- HANDLE handle = fd_to_handle (fd);
- HANDLE new_handle = fd_to_handle (fd);
- int i;
+ int newfd;
struct reader_context_s *rd_ctx;
struct writer_context_s *wt_ctx;
+ int i;
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_dup", fd);
- if (!DuplicateHandle (GetCurrentProcess(), handle,
- GetCurrentProcess(), &new_handle,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
{
- TRACE_LOG1 ("DuplicateHandle failed: ec=%d\n", (int) GetLastError ());
- /* FIXME: Translate error code. */
- gpg_err_set_errno (EIO);
+ gpg_err_set_errno (EINVAL);
return TRACE_SYSRES (-1);
}
+ newfd = new_fd();
+ if (newfd == -1)
+ return TRACE_SYSRES (-1);
+
+ fd_table[newfd].handle = fd_table[fd].handle;
+ fd_table[newfd].socket = fd_table[fd].socket;
+ fd_table[newfd].rvid = fd_table[fd].rvid;
+ fd_table[newfd].dup_from = fd;
+
rd_ctx = find_reader (fd, 0);
if (rd_ctx)
{
@@ -1860,7 +1980,7 @@
break;
/* FIXME. */
assert (i != reader_table_size);
- reader_table[i].fd = handle_to_fd (new_handle);
+ reader_table[i].fd = newfd;
reader_table[i].context = rd_ctx;
reader_table[i].used = 1;
UNLOCK (reader_table_lock);
@@ -1879,14 +1999,13 @@
break;
/* FIXME. */
assert (i != writer_table_size);
- writer_table[i].fd = handle_to_fd (new_handle);
+ writer_table[i].fd = newfd;
writer_table[i].context = wt_ctx;
writer_table[i].used = 1;
UNLOCK (writer_table_lock);
}
- return TRACE_SYSRES (handle_to_fd (new_handle));
-#endif
+ return TRACE_SYSRES (newfd);
}
@@ -1931,18 +2050,25 @@
_gpgme_io_socket (int domain, int type, int proto)
{
int res;
+ int fd;
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_socket", domain,
"type=%i, protp=%i", type, proto);
+ fd = new_fd();
+ if (fd == -1)
+ return TRACE_SYSRES (-1);
+
res = socket (domain, type, proto);
if (res == INVALID_SOCKET)
{
+ release_fd (fd);
gpg_err_set_errno (wsa2errno (WSAGetLastError ()));
return TRACE_SYSRES (-1);
}
+ fd_table[fd].socket = res;
- TRACE_SUC1 ("socket=0x%x", res);
+ TRACE_SUC2 ("socket=0x%x (0x%x)", fd, fd_table[fd].socket);
return res;
}
@@ -1956,7 +2082,13 @@
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_connect", fd,
"addr=%p, addrlen=%i", addr, addrlen);
- res = connect (fd, addr, addrlen);
+ if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
+ {
+ gpg_err_set_errno (EBADF);
+ return TRACE_SYSRES (-1);
+ }
+
+ res = connect (fd_table[fd].socket, addr, addrlen);
if (res)
{
gpg_err_set_errno (wsa2errno (WSAGetLastError ()));
More information about the Gnupg-commits
mailing list