gpgme/src/assuan-support.c
Ben Kibbey aea2c168fc Add gpgme_set_global_malloc_hooks().
* configure.ac: Remove check for vasprintf().
* doc/gpgme.texi: Add documentation.
* src/gpgme.h.in (gpgme_malloc_hooks,gpgme_malloc_hooks_t): New.
* src/gpgme.h.in (gpgme_set_global_malloc_hooks): New prototype.
* src/mem.c, src/mem.h: New.
* src/gpgme.c (gpgme_set_global_malloc_hooks): New.
* src/gpgme.def, src/libgpgme.vers: Add gpgme_set_global_malloc_hooks.
* src/vasprintf.c (vasprintf): Rename to _gpgme_vasprintf().
* src/vasprintf.c (asprintf): Rename to _gpgme_asprintf().
* src/Makefile.am: Add mem.c, mem.h and vasprintf.c to main_sources.
* src/assuan-support.c, src/ath-pthread.c, src/conversion.c,
src/data-compat.c, src/data-identify.c, src/data-mem.c, src/data.c,
src/debug.c, src/decrypt.c, src/dirinfo.c, src/encrypt.c,
src/engine-assuan.c, src/engine-g13.c, src/engine-gpg.c,
src/engine-gpgconf.c, src/engine-gpgsm.c, src/engine-spawn.c,
src/engine-uiserver.c, src/engine.c, src/export.c, src/genkey.c,
src/get-env.c, src/gpgme-w32spawn.c, src/gpgme.c, src/import.c,
src/key.c, src/keylist.c, src/op-support.c, src/passphrase.c,
src/posix-io.c, src/posix-util.c, src/progress.c, src/setenv.c,
src/sig-notation.c, src/sign.c, src/signers.c, src/trust-item.c,
src/trustlist.c, src/util.h, src/verify.c, src/version.c,
src/vfs-create.c, src/vfs-mount.c, src/w32-ce.c, src/w32-ce.h,
src/w32-glib-io.c, src/w32-io.c, src/w32-sema.c, src/w32-util.c,
src/wait-global.c, src/wait.c:
Change allocation functions: free() to _gpgme_free(), malloc() to
_gpgme_malloc(), calloc() to _gpgme_calloc(), realloc() to
_gpgme_realloc() and strdup() to _gpgme_strdup().

--
Mostly borrowed from libassuan for custom memory handling. This changes
vasprintf.c to implement _gpgme_asprintf() and _gpgme_vasprintf() and
will always use the built-in vasprintf() even when provided by the OS.
2014-10-15 21:34:10 -04:00

