diff options
author | Anas Nashif <anas.nashif@intel.com> | 2013-02-19 08:22:18 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-02-19 08:22:18 -0800 |
commit | 26fb537f9cf011eaeaf975adcad5e8e9154d04fd (patch) | |
tree | ddc2171273fca8b730b9c496e1b5ed3b01878577 /src/assuan-support.c | |
download | gpgme-upstream/1.3.2.tar.gz gpgme-upstream/1.3.2.tar.bz2 gpgme-upstream/1.3.2.zip |
Imported Upstream version 1.3.2upstream/1.3.2
Diffstat (limited to 'src/assuan-support.c')
-rw-r--r-- | src/assuan-support.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/assuan-support.c b/src/assuan-support.c new file mode 100644 index 0000000..5264346 --- /dev/null +++ b/src/assuan-support.c @@ -0,0 +1,256 @@ +#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" + + +struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks = + { + malloc, + realloc, + 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 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 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 = 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, + 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++; + } + } + } + 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); +} + + +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 + }; + |