2010-06-09 Marcus Brinkmann <marcus@g10code.de>

* w32-io.c [HAVE_W32CE_SYSTEM]: Include assuan.h and winioctl.h.
	(GPGCEDEV_IOCTL_UNBLOCK) [HAVE_W32CE_SYSTEM]: Define.
	(set_synchronize) [HAVE_W32CE_SYSTEM]: Stub it out.
	(is_socket): Allow to return -1 for auto-detect (old behaviour).
	(is_socket) [HAVE_W32CE_SYSTEM]: Return -1.
	(reader): Handle auto-detect case.  Handle ctx->stop_me before
	checking for EOF.
	(destroy_reader) [HAVE_W32CE_SYSTEM]: Unblock a pending reader.
	(writer): Handle auto-detect case.  Handle ctx->stop_me with
	ERROR_BUSY.
	(destroy_writer) [HAVE_W32CE_SYSTEM]: Unblock a pending writer.
	(_gpgme_io_pipe) [HAVE_W32CE_SYSTEM]: Implement in terms of a
	half-pipe.
	(build_commandline) [HAVE_W32CE_SYSTEM]: New function.
	(_gpgme_io_spawn) [HAVE_W32CE_SYSTEM]: Implement it differently
	for this platform.
	(_gpgme_io_fd2str) [HAVE_W32CE_SYSTEM]: Implement it for RVIDs.
	(_gpgme_io_dup) [HAVE_W32CE_SYSTEM]: Stub it out.
This commit is contained in:
Marcus Brinkmann 2010-06-09 13:33:31 +00:00
parent 13774269c0
commit 9386a5e760
2 changed files with 365 additions and 34 deletions

View File

@ -1,5 +1,24 @@
2010-06-09 Marcus Brinkmann <marcus@g10code.de> 2010-06-09 Marcus Brinkmann <marcus@g10code.de>
* w32-io.c [HAVE_W32CE_SYSTEM]: Include assuan.h and winioctl.h.
(GPGCEDEV_IOCTL_UNBLOCK) [HAVE_W32CE_SYSTEM]: Define.
(set_synchronize) [HAVE_W32CE_SYSTEM]: Stub it out.
(is_socket): Allow to return -1 for auto-detect (old behaviour).
(is_socket) [HAVE_W32CE_SYSTEM]: Return -1.
(reader): Handle auto-detect case. Handle ctx->stop_me before
checking for EOF.
(destroy_reader) [HAVE_W32CE_SYSTEM]: Unblock a pending reader.
(writer): Handle auto-detect case. Handle ctx->stop_me with
ERROR_BUSY.
(destroy_writer) [HAVE_W32CE_SYSTEM]: Unblock a pending writer.
(_gpgme_io_pipe) [HAVE_W32CE_SYSTEM]: Implement in terms of a
half-pipe.
(build_commandline) [HAVE_W32CE_SYSTEM]: New function.
(_gpgme_io_spawn) [HAVE_W32CE_SYSTEM]: Implement it differently
for this platform.
(_gpgme_io_fd2str) [HAVE_W32CE_SYSTEM]: Implement it for RVIDs.
(_gpgme_io_dup) [HAVE_W32CE_SYSTEM]: Stub it out.
* gpgme-tool.c (result_add_timestamp): Add missing NULL argument. * gpgme-tool.c (result_add_timestamp): Add missing NULL argument.
(result_sign_to_xml): Protect against NULL fingerprint. (result_sign_to_xml): Protect against NULL fingerprint.
(struct server): New members input_fd, input_filename, (struct server): New members input_fd, input_filename,

View File