283 lines
5.5 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include "assuan.h"
#include "gpgme.h"
#include "ath.h"
#include "priv-io.h"
#include "debug.h"
#include "mem.h"
static void *
_gpgme_assuan_malloc (size_t size)
{
return _gpgme_malloc (size);
}
static void *
_gpgme_assuan_realloc (void *p, size_t size)
{
return _gpgme_realloc (p, size);
}
static void
_gpgme_assuan_free (void *p)
{
_gpgme_free (p);
}
struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks =
{
_gpgme_assuan_malloc,
_gpgme_assuan_realloc,
_gpgme_assuan_free
};
int
_gpgme_assuan_log_cb (assuan_context_t ctx, void *hook,
unsigned int cat, const char *msg)
{
if (msg == NULL)
return 1;
_gpgme_debug (DEBUG_ASSUAN, "%s", msg);
return 0;
}
static void
my_usleep (assuan_context_t ctx, unsigned int usec)
{
/* FIXME: Add to ath. */
__assuan_usleep (ctx, usec);
}
/* Create a pipe with an inheritable end. */
static int
my_pipe (assuan_context_t ctx, assuan_fd_t fds[2], int inherit_idx)
{
int res;
int gfds[2];
res = _gpgme_io_pipe (gfds, inherit_idx);
/* For now... */
fds[0] = (assuan_fd_t) gfds[0];
fds[1] = (assuan_fd_t) gfds[1];
return res;
}
/* Close the given file descriptor, created with _assuan_pipe or one
of the socket functions. */
static int
my_close (assuan_context_t ctx, assuan_fd_t fd)
{
return _gpgme_io_close ((int) fd);
}
static gpgme_ssize_t
my_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
{
return _gpgme_io_read ((int) fd, buffer, size);
}
static gpgme_ssize_t
my_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, size_t size)
{
return _gpgme_io_write ((int) fd, buffer, size);
}
static int
my_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
int flags)
{
#ifdef HAVE_W32_SYSTEM
gpg_err_set_errno (ENOSYS);
return -1;
#else
return _gpgme_io_recvmsg ((int) fd, msg, flags);
#endif
}
static int
my_sendmsg (assuan_context_t ctx, assuan_fd_t fd, const assuan_msghdr_t msg,
int flags)
{
#ifdef HAVE_W32_SYSTEM
gpg_err_set_errno (ENOSYS);
return -1;
#else
return _gpgme_io_sendmsg ((int) fd, msg, flags);
#endif
}
/* If NAME is NULL, don't exec, just fork. FD_CHILD_LIST is modified
to reflect the value of the FD in the peer process (on
Windows). */
static int
my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
const char **argv,
assuan_fd_t fd_in, assuan_fd_t fd_out,
assuan_fd_t *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue, unsigned int flags)
{
int err;
struct spawn_fd_item_s *fd_items;
int i;
assert (name);
if (! name)
{
gpg_err_set_errno (ENOSYS);
return -1;
}
i = 0;
if (fd_child_list)
{
while (fd_child_list[i] != ASSUAN_INVALID_FD)
i++;
}
/* fd_in, fd_out, terminator */
i += 3;
fd_items = _gpgme_calloc (i, sizeof (struct spawn_fd_item_s));
if (! fd_items)
return -1;
i = 0;
if (fd_child_list)
{
while (fd_child_list[i] != ASSUAN_INVALID_FD)
{
fd_items[i].fd = (int) fd_child_list[i];
fd_items[i].dup_to = -1;
i++;
}
}
if (fd_in != ASSUAN_INVALID_FD)
{
fd_items[i].fd = (int) fd_in;
fd_items[i].dup_to = 0;
i++;
}
if (fd_out != ASSUAN_INVALID_FD)
{
fd_items[i].fd = (int) fd_out;
fd_items[i].dup_to = 1;
i++;
}
fd_items[i].fd = -1;
fd_items[i].dup_to = -1;
err = _gpgme_io_spawn (name, (char*const*)argv,
(IOSPAWN_FLAG_NOCLOSE | IOSPAWN_FLAG_DETACHED),
fd_items, atfork, atforkvalue, r_pid);
if (! err)
{
i = 0;
if (fd_child_list)
{
while (fd_child_list[i] != ASSUAN_INVALID_FD)
{
fd_child_list[i] = (assuan_fd_t) fd_items[i].peer_name;
i++;
}
}
}
_gpgme_free (fd_items);
return err;
}
/* If action is 0, like waitpid. If action is 1, just release the PID? */
static pid_t
my_waitpid (assuan_context_t ctx, pid_t pid,
int nowait, int *status, int options)
{
#ifdef HAVE_W32_SYSTEM
CloseHandle ((HANDLE) pid);
#else
/* We can't just release the PID, a waitpid is mandatory. But
NOWAIT in POSIX systems just means the caller already did the
waitpid for this child. */
if (! nowait)
return _gpgme_ath_waitpid (pid, status, options);
#endif
return 0;
}
static int
my_socketpair (assuan_context_t ctx, int namespace, int style,
int protocol, assuan_fd_t filedes[2])
{
#ifdef HAVE_W32_SYSTEM
gpg_err_set_errno (ENOSYS);
return -1;
#else
/* FIXME: Debug output missing. */
return __assuan_socketpair (ctx, namespace, style, protocol, filedes);
#endif
}
static int
my_socket (assuan_context_t ctx, int namespace, int style, int protocol)
{
return _gpgme_io_socket (namespace, style, protocol);
}
static int
my_connect (assuan_context_t ctx, int sock, struct sockaddr *addr,
socklen_t length)
{
return _gpgme_io_connect (sock, addr, length);
}
/* Note for Windows: Ignore the incompatible pointer type warning for
my_read and my_write. Mingw has been changed to use int for
ssize_t on 32 bit systems while we use long. For 64 bit we use
int64_t while mingw uses __int64_t. It doe not matter at all
because under Windows long and int are both 32 bit even on 64
bit. */
struct assuan_system_hooks _gpgme_assuan_system_hooks =
{
ASSUAN_SYSTEM_HOOKS_VERSION,
my_usleep,
my_pipe,
my_close,
my_read,
my_write,
my_recvmsg,
my_sendmsg,
my_spawn,
my_waitpid,
my_socketpair,
my_socket,
my_connect
};