2005-11-17 18:45:14 +00:00
|
|
|
|
/* 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 <config.h>
|
|
|
|
|
#endif
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <sys/types.h>
|
2005-11-18 16:52:38 +00:00
|
|
|
|
#include <glib.h>
|
2005-11-17 18:45:14 +00:00
|
|
|
|
#include <windows.h>
|
|
|
|
|
#include <io.h>
|
|
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "priv-io.h"
|
|
|
|
|
#include "sema.h"
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
2006-02-28 16:54:59 +00:00
|
|
|
|
#ifndef O_BINARY
|
|
|
|
|
#ifdef _O_BINARY
|
|
|
|
|
#define O_BINARY _O_BINARY
|
|
|
|
|
#else
|
|
|
|
|
#define O_BINARY 0
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
|
|
|
|
|
2005-11-18 11:18:01 +00:00
|
|
|
|
/* This file is an ugly hack to get GPGME working with glib on Windows
|
|
|
|
|
targets. On Windows, you can not select() on file descriptors.
|
|
|
|
|
The only way to check if there is something to read is to read
|
|
|
|
|
something. This means that GPGME can not let glib check for data
|
|
|
|
|
without letting glib also handle the data on Windows targets.
|
|
|
|
|
|
|
|
|
|
The ugly consequence is that we need to work on GIOChannels in
|
|
|
|
|
GPGME, creating a glib dependency. Also, we need to export an
|
|
|
|
|
interface for the application to get at GPGME's GIOChannel. There
|
|
|
|
|
is no good way to abstract all this with callbacks, because the
|
|
|
|
|
whole thing is also interconnected with the creation of pipes and
|
|
|
|
|
child processes.
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
The following rule applies only to this I/O backend:
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
|
|
|
|
* ALL operations must use the user defined event loop. GPGME can
|
|
|
|
|
not anymore provide its own event loop. This is mostly a sanity
|
|
|
|
|
requirement: Although we have in theory all information we need to
|
|
|
|
|
make the GPGME W32 code for select still work, it would be a big
|
|
|
|
|
complication and require changes throughout GPGME.
|
|
|
|
|
|
|
|
|
|
Eventually, we probably have to bite the bullet and make some
|
|
|
|
|
really nice callback interfaces to let the user control all this at
|
|
|
|
|
a per-context level. */
|
|
|
|
|
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
#define MAX_SLAFD 256
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
GIOChannel *giochannel_table[MAX_SLAFD];
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static GIOChannel *
|
2005-11-18 14:00:50 +00:00
|
|
|
|
find_channel (int fd, int create)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2005-11-18 11:18:01 +00:00
|
|
|
|
if (fd < 0 || fd >= MAX_SLAFD)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
if (create && !giochannel_table[fd])
|
2005-12-31 04:22:14 +00:00
|
|
|
|
{
|
|
|
|
|
giochannel_table[fd] = g_io_channel_win32_new_fd (fd);
|
|
|
|
|
g_io_channel_set_encoding (giochannel_table[fd], NULL, NULL);
|
|
|
|
|
g_io_channel_set_buffered (giochannel_table[fd], FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
return giochannel_table[fd];
|
2005-11-18 11:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-06 22:41:11 +00:00
|
|
|
|
|
|
|
|
|
/* Compatibility interface. Obsolete. */
|
|
|
|
|
void *
|
2005-11-18 14:00:50 +00:00
|
|
|
|
gpgme_get_giochannel (int fd)
|
2005-11-18 11:18:01 +00:00
|
|
|
|
{
|
2005-11-18 14:00:50 +00:00
|
|
|
|
return find_channel (fd, 0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-09-06 22:41:11 +00:00
|
|
|
|
/* Look up the giochannel for "file descriptor" FD. */
|
|
|
|
|
void *
|
|
|
|
|
gpgme_get_fdptr (int fd)
|
|
|
|
|
{
|
|
|
|
|
return find_channel (fd, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
/* Write the printable version of FD to the buffer BUF of length
|
|
|
|
|
BUFLEN. The printable version is the representation on the command
|
|
|
|
|
line that the child process expects. */
|
|
|
|
|
int
|
|
|
|
|
_gpgme_io_fd2str (char *buf, int buflen, int fd)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2005-11-18 14:00:50 +00:00
|
|
|
|
return snprintf (buf, buflen, "%ld", (long) _get_osfhandle (fd));
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_gpgme_io_subsystem_init (void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct
|
|
|
|
|
{
|
2007-07-13 00:43:17 +00:00
|
|
|
|
_gpgme_close_notify_handler_t handler;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
void *value;
|
2005-11-18 11:18:01 +00:00
|
|
|
|
} notify_table[MAX_SLAFD];
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2007-07-13 00:43:17 +00:00
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
int
|
|
|
|
|
_gpgme_io_read (int fd, void *buffer, size_t count)
|
|
|
|
|
{
|
|
|
|
|
int saved_errno = 0;
|
|
|
|
|
gsize nread;
|
|
|
|
|
GIOChannel *chan;
|
|
|
|
|
GIOStatus status;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_read", fd,
|
|
|
|
|
"buffer=%p, count=%u", buffer, count);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
chan = find_channel (fd, 0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
if (!chan)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOG ("no channel registered");
|
2005-11-17 18:45:14 +00:00
|
|
|
|
errno = EINVAL;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOG1 ("channel %p", chan);
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
GError *err = NULL;
|
|
|
|
|
status = g_io_channel_read_chars (chan, (gchar *) buffer,
|
|
|
|
|
count, &nread, &err);
|
|
|
|
|
if (err)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOG2 ("status %i, err %s", status, err->message);
|
2005-11-18 11:18:01 +00:00
|
|
|
|
g_error_free (err);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
|
|
|
|
if (status == G_IO_STATUS_EOF)
|
|
|
|
|
nread = 0;
|
|
|
|
|
else if (status != G_IO_STATUS_NORMAL)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOG1 ("status %d", status);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
nread = -1;
|
|
|
|
|
saved_errno = EIO;
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOGBUF (buffer, nread);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
|
|
|
|
errno = saved_errno;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (nread);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
_gpgme_io_write (int fd, const void *buffer, size_t count)
|
|
|
|
|
{
|
|
|
|
|
int saved_errno = 0;
|
|
|
|
|
gsize nwritten;
|
|
|
|
|
GIOChannel *chan;
|
|
|
|
|
GIOStatus status;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_write", fd,
|
|
|
|
|
"buffer=%p, count=%u", buffer, count);
|
|
|
|
|
TRACE_LOGBUF (buffer, count);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
chan = find_channel (fd, 0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
if (!chan)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_LOG ("fd %d: no channel registered");
|
2005-11-17 18:45:14 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
errno = saved_errno;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
|
|
|
|
return TRACE_SYSRES (nwritten);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2005-11-18 14:00:50 +00:00
|
|
|
|
_gpgme_io_pipe (int filedes[2], int inherit_idx)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2005-11-18 14:00:50 +00:00
|
|
|
|
GIOChannel *chan;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes,
|
|
|
|
|
"inherit_idx=%i (GPGME uses it for %s)",
|
|
|
|
|
inherit_idx, inherit_idx ? "writing" : "reading");
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
#define PIPEBUF_SIZE 4096
|
2006-02-28 16:54:59 +00:00
|
|
|
|
if (_pipe (filedes, PIPEBUF_SIZE, O_NOINHERIT | O_BINARY) == -1)
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
|
|
|
|
/* Make one end inheritable. */
|
|
|
|
|
if (inherit_idx == 0)
|
|
|
|
|
{
|
|
|
|
|
int new_read;
|
|
|
|
|
|
|
|
|
|
new_read = _dup (filedes[0]);
|
|
|
|
|
_close (filedes[0]);
|
|
|
|
|
filedes[0] = new_read;
|
|
|
|
|
|
|
|
|
|
if (new_read < 0)
|
|
|
|
|
{
|
|
|
|
|
_close (filedes[1]);
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2005-11-18 14:00:50 +00:00
|
|
|
|
else if (inherit_idx == 1)
|
|
|
|
|
{
|
|
|
|
|
int new_write;
|
|
|
|
|
|
|
|
|
|
new_write = _dup (filedes[1]);
|
|
|
|
|
_close (filedes[1]);
|
|
|
|
|
filedes[1] = new_write;
|
|
|
|
|
|
|
|
|
|
if (new_write < 0)
|
|
|
|
|
{
|
|
|
|
|
_close (filedes[0]);
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
/* Now we have a pipe with the right end inheritable. The other end
|
|
|
|
|
should have a giochannel. */
|
|
|
|
|
chan = find_channel (filedes[1 - inherit_idx], 1);
|
|
|
|
|
if (!chan)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
int saved_errno = errno;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
_close (filedes[0]);
|
|
|
|
|
_close (filedes[1]);
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
errno = saved_errno;
|
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SUC5 ("read=0x%x/%p, write=0x%x/%p, channel=%p",
|
2005-11-18 14:00:50 +00:00
|
|
|
|
filedes[0], (HANDLE) _get_osfhandle (filedes[0]),
|
|
|
|
|
filedes[1], (HANDLE) _get_osfhandle (filedes[1]),
|
|
|
|
|
chan);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
_gpgme_io_close (int fd)
|
|
|
|
|
{
|
|
|
|
|
GIOChannel *chan;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2005-11-18 11:18:01 +00:00
|
|
|
|
if (fd < 0 || fd >= MAX_SLAFD)
|
|
|
|
|
{
|
|
|
|
|
errno = EBADF;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-18 11:18:01 +00:00
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
|
|
|
|
/* First call the notify handler. */
|
2005-11-18 11:18:01 +00:00
|
|
|
|
if (notify_table[fd].handler)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-07-13 01:57:02 +00:00
|
|
|
|
notify_table[fd].handler (fd, notify_table[fd].value);
|
2005-11-18 11:18:01 +00:00
|
|
|
|
notify_table[fd].handler = NULL;
|
|
|
|
|
notify_table[fd].value = NULL;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2005-11-18 11:18:01 +00:00
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
/* Then do the close. */
|
2007-07-13 01:57:02 +00:00
|
|
|
|
chan = giochannel_table[fd];
|
|
|
|
|
if (chan)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-07-13 01:57:02 +00:00
|
|
|
|
g_io_channel_shutdown (chan, 1, NULL);
|
|
|
|
|
g_io_channel_unref (chan);
|
|
|
|
|
giochannel_table[fd] = NULL;
|
2005-11-18 11:18:01 +00:00
|
|
|
|
}
|
2007-07-13 01:57:02 +00:00
|
|
|
|
else
|
|
|
|
|
_close (fd);
|
2006-01-05 08:58:50 +00:00
|
|
|
|
|
2005-11-18 11:18:01 +00:00
|
|
|
|
return 0;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2007-07-13 00:43:17 +00:00
|
|
|
|
_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
|
|
|
|
|
void *value)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd,
|
|
|
|
|
"close_handler=%p/%p", handler, value);
|
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
assert (fd != -1);
|
|
|
|
|
|
|
|
|
|
if (fd < 0 || fd >= (int) DIM (notify_table))
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
{
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return TRACE_SYSRES (-1);
|
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
notify_table[fd].handler = handler;
|
|
|
|
|
notify_table[fd].value = value;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
_gpgme_io_set_nonblocking (int fd)
|
|
|
|
|
{
|
|
|
|
|
GIOChannel *chan;
|
|
|
|
|
GIOStatus status;
|
2006-01-05 08:58:50 +00:00
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd);
|
|
|
|
|
|
2005-11-18 14:00:50 +00:00
|
|
|
|
chan = find_channel (fd, 0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
if (!chan)
|
|
|
|
|
{
|
|
|
|
|
errno = EIO;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-01-05 08:58:50 +00:00
|
|
|
|
status = g_io_channel_set_flags (chan,
|
2005-11-17 18:45:14 +00:00
|
|
|
|
g_io_channel_get_flags (chan) |
|
|
|
|
|
G_IO_FLAG_NONBLOCK, NULL);
|
|
|
|
|
if (status != G_IO_STATUS_NORMAL)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
#if 0
|
|
|
|
|
/* glib 1.9.2 does not implement set_flags and returns an
|
|
|
|
|
error. */
|
|
|
|
|
errno = EIO;
|
|
|
|
|
return TRACE_SYSRES (-1);
|
|
|
|
|
#else
|
|
|
|
|
TRACE_LOG1 ("g_io_channel_set_flags failed: status=%d (ignored)",
|
|
|
|
|
status);
|
|
|
|
|
#endif
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (0);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *
|
2007-01-17 19:35:06 +00:00
|
|
|
|
build_commandline (char **argv)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-01-17 19:35:06 +00:00
|
|
|
|
int i;
|
|
|
|
|
int n = 0;
|
|
|
|
|
char *buf;
|
|
|
|
|
char *p;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2007-01-17 19:35:06 +00:00
|
|
|
|
/* We have to quote some things because under Windows the program
|
|
|
|
|
parses the commandline and does some unquoting. We enclose the
|
|
|
|
|
whole argument in double-quotes, and escape literal double-quotes
|
|
|
|
|
as well as backslashes with a backslash. We end up with a
|
|
|
|
|
trailing space at the end of the line, but that is harmless. */
|
|
|
|
|
for (i = 0; argv[i]; i++)
|
|
|
|
|
{
|
|
|
|
|
p = argv[i];
|
|
|
|
|
/* The leading double-quote. */
|
|
|
|
|
n++;
|
|
|
|
|
while (*p)
|
|
|
|
|
{
|
|
|
|
|
/* An extra one for each literal that must be escaped. */
|
|
|
|
|
if (*p == '\\' || *p == '"')
|
|
|
|
|
n++;
|
|
|
|
|
n++;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
/* The trailing double-quote and the delimiter. */
|
|
|
|
|
n += 2;
|
|
|
|
|
}
|
|
|
|
|
/* And a trailing zero. */
|
|
|
|
|
n++;
|
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
buf = p = malloc (n);
|
2007-01-17 19:35:06 +00:00
|
|
|
|
if (!buf)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
return NULL;
|
2007-01-17 19:35:06 +00:00
|
|
|
|
for (i = 0; argv[i]; i++)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-01-17 19:35:06 +00:00
|
|
|
|
char *argvp = argv[i];
|
|
|
|
|
|
|
|
|
|
*(p++) = '"';
|
|
|
|
|
while (*argvp)
|
|
|
|
|
{
|
2007-01-26 12:08:12 +00:00
|
|
|
|
if (*argvp == '\\' || *argvp == '"')
|
2007-01-17 19:35:06 +00:00
|
|
|
|
*(p++) = '\\';
|
|
|
|
|
*(p++) = *(argvp++);
|
|
|
|
|
}
|
|
|
|
|
*(p++) = '"';
|
|
|
|
|
*(p++) = ' ';
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-01-17 19:35:06 +00:00
|
|
|
|
*(p++) = 0;
|
|
|
|
|
|
2005-11-17 18:45:14 +00:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
_gpgme_io_spawn (const char *path, char **argv,
|
|
|
|
|
struct spawn_fd_item_s *fd_child_list,
|
|
|
|
|
struct spawn_fd_item_s *fd_parent_list)
|
2005-11-17 18:45:14 +00:00
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
SECURITY_ATTRIBUTES sec_attr;
|
|
|
|
|
PROCESS_INFORMATION pi =
|
|
|
|
|
{
|
|
|
|
|
NULL, /* returns process handle */
|
|
|
|
|
0, /* returns primary thread handle */
|
|
|
|
|
0, /* returns pid */
|
|
|
|
|
0 /* returns tid */
|
2005-11-17 18:45:14 +00:00
|
|
|
|
};
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
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;
|
|
|
|
|
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++;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
|
|
|
|
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 TRACE_SYSRES (-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 = (HANDLE) _get_osfhandle (fd_child_list[i].fd);
|
|
|
|
|
TRACE_LOG2 ("using 0x%x/%p for stdin", fd_child_list[i].fd,
|
|
|
|
|
_get_osfhandle (fd_child_list[i].fd));
|
|
|
|
|
duped_stdin = 1;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
else if (fd_child_list[i].dup_to == 1)
|
|
|
|
|
{
|
|
|
|
|
si.hStdOutput = (HANDLE) _get_osfhandle (fd_child_list[i].fd);
|
|
|
|
|
TRACE_LOG2 ("using 0x%x/%p for stdout", fd_child_list[i].fd,
|
|
|
|
|
_get_osfhandle (fd_child_list[i].fd));
|
|
|
|
|
}
|
|
|
|
|
else if (fd_child_list[i].dup_to == 2)
|
|
|
|
|
{
|
|
|
|
|
si.hStdError = (HANDLE) _get_osfhandle (fd_child_list[i].fd);
|
|
|
|
|
TRACE_LOG2 ("using 0x%x/%p for stderr", fd_child_list[i].fd,
|
|
|
|
|
_get_osfhandle (fd_child_list[i].fd));
|
|
|
|
|
duped_stderr = 1;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
TRACE_LOG1 ("CreateFile (\"nul\") failed: ec=%d",
|
|
|
|
|
(int) GetLastError ());
|
|
|
|
|
free (arg_string);
|
|
|
|
|
/* FIXME: Should translate the error code. */
|
|
|
|
|
errno = EIO;
|
|
|
|
|
return TRACE_SYSRES (-1);
|
|
|
|
|
}
|
|
|
|
|
/* Make sure that the process has a connected stdin. */
|
|
|
|
|
if (!duped_stdin)
|
|
|
|
|
{
|
|
|
|
|
si.hStdInput = hnul;
|
|
|
|
|
TRACE_LOG1 ("using 0x%x for dummy stdin", (int) hnul);
|
|
|
|
|
}
|
|
|
|
|
/* We normally don't want all the normal output. */
|
|
|
|
|
if (!duped_stderr)
|
|
|
|
|
{
|
|
|
|
|
si.hStdError = hnul;
|
|
|
|
|
TRACE_LOG1 ("using %d for dummy stderr", (int)hnul);
|
|
|
|
|
}
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
2007-08-02 14:59:01 +00:00
|
|
|
|
cr_flags |= CREATE_SUSPENDED;
|
|
|
|
|
cr_flags |= DETACHED_PROCESS;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
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 */
|
|
|
|
|
{
|
|
|
|
|
TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
|
|
|
|
|
free (arg_string);
|
|
|
|
|
/* FIXME: Should translate the error code. */
|
|
|
|
|
errno = EIO;
|
|
|
|
|
return TRACE_SYSRES (-1);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
|
|
|
|
/* Close the /dev/nul handle if used. */
|
|
|
|
|
if (hnul != INVALID_HANDLE_VALUE)
|
|
|
|
|
{
|
|
|
|
|
if (!CloseHandle (hnul))
|
|
|
|
|
TRACE_LOG1 ("CloseHandle (hnul) failed: ec=%d (ignored)",
|
|
|
|
|
(int) GetLastError ());
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
|
|
TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, "
|
|
|
|
|
"dwProcessID=%d, dwThreadId=%d",
|
|
|
|
|
pi.hProcess, pi.hThread,
|
|
|
|
|
(int) pi.dwProcessId, (int) pi.dwThreadId);
|
|
|
|
|
|
|
|
|
|
if (ResumeThread (pi.hThread) < 0)
|
|
|
|
|
TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
|
|
|
|
|
|
|
|
|
|
if (!CloseHandle (pi.hThread))
|
|
|
|
|
TRACE_LOG1 ("CloseHandle of thread failed: ec=%d",
|
|
|
|
|
(int) GetLastError ());
|
2005-11-17 18:45:14 +00:00
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_SUC1 ("process=%p", pi.hProcess);
|
|
|
|
|
return 0;
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
/* Select on the list of fds. Returns: -1 = error, 0 = timeout or
|
|
|
|
|
nothing to select, > 0 = number of signaled fds. */
|
2005-11-17 18:45:14 +00:00
|
|
|
|
int
|
|
|
|
|
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
|
|
|
|
|
{
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
int npollfds;
|
2005-11-18 16:52:38 +00:00
|
|
|
|
GPollFD *pollfds;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
int *pollfds_map;
|
|
|
|
|
int i;
|
|
|
|
|
int j;
|
|
|
|
|
int any;
|
|
|
|
|
int n;
|
|
|
|
|
int count;
|
|
|
|
|
/* Use a 1s timeout. */
|
|
|
|
|
int timeout = 1000;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
void *dbg_help = NULL;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_select", fds,
|
|
|
|
|
"nfds=%u, nonblock=%u", nfds, nonblock);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
2005-11-18 16:52:38 +00:00
|
|
|
|
if (nonblock)
|
|
|
|
|
timeout = 0;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
2005-11-18 16:52:38 +00:00
|
|
|
|
pollfds = calloc (nfds, sizeof *pollfds);
|
|
|
|
|
if (!pollfds)
|
|
|
|
|
return -1;
|
|
|
|
|
pollfds_map = calloc (nfds, sizeof *pollfds_map);
|
|
|
|
|
if (!pollfds_map)
|
|
|
|
|
{
|
|
|
|
|
free (pollfds);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
npollfds = 0;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_SEQ (dbg_help, "select on [ ");
|
2005-11-18 16:52:38 +00:00
|
|
|
|
any = 0;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
for (i = 0; i < nfds; i++)
|
|
|
|
|
{
|
|
|
|
|
if (fds[i].fd == -1)
|
|
|
|
|
continue;
|
|
|
|
|
if (fds[i].frozen)
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_ADD1 (dbg_help, "f0x%x ", fds[i].fd);
|
2005-11-18 16:52:38 +00:00
|
|
|
|
else if (fds[i].for_read )
|
2005-11-18 14:00:50 +00:00
|
|
|
|
{
|
2005-11-18 16:52:38 +00:00
|
|
|
|
GIOChannel *chan = find_channel (fds[i].fd, 0);
|
|
|
|
|
assert (chan);
|
|
|
|
|
g_io_channel_win32_make_pollfd (chan, G_IO_IN, pollfds + npollfds);
|
|
|
|
|
pollfds_map[npollfds] = i;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_ADD2 (dbg_help, "r0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd);
|
2005-11-18 16:52:38 +00:00
|
|
|
|
npollfds++;
|
|
|
|
|
any = 1;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
|
|
|
|
else if (fds[i].for_write)
|
|
|
|
|
{
|
2005-11-18 16:52:38 +00:00
|
|
|
|
GIOChannel *chan = find_channel (fds[i].fd, 0);
|
|
|
|
|
assert (chan);
|
|
|
|
|
g_io_channel_win32_make_pollfd (chan, G_IO_OUT, pollfds + npollfds);
|
|
|
|
|
pollfds_map[npollfds] = i;
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_ADD2 (dbg_help, "w0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd);
|
2005-11-18 16:52:38 +00:00
|
|
|
|
npollfds++;
|
|
|
|
|
any = 1;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2005-11-18 16:52:38 +00:00
|
|
|
|
fds[i].signaled = 0;
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_END (dbg_help, "]");
|
2005-11-18 16:52:38 +00:00
|
|
|
|
if (!any)
|
|
|
|
|
{
|
|
|
|
|
count = 0;
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
count = g_io_channel_win32_poll (pollfds, npollfds, timeout);
|
|
|
|
|
if (count < 0)
|
|
|
|
|
{
|
|
|
|
|
int saved_errno = errno;
|
|
|
|
|
errno = saved_errno;
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_SEQ (dbg_help, "select OK [ ");
|
|
|
|
|
if (TRACE_ENABLED (dbg_help))
|
2005-11-18 14:00:50 +00:00
|
|
|
|
{
|
2005-11-18 16:52:38 +00:00
|
|
|
|
for (i = 0; i < npollfds; i++)
|
2005-11-18 14:00:50 +00:00
|
|
|
|
{
|
2005-11-18 16:52:38 +00:00
|
|
|
|
if ((pollfds[i].revents & G_IO_IN))
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_ADD1 (dbg_help, "r0x%x ", fds[pollfds_map[i]].fd);
|
2005-11-18 16:52:38 +00:00
|
|
|
|
if ((pollfds[i].revents & G_IO_OUT))
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_ADD1 (dbg_help, "w0x%x ", fds[pollfds_map[i]].fd);
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
TRACE_END (dbg_help, "]");
|
2005-11-18 14:00:50 +00:00
|
|
|
|
}
|
2005-11-18 16:52:38 +00:00
|
|
|
|
|
|
|
|
|
/* COUNT is used to stop the lop as soon as possible. */
|
|
|
|
|
for (n = count, i = 0; i < npollfds && n; i++)
|
|
|
|
|
{
|
|
|
|
|
j = pollfds_map[i];
|
|
|
|
|
assert (j >= 0 && j < nfds);
|
|
|
|
|
if (fds[j].fd == -1)
|
|
|
|
|
;
|
|
|
|
|
else if (fds[j].for_read)
|
|
|
|
|
{
|
|
|
|
|
if ((pollfds[i].revents & G_IO_IN))
|
|
|
|
|
{
|
|
|
|
|
fds[j].signaled = 1;
|
|
|
|
|
n--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (fds[j].for_write)
|
|
|
|
|
{
|
|
|
|
|
if ((pollfds[i].revents & G_IO_OUT))
|
|
|
|
|
{
|
|
|
|
|
fds[j].signaled = 1;
|
|
|
|
|
n--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-11-18 14:00:50 +00:00
|
|
|
|
|
2005-11-18 16:52:38 +00:00
|
|
|
|
leave:
|
|
|
|
|
free (pollfds);
|
|
|
|
|
free (pollfds_map);
|
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
(_gpgme_debug): Save and restore ERRNO.
(TOHEX): New macro.
(_gpgme_debug_buffer): New function.
* conversion.c, data-compat.c, data-mem.c, data.c, engine-gpgsm.c,
gpgme.c, keylist.c, posix-io.c, rungpg.c, sign.c, version.c,
w32-io.c, wait.c: Replace DEBUG macros by TRACE_* variants. In
most of these files, add many more tracepoints.
2007-07-17 12:36:04 +00:00
|
|
|
|
return TRACE_SYSRES (count);
|
2005-11-17 18:45:14 +00:00
|
|
|
|
}
|
2007-07-16 17:26:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
_gpgme_io_dup (int fd)
|
|
|
|
|
{
|
|
|
|
|
return _dup (fd);
|
|
|
|
|
}
|