@ -33,6 +33,13 @@
#include <windows.h> #include <windows.h>
#include <io.h> #include <io.h>
#ifdef HAVE_W32CE_SYSTEM
#include <assuan.h>
#include <winioctl.h>
#define GPGCEDEV_IOCTL_UNBLOCK \
CTL_CODE (FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
#include "util.h" #include "util.h"
#include "sema.h" #include "sema.h"
#include "priv-io.h" #include "priv-io.h"
@ -154,6 +161,9 @@ get_desired_thread_priority (void)
static HANDLE static HANDLE
set_synchronize (HANDLE hd) set_synchronize (HANDLE hd)
{ {
#ifdef HAVE_W32CE_SYSTEM
return hd;
#else
HANDLE new_hd; HANDLE new_hd;
/* For NT we have to set the sync flag. It seems that the only way /* For NT we have to set the sync flag. It seems that the only way
@ -171,13 +181,18 @@ set_synchronize (HANDLE hd)
CloseHandle (hd); CloseHandle (hd);
return new_hd; return new_hd;
#endif
} }
/* Return true if HD refers to a socket. */ /* Return 1 if HD refers to a socket, 0 if it does not refer to a
socket, and -1 for unknown (autodetect). */
static int static int
is_socket (HANDLE hd) is_socket (HANDLE hd)
{ {
#ifdef HAVE_W32CE_SYSTEM
return -1;
#else
/* We need to figure out whether we are working on a socket or on a /* We need to figure out whether we are working on a socket or on a
handle. A trivial way would be to check for the return code of handle. A trivial way would be to check for the return code of
recv and see if it is WSAENOTSOCK. However the recv may block recv and see if it is WSAENOTSOCK. However the recv may block
@ -193,12 +208,14 @@ is_socket (HANDLE hd)
only if it is supported by the service provider. Tests on a only if it is supported by the service provider. Tests on a
stock XP using a local TCP socket show that it does not work. */ stock XP using a local TCP socket show that it does not work. */
DWORD dummyflags, dummyoutsize, dummyinsize, dummyinst; DWORD dummyflags, dummyoutsize, dummyinsize, dummyinst;
if (GetFileType (hd) == FILE_TYPE_PIPE if (GetFileType (hd) == FILE_TYPE_PIPE
&& !GetNamedPipeInfo (hd, &dummyflags, &dummyoutsize, && !GetNamedPipeInfo (hd, &dummyflags, &dummyoutsize,
&dummyinsize, &dummyinst)) &dummyinsize, &dummyinst))
return 1; /* Function failed; thus we assume it is a socket. */ return 1; /* Function failed; thus we assume it is a socket. */
else else
return 0; /* Success; this is not a socket. */ return 0; /* Success; this is not a socket. */
#endif
} }
@ -243,7 +260,7 @@ reader (void *arg)
TRACE_LOG2 ("%s %d bytes", sock? "receiving":"reading", nbytes); TRACE_LOG2 ("%s %d bytes", sock? "receiving":"reading", nbytes);
if (sock) if (sock == -1 || sock == 1)
{ {
int n; int n;
@ -251,6 +268,17 @@ reader (void *arg)
ctx->buffer + ctx->writepos, nbytes, 0); ctx->buffer + ctx->writepos, nbytes, 0);
if (n < 0) if (n < 0)
{ {
if (sock == -1)
{
if (WSAGetLastError () == WSAENOTSOCK)
{
sock = 0;
goto try_readfile;
}
else
sock = 1;
}
ctx->error_code = (int) WSAGetLastError (); ctx->error_code = (int) WSAGetLastError ();
if (ctx->error_code == ERROR_BROKEN_PIPE) if (ctx->error_code == ERROR_BROKEN_PIPE)
{ {
@ -268,10 +296,13 @@ reader (void *arg)
} }
else else
{ {
try_readfile:
if (!ReadFile (ctx->file_hd, if (!ReadFile (ctx->file_hd,
ctx->buffer + ctx->writepos, nbytes, &nread, NULL)) ctx->buffer + ctx->writepos, nbytes, &nread, NULL))
{ {
ctx->error_code = (int) GetLastError (); ctx->error_code = (int) GetLastError ();
/* NOTE (W32CE): Do not ignore ERROR_BUSY! Check at
least stop_me if that happens. */
if (ctx->error_code == ERROR_BROKEN_PIPE) if (ctx->error_code == ERROR_BROKEN_PIPE)
{ {
ctx->eof = 1; ctx->eof = 1;
@ -285,20 +316,21 @@ reader (void *arg)
break; break;
} }
} }
if (!nread)
{
ctx->eof = 1;
TRACE_LOG ("got eof");
break;
}
TRACE_LOG1 ("got %u bytes", nread);
LOCK (ctx->mutex); LOCK (ctx->mutex);
if (ctx->stop_me) if (ctx->stop_me)
{ {
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
break; break;
} }
if (!nread)
{
ctx->eof = 1;
TRACE_LOG ("got eof");
UNLOCK (ctx->mutex);
break;
}
TRACE_LOG1 ("got %u bytes", nread);
ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE; ctx->writepos = (ctx->writepos + nread) % READBUF_SIZE;
if (!SetEvent (ctx->have_data_ev)) if (!SetEvent (ctx->have_data_ev))
TRACE_LOG2 ("SetEvent (0x%x) failed: ec=%d", ctx->have_data_ev, TRACE_LOG2 ("SetEvent (0x%x) failed: ec=%d", ctx->have_data_ev,
@ -403,6 +435,19 @@ destroy_reader (struct reader_context_s *ctx)
SetEvent (ctx->have_space_ev); SetEvent (ctx->have_space_ev);
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
#ifdef HAVE_W32CE_SYSTEM
/* Scenario: We never create a full pipe, but already started
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))
{
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
"unblock control call failed for thread %p", ctx->thread_hd);
}
#endif
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd, TRACE1 (DEBUG_SYSIO, "gpgme:destroy_reader", ctx->file_hd,
"waiting for termination of thread %p", ctx->thread_hd); "waiting for termination of thread %p", ctx->thread_hd);
WaitForSingleObject (ctx->stopped, INFINITE); WaitForSingleObject (ctx->stopped, INFINITE);
@ -603,7 +648,7 @@ writer (void *arg)
/* Note that CTX->nbytes is not zero at this point, because /* Note that CTX->nbytes is not zero at this point, because
_gpgme_io_write always writes at least 1 byte before waking _gpgme_io_write always writes at least 1 byte before waking
us up, unless CTX->stop_me is true, which we catch above. */ us up, unless CTX->stop_me is true, which we catch above. */
if (sock) if (sock == -1 || sock == 1)
{ {
/* We need to try send first because a socket handle can't /* We need to try send first because a socket handle can't
be used with WriteFile. */ be used with WriteFile. */
@ -613,6 +658,17 @@ writer (void *arg)
ctx->buffer, ctx->nbytes, 0); ctx->buffer, ctx->nbytes, 0);
if (n < 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_code = (int) WSAGetLastError ();
ctx->error = 1; ctx->error = 1;
TRACE_LOG1 ("send error: ec=%d", ctx->error_code); TRACE_LOG1 ("send error: ec=%d", ctx->error_code);
@ -622,9 +678,17 @@ writer (void *arg)
} }
else else
{ {
try_writefile:
if (!WriteFile (ctx->file_hd, ctx->buffer, if (!WriteFile (ctx->file_hd, ctx->buffer,
ctx->nbytes, &nwritten, NULL)) ctx->nbytes, &nwritten, NULL))
{ {
if (GetLastError () == ERROR_BUSY)
{
/* Probably stop_me is set now. */
TRACE_LOG ("pipe busy (unblocked?)");
continue;
}
ctx->error_code = (int) GetLastError (); ctx->error_code = (int) GetLastError ();
ctx->error = 1; ctx->error = 1;
TRACE_LOG1 ("write error: ec=%d", ctx->error_code); TRACE_LOG1 ("write error: ec=%d", ctx->error_code);
@ -733,6 +797,19 @@ destroy_writer (struct writer_context_s *ctx)
SetEvent (ctx->have_data); SetEvent (ctx->have_data);
UNLOCK (ctx->mutex); UNLOCK (ctx->mutex);
#ifdef HAVE_W32CE_SYSTEM
/* Scenario: We never create a full pipe, but already started
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))
{
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_writer", ctx->file_hd,
"unblock control call failed for thread %p", ctx->thread_hd);
}
#endif
TRACE1 (DEBUG_SYSIO, "gpgme:destroy_writer", ctx->file_hd, TRACE1 (DEBUG_SYSIO, "gpgme:destroy_writer", ctx->file_hd,
"waiting for termination of thread %p", ctx->thread_hd); "waiting for termination of thread %p", ctx->thread_hd);
WaitForSingleObject (ctx->stopped, INFINITE); WaitForSingleObject (ctx->stopped, INFINITE);
@ -894,11 +971,40 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
{ {
HANDLE rh; HANDLE rh;
HANDLE wh; HANDLE wh;
SECURITY_ATTRIBUTES sec_attr;
#ifdef HAVE_W32CE_SYSTEM
HANDLE hd;
int rvid;
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes, TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes,
"inherit_idx=%i (GPGME uses it for %s)", "inherit_idx=%i (GPGME uses it for %s)",
inherit_idx, inherit_idx ? "reading" : "writing"); inherit_idx, inherit_idx ? "reading" : "writing");
hd = _assuan_w32ce_prepare_pipe (&rvid, !inherit_idx);
if (hd == INVALID_HANDLE_VALUE)
{
TRACE_LOG1 ("_assuan_w32ce_prepare_pipe failed: ec=%d",
(int) GetLastError ());
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
if (inherit_idx == 0)
{
/* FIXME: For now. We need to detect them at close. */
rh = (void*) ((rvid << 1) | 1);
wh = hd;
}
else
{
rh = hd;
/* FIXME: For now. We need to detect them at close. */
wh = (void*) ((rvid << 1) | 1);
}
#else
SECURITY_ATTRIBUTES sec_attr;
memset (&sec_attr, 0, sizeof (sec_attr)); memset (&sec_attr, 0, sizeof (sec_attr));
sec_attr.nLength = sizeof (sec_attr); sec_attr.nLength = sizeof (sec_attr);
sec_attr.bInheritHandle = FALSE; sec_attr.bInheritHandle = FALSE;
@ -914,7 +1020,6 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
/* Make one end inheritable. */ /* Make one end inheritable. */
if (inherit_idx == 0) if (inherit_idx == 0)
{ {
struct writer_context_s *ctx;
HANDLE hd; HANDLE hd;
if (!DuplicateHandle (GetCurrentProcess(), rh, if (!DuplicateHandle (GetCurrentProcess(), rh,
GetCurrentProcess(), &hd, 0, GetCurrentProcess(), &hd, 0,
@ -930,22 +1035,9 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
} }
CloseHandle (rh); CloseHandle (rh);
rh = hd; rh = hd;
ctx = find_writer (handle_to_fd (wh), 0);
assert (ctx == NULL);
ctx = find_writer (handle_to_fd (wh), 1);
if (!ctx)
{
CloseHandle (rh);
CloseHandle (wh);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
} }
else if (inherit_idx == 1) else if (inherit_idx == 1)
{ {
struct reader_context_s *ctx;
HANDLE hd; HANDLE hd;
if (!DuplicateHandle( GetCurrentProcess(), wh, if (!DuplicateHandle( GetCurrentProcess(), wh,
GetCurrentProcess(), &hd, 0, GetCurrentProcess(), &hd, 0,
@ -961,14 +1053,38 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
} }
CloseHandle (wh); CloseHandle (wh);
wh = hd; wh = hd;
}
#endif
if (inherit_idx == 0)
{
struct writer_context_s *ctx;
ctx = find_writer (handle_to_fd (wh), 0);
assert (ctx == NULL);
ctx = find_writer (handle_to_fd (wh), 1);
if (!ctx)
{
#ifndef HAVE_W32CE_SYSTEM
CloseHandle (rh);
#endif
CloseHandle (wh);
/* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
}
else if (inherit_idx == 1)
{
struct reader_context_s *ctx;
ctx = find_reader (handle_to_fd (rh), 0); ctx = find_reader (handle_to_fd (rh), 0);
assert (ctx == NULL); assert (ctx == NULL);
ctx = find_reader (handle_to_fd (rh), 1); ctx = find_reader (handle_to_fd (rh), 1);
if (!ctx) if (!ctx)
{ {
CloseHandle (rh); CloseHandle (rh);
#ifndef HAVE_W32CE_SYSTEM
CloseHandle (wh); CloseHandle (wh);
#endif
/* FIXME: Should translate the error code. */ /* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO); gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1); return TRACE_SYSRES (-1);
@ -995,6 +1111,12 @@ _gpgme_io_close (int fd)
return TRACE_SYSRES (-1); 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_reader (fd);
kill_writer (fd); kill_writer (fd);
LOCK (notify_table_lock); LOCK (notify_table_lock);
@ -1066,7 +1188,105 @@ _gpgme_io_set_nonblocking (int fd)
return 0; return 0;
} }
#ifdef HAVE_W32CE_SYSTEM
static char *
build_commandline (char **argv, int fd0, int fd0_isnull,
int fd1, int fd1_isnull,
int fd2, int fd2_isnull)
{
int i, n;
const char *s;
char *buf, *p;
char fdbuf[3*30];
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);
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);
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);
p += strlen (p);
}
strcpy (p, "-&S2=null ");
p += strlen (p);
n = strlen (fdbuf);
for (i=0; (s = argv[i]); i++)
{
if (!i)
continue; /* Ignore argv[0]. */
n += strlen (s) + 1 + 2; /* (1 space, 2 quoting) */
for (; *s; s++)
if (*s == '\"')
n++; /* Need to double inner quotes. */
}
n++;
buf = p = malloc (n);
if (! buf)
return NULL;
p = stpcpy (p, fdbuf);
for (i = 0; argv[i]; i++)
{
if (!i)
continue; /* Ignore argv[0]. */
if (i > 1)
p = stpcpy (p, " ");
if (! *argv[i]) /* Empty string. */
p = stpcpy (p, "\"\"");
else if (strpbrk (argv[i], " \t\n\v\f\""))
{
p = stpcpy (p, "\"");
for (s = argv[i]; *s; s++)
{
*p++ = *s;
if (*s == '\"')
*p++ = *s;
}
*p++ = '\"';
*p = 0;
}
else
p = stpcpy (p, argv[i]);
}
return buf;
}
#else
static char * static char *
build_commandline (char **argv) build_commandline (char **argv)
{ {
@ -1120,6 +1340,7 @@ build_commandline (char **argv)
return buf; return buf;
} }
#endif
int int
@ -1128,7 +1349,6 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
void (*atfork) (void *opaque, int reserved), void (*atfork) (void *opaque, int reserved),
void *atforkvalue, pid_t *r_pid) void *atforkvalue, pid_t *r_pid)
{ {
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi = PROCESS_INFORMATION pi =
{ {
NULL, /* returns process handle */ NULL, /* returns process handle */
@ -1136,10 +1356,85 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
0, /* returns pid */ 0, /* returns pid */
0 /* returns tid */ 0 /* returns tid */
}; };
STARTUPINFO si;
int cr_flags = (CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ()));
int i; int i;
#ifdef HAVE_W32CE_SYSTEM
int fd_in = -1;
int fd_out = -1;
int fd_err = -1;
int fd_in_isnull = 1;
int fd_out_isnull = 1;
int fd_err_isnull = 1;
char *cmdline;
TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
"path=%s", path);
i = 0;
while (argv[i])
{
TRACE_LOG2 ("argv[%2i] = %s", i, argv[i]);
i++;
}
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);
if (fd_list[i].dup_to == 0)
{
fd_in = fd_list[i].fd;
fd_in_isnull = 0;
}
else if (fd_list[i].dup_to == 1)
{
fd_out = fd_list[i].fd;
fd_out_isnull = 0;
}
else if (fd_list[i].dup_to == 2)
{
fd_err = fd_list[i].fd;
fd_err_isnull = 0;
}
}
cmdline = build_commandline (argv, fd_in, fd_in_isnull,
fd_out, fd_out_isnull, fd_err, fd_err_isnull);
if (!cmdline)
{
TRACE_LOG1 ("build_commandline failed: %s", strerror (errno));
return TRACE_SYSRES (-1);
}
fprintf (stderr, "SPAWNY: %s\n", cmdline);
if (!CreateProcessA (path, /* Program to start. */
cmdline, /* Command line arguments. */
NULL, /* (not supported) */
NULL, /* (not supported) */
FALSE, /* (not supported) */
(CREATE_SUSPENDED), /* Creation flags. */
NULL, /* (not supported) */
NULL, /* (not supported) */
NULL, /* (not supported) */
&pi /* Returns process information.*/
))
{
TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
free (cmdline);
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
/* Insert the inherited handles. */
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;
}
#else
SECURITY_ATTRIBUTES sec_attr;
STARTUPINFOA si;
int cr_flags = CREATE_DEFAULT_ERROR_MODE;
char **args; char **args;
char *arg_string; char *arg_string;
/* FIXME. */ /* FIXME. */
@ -1183,7 +1478,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if (!arg_string) if (!arg_string)
{ {
close (tmp_fd); close (tmp_fd);
DeleteFile (tmp_name); DeleteFileA (tmp_name);
return TRACE_SYSRES (-1); return TRACE_SYSRES (-1);
} }
@ -1196,7 +1491,10 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
si.hStdError = INVALID_HANDLE_VALUE; si.hStdError = INVALID_HANDLE_VALUE;
cr_flags |= CREATE_SUSPENDED; cr_flags |= CREATE_SUSPENDED;
#ifndef HAVE_W32CE_SYSTEM
cr_flags |= DETACHED_PROCESS; cr_flags |= DETACHED_PROCESS;
cr_flags |= GetPriorityClass (GetCurrentProcess ());
#endif
if (!CreateProcessA (_gpgme_get_w32spawn_path (), if (!CreateProcessA (_gpgme_get_w32spawn_path (),
arg_string, arg_string,
&sec_attr, /* process security attributes */ &sec_attr, /* process security attributes */
@ -1211,7 +1509,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ()); TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
free (arg_string); free (arg_string);
close (tmp_fd); close (tmp_fd);
DeleteFile (tmp_name); DeleteFileA (tmp_name);
/* FIXME: Should translate the error code. */ /* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO); gpg_err_set_errno (EIO);
@ -1241,7 +1539,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
CloseHandle (pi.hProcess); CloseHandle (pi.hProcess);
close (tmp_fd); close (tmp_fd);
DeleteFile (tmp_name); DeleteFileA (tmp_name);
/* FIXME: Should translate the error code. */ /* FIXME: Should translate the error code. */
gpg_err_set_errno (EIO); gpg_err_set_errno (EIO);
@ -1294,6 +1592,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
close (tmp_fd); close (tmp_fd);
/* The temporary file is deleted by the gpgme-w32spawn process /* The temporary file is deleted by the gpgme-w32spawn process
(hopefully). */ (hopefully). */
#endif
TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, " TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, "
"dwProcessID=%d, dwThreadId=%d", "dwProcessID=%d, dwThreadId=%d",
@ -1511,6 +1811,13 @@ _gpgme_io_subsystem_init (void)
int int
_gpgme_io_fd2str (char *buf, int buflen, int fd) _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! */
#endif
return snprintf (buf, buflen, "%d", fd); return snprintf (buf, buflen, "%d", fd);
} }
@ -1518,6 +1825,10 @@ _gpgme_io_fd2str (char *buf, int buflen, int fd)
int int
_gpgme_io_dup (int fd) _gpgme_io_dup (int fd)
{ {
#ifdef HAVE_W32CE_SYSTEM
gpg_err_set_errno (EIO);
return -1;
#else
HANDLE handle = fd_to_handle (fd); HANDLE handle = fd_to_handle (fd);
HANDLE new_handle = fd_to_handle (fd); HANDLE new_handle = fd_to_handle (fd);
int i; int i;
@ -1575,6 +1886,7 @@ _gpgme_io_dup (int fd)
} }
return TRACE_SYSRES (handle_to_fd (new_handle)); return TRACE_SYSRES (handle_to_fd (new_handle));
#endif
} }