2010-06-10 Marcus Brinkmann <marcus@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.
This commit is contained in:
parent
b243c4263e
commit
dbb1112da1
@ -1,3 +1,30 @@
|
||||
2010-06-10 Marcus Brinkmann <marcus@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@g10code.de>
|
||||
|
||||
* w32-io.c [HAVE_W32CE_SYSTEM]: Include assuan.h and winioctl.h.
|
||||
|
@ -204,6 +204,10 @@ void _gpgme_debug_frame_end (void);
|
||||
_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", \
|
||||
|
392
src/w32-io.c
392
src/w32-io.c
@ -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
|
||||
|
||||
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 fd_to_handle(a) ((HANDLE)(a))
|
||||
#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
|
||||
#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 @@ static struct
|
||||
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 @@ DEFINE_STATIC_LOCK (reader_table_lock);
|
||||
struct writer_context_s
|
||||
{
|
||||
HANDLE file_hd;
|
||||
int file_sock;
|
||||
HANDLE thread_hd;
|
||||
int refcount;
|
||||
|
||||
@ -229,7 +296,10 @@ reader (void *arg)
|
||||
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 @@ reader (void *arg)
|
||||
|
||||
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 @@ reader (void *arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
try_readfile:
|
||||
if (!ReadFile (ctx->file_hd,
|
||||
ctx->buffer + ctx->writepos, nbytes, &nread, NULL))
|
||||
{
|
||||
@ -348,7 +405,7 @@ reader (void *arg)
|
||||
|
||||
|
||||
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 @@ create_reader (HANDLE fd)
|
||||
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 @@ destroy_reader (struct reader_context_s *ctx)
|
||||
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,
|
||||
NULL, 0, NULL, 0, NULL, NULL))
|
||||
if (ctx->file_hd != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
|
||||
"unblock control call failed for thread %p", ctx->thread_hd);
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -491,7 +558,7 @@ find_reader (int fd, int start_it)
|
||||
|
||||
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 @@ writer (void *arg)
|
||||
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 @@ 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 (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 @@ writer (void *arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
try_writefile:
|
||||
if (!WriteFile (ctx->file_hd, ctx->buffer,
|
||||
ctx->nbytes, &nwritten, NULL))
|
||||
{
|
||||
@ -711,7 +768,7 @@ writer (void *arg)
|
||||
|
||||
|
||||
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 @@ create_writer (HANDLE fd)
|
||||
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 @@ find_writer (int fd, int start_it)
|
||||
|
||||
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 @@ _gpgme_io_write (int fd, const void *buffer, size_t count)
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
{
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
{
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
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 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
|
||||
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 @@ _gpgme_io_close (int fd)
|
||||
int i;
|
||||
_gpgme_close_notify_handler_t handler = NULL;
|
||||
void *value = NULL;
|
||||
|
||||
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);
|
||||
|
||||
if (fd == -1)
|
||||
@ -1110,12 +1206,11 @@ _gpgme_io_close (int fd)
|
||||
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
|
||||
if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used)
|
||||
{
|
||||
gpg_err_set_errno (EBADF);
|
||||
return TRACE_SYSRES (-1);
|
||||
}
|
||||
|
||||
kill_reader (fd);
|
||||
kill_writer (fd);
|
||||
@ -1136,14 +1231,33 @@ _gpgme_io_close (int fd)
|
||||
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 @@ _gpgme_io_set_nonblocking (int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
static char *
|
||||
build_commandline (char **argv, int fd0, int fd0_isnull,
|
||||
@ -1202,42 +1317,28 @@ build_commandline (char **argv, int fd0, int fd0_isnull,
|
||||
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 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
|
||||
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 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
|
||||
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 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
|
||||
else if (code == WAIT_FAILED)
|
||||
{
|
||||
int le = (int) GetLastError ();
|
||||
#if 0
|
||||
if (le == ERROR_INVALID_HANDLE)
|
||||
{
|
||||
int k;
|
||||
@ -1765,6 +1882,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
|
||||
}
|
||||
TRACE_LOG (" oops, or not???");
|
||||
}
|
||||
#endif
|
||||
TRACE_LOG1 ("WFMO failed: %d", le);
|
||||
count = -1;
|
||||
}
|
||||
@ -1813,9 +1931,11 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
|
||||
{
|
||||
#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 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
|
||||
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 @@ _gpgme_io_dup (int fd)
|
||||
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 @@ _gpgme_io_dup (int fd)
|
||||
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 @@ int
|
||||
_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 @@ _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen)
|
||||
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 ()));
|
||||
|
Loading…
Reference in New Issue
Block a user